/* ============================================================================
   OMCWEB — Management UI
   ทิศทางการออกแบบ: corporate clean (CLAUDE.md ข้อ 1)
   ‼️ ค่าสี ระยะห่าง ขนาด ทั้งระบบอยู่ที่ไฟล์นี้ที่เดียว (กฎเหล็กข้อ 8)
      ห้าม hardcode ค่าดิบในหน้า ห้ามมี <style> ในหน้า ห้ามมี CSS แยกต่อหน้า
   ============================================================================ */

:root {
    /* ---- สีแบรนด์ ---- */
    /* --color-primary คือสีแบรนด์ ใช้กับพื้นที่ขนาดใหญ่และงานตกแต่ง
       ส่วนข้อความและพื้นปุ่มต้องใช้ --color-primary-strong เพราะสีแบรนด์บนพื้นขาว
       ได้ contrast เพียง 3.58:1 ซึ่งไม่ผ่าน WCAG AA (design.md ข้อ 3.8) */
    --color-primary:        #E8590C;
    --color-primary-strong: #C0430A;
    --color-primary-hover:  #A63808;
    --color-primary-soft:   #FDF0E7;
    --color-primary-border: #F6C9AC;
    --color-secondary:      #1B2A4A;
    --color-secondary-soft: #EDF1F7;

    /* ---- พื้นเข้มของหน้าแนะนำผลิตภัณฑ์ ---- */
    /* ‼️ ตัวอักษรบนพื้นกรมท่าต้องใช้สามตัวนี้เท่านั้น ค่าอื่นไม่ผ่าน WCAG AA
       #FFFFFF บน --color-hero = 14.11:1 · --color-text-on-dark-muted = 7.94:1
       --color-primary-on-dark = 6.02:1 (สีแบรนด์ตัวจริงได้แค่ 3.96:1 จึงใช้บนพื้นเข้มไม่ได้)
       --color-success-on-dark = 8.16:1 */
    --color-hero:               #1B2A4A;
    --color-hero-deep:          #101B31;
    --color-text-on-dark-muted: #B9C4D6;
    --color-primary-on-dark:    #FF8A3D;
    --color-success-on-dark:    #6FD6AE;
    --color-device-edge:        #D4DAE3;

    /* ---- พื้นผิว ---- */
    --color-bg:            #F6F7F9;
    --color-surface:       #FFFFFF;
    --color-surface-muted: #FAFAFB;
    --color-border:        #E3E6EA;
    --color-border-strong: #CBD2DA;
    --color-text:          #1C2430;
    --color-text-muted:    #667283;
    /* ‼️ --color-text-muted ถูกเลือกโดยเทียบพื้นขาว (4.88:1 ผ่าน AA พอดี)
       พอเอาไปวางบนพื้นที่เข้มกว่าอย่าง --color-neutral-soft จะเหลือ 4.32:1 = ไม่ผ่าน
       ตัวอักษรที่อยู่บนพื้นสีเทาอ่อนต้องใช้ตัวนี้แทน (5.60:1 บนพื้นเทาอ่อน · 6.34:1 บนขาว)
       ยกเว้น control ที่ปิดใช้งาน (WCAG 1.4.3) และไอคอนล้วน (ใช้เกณฑ์ 3:1 ตาม 1.4.11) */
    --color-text-muted-on-soft: #566072;
    --color-text-inverse:  #FFFFFF;

    /* ---- สี semantic: ใช้สื่อสถานะเท่านั้น ห้ามใช้ตกแต่ง ---- */
    --color-success:      #16704F;
    --color-success-soft: #E7F5EF;
    --color-warning:      #92610F;
    --color-warning-soft: #FDF5E3;
    --color-danger:       #C42B2B;
    --color-danger-soft:  #FCEDED;
    --color-info:         #1F5F9E;
    --color-info-soft:    #EAF2FA;
    /* #667283 บนพื้น --color-neutral-soft ได้แค่ 4.32:1 จึงต้องเข้มกว่าสีข้อความรองทั่วไป */
    --color-neutral:      #55606F;
    --color-neutral-soft: #EFF1F4;

    /* ---- ระยะห่าง: ทวีคูณของ 4px ---- */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 16px;
    --space-4: 24px;
    --space-5: 32px;
    --space-6: 48px;
    --space-7: 64px;
    --space-8: 88px;

    /* ---- ตัวอักษร (ต้องรองรับไทยและละติน · ห้ามใช้ Inter/Roboto ตาม design.md ข้อ 1) ---- */
    --font-family: "IBM Plex Sans Thai", "Noto Sans Thai", "Sarabun", "Segoe UI", system-ui, sans-serif;
    --font-family-mono: "JetBrains Mono", "Cascadia Mono", ui-monospace, monospace;
    --font-size-xs:   12px;
    --font-size-sm:   14px;
    --font-size-base: 16px;
    --font-size-lg:   20px;
    --font-size-xl:   24px;
    --font-size-2xl:  32px;
    --font-size-3xl:  40px;
    --font-size-4xl:  50px;
    --font-weight-normal: 400;
    --font-weight-medium: 500;
    --font-weight-bold:   600;
    --line-height-base:  1.6;
    --line-height-tight: 1.3;

    /* ---- รูปทรง ---- */
    --radius-sm:   4px;
    --radius-base: 8px;
    --radius-lg:   12px;
    --radius-pill: 999px;
    --border-width: 1px;
    --shadow-sm:    0 1px 2px rgba(28, 36, 48, .06);
    --shadow-base:  0 2px 8px rgba(28, 36, 48, .08);
    --shadow-lg:    0 12px 32px rgba(28, 36, 48, .14);
    --shadow-device: 0 24px 60px rgba(9, 15, 28, .35);

    /* ---- ขนาด component: ต้องเท่ากันทั้งระบบ ---- */
    --height-input:  40px;
    --height-button: 40px;
    --height-row:    48px;
    --icon-size:     20px;
    --sidebar-width: 248px;
    --topbar-height: 60px;
    --content-max:   1320px;
    --size-strip-icon:     40px;
    --size-tpl-card:       208px;
    --size-rail-arrow:     40px;
    --size-rail-arrow-top: 84px;

    --transition-base: 180ms ease;

    /* ---- โทนสีของชิปไอคอน (design system v2) ----
       ‼️ ใช้กับ "ชิปไอคอน" ในการ์ดเท่านั้น ห้ามใช้ระบายพื้นการ์ดทั้งใบ (design.md ข้อ 5.3)
          การ์ดทุกใบยังเป็นพื้นขาวเหมือนกันหมด ต่างกันแค่ไอคอนนำสายตาให้จำตำแหน่งได้
       ‼️ ทุกคู่ผ่าน WCAG AA บนพื้นของตัวเอง (ตรวจซ้ำด้วย scripts/check-screens.php) */
    --tint-brand-bg:  #FDF0E7;  --tint-brand-fg:  #C0430A;
    --tint-green-bg:  #E7F5EF;  --tint-green-fg:  #16704F;
    --tint-violet-bg: #EFECFD;  --tint-violet-fg: #4F35BE;
    --tint-blue-bg:   #EAF2FA;  --tint-blue-fg:   #1F5F9E;
    --tint-slate-bg:  #EFF1F4;  --tint-slate-fg:  #55606F;

    /* ---- สีของกราฟ (ไล่ตามลำดับเสมอ ห้ามสุ่ม · design.md ข้อ 5.4) ---- */
    --chart-1: #E8590C;
    --chart-2: #5B3FD1;
    --chart-3: #16704F;
    --chart-4: #1F5F9E;
    --chart-5: #C9CFD8;
    --chart-grid: #EDEFF3;

    /* ---- โครงหน้าจอเพิ่มเติม ---- */
    --sidebar-width-collapsed: 76px;
    --radius-xl: 16px;
    --shadow-card: 0 1px 2px rgba(28, 36, 48, .04), 0 1px 3px rgba(28, 36, 48, .06);
    --shadow-pop:  0 8px 24px rgba(28, 36, 48, .10);
    --height-control-sm: 32px;
    /* ช่องกรอกของหน้าที่ยังไม่ล็อกอิน — สูงกว่าในระบบจัดการเพราะเป็นหน้าที่ผู้ใช้ใหม่เจอก่อนใคร */
    --height-input-auth: 46px;

    /* ---- ค่าที่เคยเขียนดิบอยู่ในกฎ ยกขึ้นมาเป็น token เพื่อให้โหมดมืดเปลี่ยนตามได้ ---- */
    /* ‼️ ฉากหลังของ modal/drawer/ทัวร์ ต้องเข้มขึ้นในโหมดมืด ไม่ใช่ค่าเดิม
       พื้นหลังโหมดมืดเข้มอยู่แล้ว ถ้าใช้ความทึบเท่าเดิมจะแยกไม่ออกว่าอะไรอยู่หน้าอะไร */
    --color-backdrop:        rgba(28, 36, 48, .5);
    --color-backdrop-strong: rgba(28, 36, 48, .55);
    --auth-aside-bg:   linear-gradient(160deg, #FFF6EF 0%, #FFFDFB 46%, #FDF1E7 100%);
    --auth-aside-glow: radial-gradient(circle, rgba(232, 89, 12, .10), transparent 64%);
}

/* ---------------------------------------------------------------- base */

*,
*::before,
*::after { box-sizing: border-box; }

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

/* ‼️ [hidden] ต้องชนะทุกกฎที่ตั้ง display ไว้
      กฎ [hidden] ของเบราว์เซอร์มาจาก user agent ซึ่งแพ้กฎของเราทุกข้อ
      คลาสอย่าง .tile ที่ตั้ง display:flex จึงทำให้ element ที่ติด hidden ยังโผล่อยู่
      (เจอจริง 2026-08-31 — แผงสรุปองค์กรขึ้นมาทั้งที่ยังไม่ได้เลือกอะไรเลย)
      ก่อนหน้านี้แต่ละ component ไปเขียน X[hidden] { display: none } ของตัวเอง
      ซึ่งแปลว่าคนที่เพิ่ม component ใหม่ต้องจำกฎนี้เองทุกครั้ง แล้วก็จะมีวันที่ลืม */
[hidden] { display: none !important; }

body {
    margin: 0;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-family);
    font-size: var(--font-size-base);
    line-height: var(--line-height-base);
}

h1, h2, h3, h4, h5, h6 {
    margin: 0 0 var(--space-2);
    line-height: var(--line-height-tight);
    font-weight: var(--font-weight-bold);
}

h1 { font-size: var(--font-size-2xl); }
h2 { font-size: var(--font-size-xl); }
h3 { font-size: var(--font-size-lg); }
h4 { font-size: var(--font-size-base); }

p { margin: 0 0 var(--space-3); }

a {
    color: var(--color-primary-strong);
    text-decoration: none;
    transition: color var(--transition-base);
}

a:hover { color: var(--color-primary-hover); text-decoration: underline; }

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

img { max-width: 100%; height: auto; }

hr {
    border: 0;
    border-top: var(--border-width) solid var(--color-border);
    margin: var(--space-4) 0;
}

small { font-size: var(--font-size-sm); }

code, pre { font-family: var(--font-family-mono); font-size: var(--font-size-sm); }

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

.skip-link {
    position: absolute;
    left: var(--space-3);
    top: calc(var(--space-3) * -4);
    z-index: 100;
    background: var(--color-surface);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-base);
    box-shadow: var(--shadow-base);
    transition: top var(--transition-base);
}

.skip-link:focus { top: var(--space-3); }

/* ------------------------------------------------------------- utilities */

.text-muted   { color: var(--color-text-muted); }
.text-sm      { font-size: var(--font-size-sm); }
.text-xs      { font-size: var(--font-size-xs); }
.text-lg      { font-size: var(--font-size-lg); }
.text-bold    { font-weight: var(--font-weight-bold); }
.text-medium  { font-weight: var(--font-weight-medium); }
.text-right   { text-align: right; }
.text-center  { text-align: center; }
.text-nowrap  { white-space: nowrap; }
.text-block   { display: block; }   /* ข้อความรองที่ต้องขึ้นบรรทัดใหม่ใต้ชื่อหลัก */
.text-danger  { color: var(--color-danger); }
.text-success { color: var(--color-success); }
.text-primary { color: var(--color-primary-strong); }

.truncate {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ‼️ ใช้กับ <ul> ได้ด้วย จึงต้องล้าง padding/marker ของ list ทิ้ง ไม่งั้นเนื้อหาจะเยื้องเข้าไป 40px */
ul[class*="stack"],
ol[class*="stack"] { list-style: none; padding: 0; margin: 0; }

/* ‼️ .stack-1 เคยถูกใช้ในหน้าโดยไม่มีนิยาม (ทะเบียนหนี้เทคนิค) — ประกาศไว้ที่นี่ให้ครบชุด */
.stack-1 { display: flex; flex-direction: column; gap: var(--space-1); }
.stack   { display: flex; flex-direction: column; gap: var(--space-3); }
.stack-2 { display: flex; flex-direction: column; gap: var(--space-2); }
/* ‼️ .stack-3 มีระยะเท่ากับ .stack เป๊ะๆ — มีอยู่เพื่อให้เขียนเป็นชุดเลขต่อเนื่องได้
      โดยไม่ต้องจำว่าเลข 3 คือตัวที่ไม่มีเลข (ที่ผ่านมาหน้าที่เขียน stack-3 ได้ระยะศูนย์) */
.stack-3 { display: flex; flex-direction: column; gap: var(--space-3); }
.stack-4 { display: flex; flex-direction: column; gap: var(--space-4); }
/* ‼️ ต้องมีคู่กับ .truncate ในกล่อง flex เสมอ — ลูกของ flex มี min-width: auto โดยปริยาย
      จึงไม่ยอมหดต่ำกว่าความกว้างของข้อความ แล้ว truncate ไม่ทำงานและกล่องล้นออกนอกจอ */
.min-w-0 { min-width: 0; }
.stack-5 { display: flex; flex-direction: column; gap: var(--space-5); }

.row-flex {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.row-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.grid { display: grid; gap: var(--space-4); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* คอลัมน์ที่เนื้อหาสั้นกว่าไม่ต้องยืดตามคอลัมน์ที่ยาวกว่า — กันการ์ดว่างสูงเกินจำเป็น */
.grid-sidebar { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); align-items: start; }

.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mb-0 { margin-bottom: 0; }
.mb-2 { margin-bottom: var(--space-2); }
.mb-3 { margin-bottom: var(--space-3); }
.mb-4 { margin-bottom: var(--space-4); }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.w-full { width: 100%; }
.flex-1 { flex: 1 1 0%; min-width: 0; }   /* basis 0 เพื่อให้ข้อความยาวหดตัว ไม่ใช่ wrap ทั้งบล็อกลงบรรทัดใหม่ */

/* ------------------------------------------------------------ app shell */

.app {
    display: grid;
    grid-template-columns: var(--sidebar-width) minmax(0, 1fr);
    min-height: 100vh;
}

/* ‼️ แถบข้างเป็นพื้นขาว ไม่ใช่พื้นกรมท่าอีกต่อไป (Visual Standard ที่อนุมัติ 2026-08-23)
   สีกรมท่ายังเป็นสีรองของแบรนด์ แต่ย้ายไปอยู่ที่ตัวอักษรหัวข้อและพื้นเข้มของหน้าแนะนำผลิตภัณฑ์
   เหตุผล: เมนู 12-13 รายการบนพื้นเข้มเต็มความสูงจอ กินสัดส่วนสีเกิน 30% ตาม design.md ข้อ 3.7
   และทำให้พื้นที่เนื้อหาดู "จม" — พื้นขาวคั่นด้วยเส้นเดียวให้น้ำหนักสายตาไปที่เนื้อหาแทน */
.sidebar {
    background: var(--color-surface);
    border-right: var(--border-width) solid var(--color-border);
    color: var(--color-text);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-4) var(--space-3);
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-text);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-lg);
    letter-spacing: .01em;
    padding: 0 var(--space-1);
    min-height: var(--space-5);
}

.sidebar-brand:hover { color: var(--color-text); text-decoration: none; }

.sidebar-brand-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--space-5);
    height: var(--space-5);
    /* ‼️ ต้องเป็น --color-primary-strong ไม่ใช่ --color-primary
       ตัวอักษรขาวบนสีแบรนด์ตัวจริงได้ contrast แค่ 3.58:1 ซึ่งไม่ผ่าน WCAG AA (design.md ข้อ 3.8) */
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    border-radius: var(--radius-base);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-bold);
    letter-spacing: .04em;
    flex: none;
}

.sidebar-section-title {
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--color-text-muted);
    padding: 0 var(--space-2);
    margin-bottom: var(--space-1);
}

.sidebar-nav { display: flex; flex-direction: column; gap: 2px; }

/* -------------------------------------------------- หมวดในเมนูข้าง

   ‼️ ใช้ <details> เป็นฐาน · พับ/กางได้เองแม้ JavaScript ไม่โหลด
      และได้คีย์บอร์ดกับ ARIA มาครบโดยไม่ต้องเขียนเอง
      JavaScript มีหน้าที่แค่ "จำ" ว่าผู้ใช้เปิดหรือปิดอะไรไว้ */

.sidebar-group { border: 0; }

.sidebar-group + .sidebar-group,
.sidebar-link + .sidebar-group { margin-top: var(--space-2); }

.sidebar-group-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    /* ‼️ พื้นที่กดต้องไม่น้อยกว่า 44px ตามเกณฑ์การกดด้วยนิ้ว
          หัวข้อหมวดคือสิ่งที่ถูกกดบ่อยที่สุดบนมือถือ */
    min-height: var(--space-6);
    padding: 0 var(--space-2);
    cursor: pointer;
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--color-text-muted);
    list-style: none;
    user-select: none;
}

/* ลูกศรของเบราว์เซอร์เอง — ซ่อนแล้วใช้ไอคอนของระบบแทนให้เหมือนที่อื่น */
.sidebar-group-title::-webkit-details-marker { display: none; }

.sidebar-group-title:hover { color: var(--color-text); }

.sidebar-group-title .icon {
    width: var(--font-size-sm);
    height: var(--font-size-sm);
    flex: none;
    transition: transform var(--transition-base);
}

.sidebar-group[open] > .sidebar-group-title .icon { transform: rotate(180deg); }

.sidebar-group-title > span {
    /* ‼️ ชื่อหมวดยาวต้องไม่ดันแถบข้างให้กว้างขึ้น · ตัดด้วยจุดไข่ปลาแทน */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sidebar-group-items {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: var(--space-1);
}

/* ‼️ เส้นบอกตำแหน่งด้านซ้ายอยู่ที่ ::before ของทุกลิงก์ (โปร่งใสเมื่อไม่ active)
   ถ้าใส่เฉพาะตัวที่ active ข้อความจะขยับตอนเปลี่ยนหน้า */
.sidebar-link {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
    border-radius: var(--radius-base);
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-sm);
    transition: background var(--transition-base), color var(--transition-base);
}

.sidebar-link::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 3px;
    height: 60%;
    border-radius: 0 var(--radius-pill) var(--radius-pill) 0;
    background: transparent;
    transition: background var(--transition-base);
}

.sidebar-link:hover {
    background: var(--color-surface-muted);
    color: var(--color-text);
    text-decoration: none;
}

.sidebar-link.is-active {
    background: var(--color-primary-soft);
    color: var(--color-primary-strong);
    font-weight: var(--font-weight-medium);
}

.sidebar-link.is-active::before { background: var(--color-primary); }

.sidebar-link .icon { width: var(--icon-size); height: var(--icon-size); flex: none; }

.sidebar-footer { margin-top: auto; display: flex; flex-direction: column; gap: var(--space-2); }

/* การ์ดคู่มือท้ายแถบข้าง — จุดเดียวที่พาผู้ใช้ใหม่ไปหาวิธีใช้งานได้โดยไม่ต้องถาม */
.sidebar-card {
    display: block;
    background: var(--color-primary-soft);
    border: var(--border-width) solid var(--color-primary-border);
    border-radius: var(--radius-lg);
    padding: var(--space-3);
    color: var(--color-text);
}

.sidebar-card:hover { text-decoration: none; color: var(--color-text); }

.sidebar-card-title {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-bold);
    color: var(--color-primary-strong);
    margin-bottom: var(--space-1);
}

.sidebar-card-title .icon { width: var(--icon-size); height: var(--icon-size); flex: none; }

.sidebar-card-text {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted-on-soft);
    margin: 0 0 var(--space-3);
    line-height: var(--line-height-base);
}

/* ---- โหมดย่อแถบข้างบนจอใหญ่ (ปุ่มเดียวกับที่เปิด drawer บนมือถือ) ---- */
.app.is-rail { grid-template-columns: var(--sidebar-width-collapsed) minmax(0, 1fr); }

.app.is-rail .sidebar { padding-left: var(--space-2); padding-right: var(--space-2); align-items: stretch; }
.app.is-rail .sidebar-brand { justify-content: center; padding: 0; }
.app.is-rail .sidebar-brand > span:not(.sidebar-brand-mark) { display: none; }
.app.is-rail .sidebar-link { justify-content: center; padding-left: var(--space-2); }
.app.is-rail .sidebar-link > span { display: none; }
.app.is-rail .sidebar-link::before { display: none; }
.app.is-rail .sidebar-section-title,
.app.is-rail .sidebar-card-title span,
.app.is-rail .sidebar-card-text,
.app.is-rail .sidebar-card .btn span { display: none; }
.app.is-rail .sidebar-card { padding: var(--space-2); text-align: center; }
.app.is-rail .sidebar-card-title { justify-content: center; margin: 0; }

.main { display: flex; flex-direction: column; min-width: 0; }

.topbar {
    height: var(--topbar-height);
    background: var(--color-surface);
    border-bottom: var(--border-width) solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 0 var(--space-4);
    position: sticky;
    top: 0;
    z-index: 20;
}

.topbar-left { display: flex; align-items: center; gap: var(--space-3); min-width: 0; flex: 1 1 auto; }

/* ป้ายบอกโซนบนแถบบนของทีมงานแพลตฟอร์ม — ลูกค้าไม่มีป้ายนี้ */
.topbar-context {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--color-text-muted-on-soft);
    min-width: 0;
}

/* ห้าม wrap เด็ดขาด — ถ้า wrap บนจอแคบ แถบภาษาจะถูกดันขึ้นไปพ้นขอบจอด้านบน */
.topbar-right { display: flex; align-items: center; gap: var(--space-2); flex-wrap: nowrap; min-width: 0; }

.content {
    /* เว้นท้ายหน้าไว้ให้ปุ่มแจ้งปัญหาแบบลอย ไม่ทับปุ่มหรือฟอร์มบรรทัดสุดท้าย */
    padding: var(--space-4) var(--space-4) var(--space-7);
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
    flex: 1 1 auto;
}

.content-narrow { max-width: 720px; }

/* --------------------------------------------------------- page header */

.page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin-bottom: var(--space-4);
}

.page-header h1 { margin-bottom: var(--space-1); }

.page-header-description { color: var(--color-text-muted); margin: 0; }

.page-header-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

.breadcrumb {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    list-style: none;
    padding: 0;
    margin: 0 0 var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    flex-wrap: wrap;
}

.breadcrumb li::after { content: "/"; margin-left: var(--space-2); color: var(--color-border-strong); }
.breadcrumb li:last-child::after { content: ""; }

/* ---------------------------------------------------------------- card */

.card {
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
}

.card + .card { margin-top: var(--space-4); }

/* ‼️ ระยะซ้อนการ์ดข้างบนใช้ได้เฉพาะการ์ดที่วางต่อกันในสายเนื้อหาแนวตั้ง
      พอการ์ดสองใบเป็นลูกของกริดที่มี gap อยู่แล้ว ระยะนี้กลายเป็นการดันใบที่สอง
      ให้ต่ำกว่าใบแรก 24px — ขอบบนของสองกล่องที่วางข้างกันจึงไม่ตรงกันทั้งระบบ
      (วัดจริงที่หน้าภาพรวม 2026-08-30: "กิจกรรมล่าสุด" top=850 · "ผู้สนใจล่าสุด" top=874)
   ‼️ ใช้ > เท่านั้น การ์ดที่ซ้อนกันอยู่ภายในคอลัมน์เดียวของกริดยังต้องมีระยะห่างเหมือนเดิม
   ‼️ ต้องไล่ใส่ให้ครบทุกกริดที่มีการ์ดเป็นลูกโดยตรง — เพิ่มกริดใหม่เมื่อไหร่ต้องเพิ่มที่นี่ด้วย
      ด่านที่จับให้อัตโนมัติคือกฎ "stacking" ใน scripts/check-screens.php
      ซึ่งวัดจากหน้าจอจริงว่ากล่องที่อยู่แถวเดียวกันของกริด ขอบบนตรงกันหรือไม่ */
.grid > .card + .card,
.help-categories > .card + .card { margin-top: 0; }

.card-header {
    padding: var(--space-3) var(--space-4);
    border-bottom: var(--border-width) solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.card-header h2,
.card-header h3 { margin: 0; font-size: var(--font-size-base); }

.card-body { padding: var(--space-4); }
.card-body-tight { padding: var(--space-3); }

.card-footer {
    padding: var(--space-3) var(--space-4);
    border-top: var(--border-width) solid var(--color-border);
    background: var(--color-surface-muted);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.section-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-bold);
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--color-text-muted);
    margin-bottom: var(--space-2);
}

/* ------------------------------------------------------------ KPI card */

.kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: var(--space-3);
}

/* ‼️ ชิปไอคอนอยู่ซ้าย ตัวเลขอยู่ขวา ตาม Visual Standard ที่อนุมัติ
   การ์ดทุกใบพื้นขาวเหมือนกัน ต่างกันแค่โทนของชิปไอคอน (design.md ข้อ 5.3) */
.kpi {
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-3) var(--space-4);
    box-shadow: var(--shadow-card);
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    min-width: 0;
}

.kpi-body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; flex: 1 1 auto; }

.kpi-label {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
}

.kpi-value {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
    font-variant-numeric: tabular-nums;
}

/* ‼️ ค่าที่เป็นข้อความ (เช่น "ต้องดำเนินการ") ยาวกว่าตัวเลขมาก
      ถ้าปล่อยขนาดเดิมจะตัดสองบรรทัดจนการ์ดสูงไม่เท่ากันทั้งแถว
      เจอจากภาพหน้าจอจริง 2026-08-27
      ‼️ ลดขนาดเฉพาะค่าที่เป็นคำ ไม่แตะค่าที่เป็นตัวเลข
         เพราะตัวเลขคือสิ่งที่คนกวาดตาหาก่อน ต้องใหญ่ไว้เหมือนเดิม */
.kpi-value.is-text {
    font-size: var(--font-size-lg);
    line-height: var(--line-height-snug);
}
.kpi-meta { font-size: var(--font-size-sm); color: var(--color-text-muted); }

.kpi-icon {
    width: var(--space-6);
    height: var(--space-6);
    border-radius: var(--radius-lg);
    background: var(--tint-brand-bg);
    color: var(--tint-brand-fg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.kpi-icon .icon { width: var(--space-4); height: var(--space-4); }

/* โทนชิปไอคอน — ใช้ได้กับ .kpi-icon และ .tile-icon เท่านั้น */
.tint-brand  { background: var(--tint-brand-bg);  color: var(--tint-brand-fg); }
.tint-green  { background: var(--tint-green-bg);  color: var(--tint-green-fg); }
.tint-violet { background: var(--tint-violet-bg); color: var(--tint-violet-fg); }
.tint-blue   { background: var(--tint-blue-bg);   color: var(--tint-blue-fg); }
.tint-slate  { background: var(--tint-slate-bg);  color: var(--tint-slate-fg); }

/* ค่าเปลี่ยนแปลงเทียบช่วงก่อนหน้า — แสดงเฉพาะเมื่อมีข้อมูลช่วงก่อนหน้าจริง */
.kpi-delta { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--font-size-sm); }
.kpi-delta .icon { width: var(--font-size-sm); height: var(--font-size-sm); }
.kpi-delta.is-up { color: var(--color-success); }
.kpi-delta.is-down { color: var(--color-danger); }
.kpi-delta.is-flat { color: var(--color-text-muted); }

/* -------------------------------------------------------------- button */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    height: var(--height-button);
    padding: 0 var(--space-3);
    border-radius: var(--radius-base);
    border: var(--border-width) solid transparent;
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    transition: background var(--transition-base), border-color var(--transition-base), color var(--transition-base);
}

.btn:hover { text-decoration: none; }

/* ‼️ นิยามของปุ่มหลักย้ายไปอยู่ท้ายไฟล์ในหมวดโหมดมืด เพราะต้องใช้ token ของตัวเอง */

.btn-secondary {
    background: var(--color-surface);
    border-color: var(--color-border-strong);
    color: var(--color-text);
}

.btn-secondary:hover { background: var(--color-surface-muted); border-color: var(--color-text-muted); color: var(--color-text); }

.btn-ghost { background: transparent; color: var(--color-text-muted); }
.btn-ghost:hover { background: var(--color-neutral-soft); color: var(--color-text); }

.btn-danger { background: var(--solid-danger-bg); border-color: var(--solid-danger-bg); color: var(--solid-danger-fg); }
.btn-danger:hover { background: var(--solid-danger-bg); border-color: var(--solid-danger-bg); filter: brightness(.92); color: var(--solid-danger-fg); }

.btn-danger-ghost { background: transparent; border-color: var(--color-border); color: var(--color-danger); }
.btn-danger-ghost:hover { background: var(--color-danger-soft); border-color: var(--color-danger); }

.btn-sm { height: var(--space-5); padding: 0 var(--space-2); font-size: var(--font-size-xs); }
.btn-lg { height: var(--space-6); padding: 0 var(--space-4); font-size: var(--font-size-base); }
.btn-block { width: 100%; }

.btn[disabled],
.btn.is-disabled {
    background: var(--color-neutral-soft);
    border-color: var(--color-border);
    /* ปุ่มที่กดไม่ได้ก็ต้องอ่านออก — ผู้ใช้ต้องรู้ว่าปุ่มนี้คืออะไรจึงจะรู้ว่าต้องทำอะไรก่อน */
    color: var(--color-neutral);
    cursor: not-allowed;
    box-shadow: none;
}

.btn-icon { width: var(--height-button); padding: 0; }

.btn .icon { width: var(--icon-size); height: var(--icon-size); }

/* --------------------------------------------------------------- forms */

.form-grid { display: grid; gap: var(--space-3); }
.form-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.field { display: flex; flex-direction: column; gap: var(--space-1); }

.field-label {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
}

.field-required { color: var(--color-danger); margin-left: var(--space-1); }

.field-hint { font-size: var(--font-size-xs); color: var(--color-text-muted); }

.field-error { font-size: var(--font-size-xs); color: var(--color-danger); }

.input,
.select,
.textarea {
    width: 100%;
    min-height: var(--height-input);
    padding: 0 var(--space-2);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-base);
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: var(--font-size-sm);
    transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.textarea { padding: var(--space-2); min-height: calc(var(--height-input) * 3); resize: vertical; line-height: var(--line-height-base); }

.input:hover,
.select:hover,
.textarea:hover { border-color: var(--color-text-muted); }

.input:focus,
.select:focus,
.textarea:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-soft);
    outline: none;
}

.input[disabled],
.select[disabled],
.textarea[disabled] {
    background: var(--color-neutral-soft);
    color: var(--color-text-muted);
    cursor: not-allowed;
}

.input.has-error,
.select.has-error,
.textarea.has-error { border-color: var(--color-danger); }

.select { appearance: none; padding-right: var(--space-5); background-image: none; }

.checkbox,
.radio {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    cursor: pointer;
}

.checkbox input,
.radio input { margin-top: var(--space-1); accent-color: var(--color-primary); }

/* ‼️ จัดของเรียงแนวนอนพร้อมช่องไฟ · ถูกใช้ในหน้าอยู่แล้วแต่ไม่เคยมีนิยาม
      markup ที่อ้างคลาสซึ่งไม่มีอยู่จริงจะดูเหมือนตั้งใจจัดวาง แต่ไม่ทำอะไรเลย
      แล้วคนที่มาแก้ทีหลังจะไล่หาสาเหตุที่ CSS ทั้งที่ไม่มีอะไรให้หา (พบ 2026-09-03) */
.cluster-2 {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.form-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    padding-top: var(--space-3);
    border-top: var(--border-width) solid var(--color-border);
    margin-top: var(--space-4);
}

.input-group { display: flex; align-items: stretch; gap: var(--space-2); flex-wrap: wrap; }
.input-group > .input { flex: 1 1 200px; }

/* ‼️ ช่องกรอกที่มีป้ายกำกับของตัวเอง อยู่แถวเดียวกับปุ่มได้
   ต้องชิดล่างไม่ใช่ยืดเต็ม ไม่งั้นปุ่มจะสูงเท่าป้าย+ช่องรวมกัน */
.input-group-field { align-items: flex-end; }
.input-group-field > .field { flex: 1 1 200px; min-width: 0; }

.input-affix {
    display: inline-flex;
    align-items: center;
    padding: 0 var(--space-2);
    background: var(--color-surface-muted);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-base);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    white-space: nowrap;
}

.color-input { width: var(--space-6); min-width: var(--space-6); padding: var(--space-1); height: var(--height-input); }

/* --------------------------------------------------------------- table */

/* ‼️ ต้องเป็น position: relative — ไม่งั้นลูกที่เป็น position:absolute (เช่น .visually-hidden ในหัวคอลัมน์)
   จะหลุดออกไปนอกกรอบที่เลื่อนได้ แล้วดันให้ทั้งหน้าเลื่อนแนวนอนตามไปด้วย
   (เจอจริงที่จอ 820px หน้ารายการเว็บไซต์ของทีมงาน: หน้าเลื่อนได้ 881px ทั้งที่จอกว้าง 798px) */
.table-wrap {
    position: relative;
    width: 100%;
    overflow-x: auto;
    border-radius: var(--radius-lg);
}

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
    background: var(--color-surface);
}

.table th,
.table td {
    padding: var(--space-2) var(--space-3);
    text-align: left;
    border-bottom: var(--border-width) solid var(--color-border);
    vertical-align: middle;
}

.table th {
    background: var(--color-surface);
    color: var(--color-text-muted-on-soft);
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-xs);
    letter-spacing: .02em;
    white-space: nowrap;
}

/* หัวคอลัมน์ที่กดเรียงลำดับได้ — ต้องเป็น <a> เพราะเปลี่ยน URL จริง (เรียงฝั่งเซิร์ฟเวอร์) */
.table th a {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: inherit;
}

.table th a:hover { color: var(--color-text); text-decoration: none; }
.table th a .icon { width: var(--font-size-sm); height: var(--font-size-sm); opacity: .55; }
.table th a.is-sorted { color: var(--color-primary-strong); }
.table th a.is-sorted .icon { opacity: 1; }

.table tbody tr { height: var(--height-row); }

.table tbody tr:hover { background: var(--color-surface-muted); }

.table tbody tr:last-child td { border-bottom: 0; }

.table .cell-numeric { text-align: right; font-variant-numeric: tabular-nums; }

.table .cell-actions { text-align: right; white-space: nowrap; }

.table-compact th,
.table-compact td { padding: var(--space-1) var(--space-2); }

/* --------------------------------------------------------------- badge */

.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 0 var(--space-2);
    height: var(--space-4);
    border-radius: var(--radius-pill);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    background: var(--color-neutral-soft);
    color: var(--color-neutral);
    white-space: nowrap;
}

.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-strong); }

.badge-dot {
    width: var(--space-2);
    height: var(--space-2);
    border-radius: var(--radius-pill);
    background: currentColor;
    flex: none;
}

/* --------------------------------------------------------------- alert */

.alert {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    padding: var(--space-3);
    border-radius: var(--radius-base);
    border: var(--border-width) solid transparent;
    font-size: var(--font-size-sm);
    margin-bottom: var(--space-3);
}

.alert-success { background: var(--color-success-soft); border-color: var(--color-success); color: var(--color-success); }
.alert-danger  { background: var(--color-danger-soft);  border-color: var(--color-danger);  color: var(--color-danger); }
.alert-warning { background: var(--color-warning-soft); border-color: var(--color-warning); color: var(--color-warning); }
.alert-info    { background: var(--color-info-soft);    border-color: var(--color-info);    color: var(--color-info); }

/* โทนกลาง — ใช้บอกว่า "เจ้านี้ทำไม่ได้" ซึ่งไม่ใช่ความผิดพลาดและไม่ใช่คำเตือน
   ‼️ ห้ามใช้สี semantic กับเรื่องนี้ · สีเตือนที่ใช้กับเรื่องที่ไม่ใช่ปัญหา
      ทำให้ผู้ใช้เลิกเชื่อสีเตือนทั้งระบบ แล้วมองข้ามของจริงในวันที่มีปัญหาจริง */
.alert-muted   { background: var(--color-surface-muted); border-color: var(--color-border); color: var(--color-text); }

.toast-stack {
    position: fixed;
    right: var(--space-4);
    bottom: var(--space-4);
    z-index: 80;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    max-width: 360px;
}

.toast {
    background: var(--color-surface);
    border-left: var(--space-1) solid var(--color-primary);
    box-shadow: var(--shadow-lg);
    border-radius: var(--radius-base);
    padding: var(--space-3);
    font-size: var(--font-size-sm);
}

.toast-success { border-left-color: var(--color-success); }
.toast-danger  { border-left-color: var(--color-danger); }
.toast-info    { border-left-color: var(--color-info); }

/* --------------------------------------------------- empty / loading state */

.empty-state {
    text-align: center;
    padding: var(--space-6) var(--space-4);
    color: var(--color-text-muted);
}

.empty-state-icon {
    width: var(--space-7);
    height: var(--space-7);
    border-radius: var(--radius-pill);
    background: var(--color-neutral-soft);
    color: var(--color-text-muted);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: var(--space-3);
}

.empty-state h3 { color: var(--color-text); }

.loading-state {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-5);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.spinner {
    width: var(--space-4);
    height: var(--space-4);
    border: 2px solid var(--color-border);
    border-top-color: var(--color-primary);
    border-radius: var(--radius-pill);
    animation: spin 700ms linear infinite;
    flex: none;
}

@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ---------------------------------------------------------- pagination */

.pagination {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    flex-wrap: wrap;
    list-style: none;
    padding: 0;
    margin: 0;
}

.pagination a,
.pagination span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--space-5);
    height: var(--space-5);
    padding: 0 var(--space-2);
    border-radius: var(--radius-base);
    border: var(--border-width) solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: var(--font-size-sm);
}

.pagination a:hover { background: var(--color-surface-muted); text-decoration: none; }

.pagination .is-current {
    background: var(--btn-primary-bg);
    border-color: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    font-weight: var(--font-weight-medium);
}

.pagination .is-disabled { color: var(--color-text-muted); background: var(--color-surface-muted); }

.list-toolbar {
    display: flex;
    align-items: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-bottom: var(--space-3);
}

.list-toolbar .field { min-width: 160px; }

.list-summary {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    margin-top: var(--space-3);
}

/* --------------------------------------------------------------- modal */

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: var(--color-backdrop);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-3);
    z-index: 90;
}

.modal-backdrop[hidden] { display: none; }

.modal {
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: 100%;
    max-width: 560px;
    max-height: 90vh;
    overflow-y: auto;
}

.modal-lg { max-width: 860px; }

.modal-header {
    padding: var(--space-3) var(--space-4);
    border-bottom: var(--border-width) solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
}

.modal-header h2 { margin: 0; font-size: var(--font-size-lg); }

.modal-body { padding: var(--space-4); }

.modal-footer {
    padding: var(--space-3) var(--space-4);
    border-top: var(--border-width) solid var(--color-border);
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.drawer {
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    width: min(480px, 100%);
    background: var(--color-surface);
    box-shadow: var(--shadow-lg);
    z-index: 90;
    display: flex;
    flex-direction: column;
}

.drawer[hidden] { display: none; }

/* ----------------------------------------------------- support button */

.support-fab {
    position: fixed;
    right: var(--space-4);
    bottom: var(--space-4);
    z-index: 70;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    height: var(--space-6);
    padding: 0 var(--space-3);
    border-radius: var(--radius-pill);
    background: var(--color-secondary);
    color: var(--color-text-inverse);
    border: 0;
    box-shadow: var(--shadow-lg);
    cursor: pointer;
    font-family: inherit;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
}

.support-fab:hover { background: var(--btn-primary-bg); color: var(--btn-primary-fg); }

.support-type-list { display: grid; gap: var(--space-2); }

.support-type {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    background: var(--color-surface);
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    font-size: var(--font-size-sm);
    width: 100%;
    transition: border-color var(--transition-base), background var(--transition-base);
}

.support-type:hover { border-color: var(--color-primary); background: var(--color-primary-soft); }

.support-type-title { font-weight: var(--font-weight-medium); color: var(--color-text); }

.support-type-hint { color: var(--color-text-muted); font-size: var(--font-size-xs); }

/* ---------------------------------------------------------------- tabs */

.tabs {
    display: flex;
    gap: var(--space-1);
    border-bottom: var(--border-width) solid var(--color-border);
    margin-bottom: var(--space-4);
    overflow-x: auto;
}

.tab {
    padding: var(--space-2) var(--space-3);
    border-bottom: 2px solid transparent;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    white-space: nowrap;
}

.tab:hover { color: var(--color-text); text-decoration: none; }

.tab.is-active {
    color: var(--color-primary-strong);
    border-bottom-color: var(--color-primary);
    font-weight: var(--font-weight-medium);
}

/* --------------------------------------------------------------- steps */

.steps {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-bottom: var(--space-4);
}

.step {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.step-number {
    width: var(--space-5);
    height: var(--space-5);
    border-radius: var(--radius-pill);
    background: var(--color-neutral-soft);
    color: var(--color-text-muted-on-soft);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: var(--font-weight-medium);
    flex: none;
}

.step.is-active { color: var(--color-text); font-weight: var(--font-weight-medium); }
.step.is-active .step-number { background: var(--btn-primary-bg); color: var(--btn-primary-fg); }
.step.is-done .step-number { background: var(--color-success-soft); color: var(--color-success); }

.step-divider { flex: 1 1 var(--space-5); height: var(--border-width); background: var(--color-border); min-width: var(--space-4); }

/* ------------------------------------------------------ choice / option */

.choice-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: var(--space-3);
}

.choice {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    background: var(--color-surface);
    cursor: pointer;
    transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.choice:hover { border-color: var(--color-primary); }

.choice input { position: absolute; opacity: 0; pointer-events: none; }

.choice.is-selected,
.choice:has(input:checked) {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-soft);
}

.choice-title { font-weight: var(--font-weight-medium); }
.choice-hint { font-size: var(--font-size-xs); color: var(--color-text-muted); }

/* ---------------------------------------------- การ์ดแม่แบบ (ภาพเป็นพระเอก)

   ‼️ ภาพในการ์ดคือ "ภาพหน้าจอจริง" ของเว็บที่สร้างจากแม่แบบนั้น
      (สร้างด้วย scripts/build-template-previews.php) จึงตรงกับสิ่งที่ผู้ใช้จะได้เสมอ
   ‼️ การ์ดต้องใหญ่พอให้ดูออกว่าเป็นธุรกิจอะไรโดยไม่ต้องอ่านตัวหนังสือ
      ของเดิมกว้าง 260px และครอบ 4:3 ทำให้เห็นแค่หัวเว็บ อ่านไม่ออกว่าเป็นแม่แบบของอะไร */

.template-card { padding: 0; overflow: hidden; }

.template-grid { grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: var(--space-4); }

/* กรอบเบราว์เซอร์จำลอง — วาดด้วย CSS ล้วน ไม่มีไฟล์ภาพเพิ่ม */
.template-frame { display: block; border-bottom: var(--border-width) solid var(--color-border); }

.template-frame-bar {
    display: flex;
    align-items: center;
    gap: 5px;
    height: 26px;
    padding: 0 var(--space-2);
    background: var(--color-surface-muted);
    border-bottom: var(--border-width) solid var(--color-border);
}

.template-frame-bar > span {
    width: 7px;
    height: 7px;
    border-radius: var(--radius-pill);
    background: var(--color-border-strong);
    flex: none;
}

.template-frame-address {
    flex: 1 1 auto;
    height: 10px;
    margin-left: var(--space-2);
    border-radius: var(--radius-pill);
    background: var(--color-border);
}

.template-preview {
    aspect-ratio: 3 / 2;
    background: var(--color-secondary-soft);
    display: block;
    overflow: hidden;
}

.template-preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: top center;
    display: block;
    transition: transform var(--transition-base);
}

.template-card:hover .template-preview img { transform: scale(1.02); }

/* ‼️ ข้อความใต้ภาพต้องสั้น — ภาพคือสิ่งที่บอกว่าเป็นแม่แบบของธุรกิจอะไร */
.template-card .choice-body {
    padding: var(--space-3);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.template-card .choice-hint {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

@media (max-width: 600px) {
    .template-grid { grid-template-columns: 1fr; }
}

/* ------------------------------------------- ขั้นตอนแนะนำ (setup progress)

   ‼️ สถานะทุกขั้นมาจากข้อมูลจริง (SetupProgressService) แผงนี้จึงหายไปเองเมื่อครบ
      ห้ามทำให้ดู "เกือบเสร็จ" ด้วยการนับขั้นที่ระบบทำให้เองเป็นผลงานของผู้ใช้ */

/* ‼️ ข้อความต้องใช้ --color-primary-strong เสมอ — สีแบรนด์บนพื้นขาวได้ contrast แค่ 3.58:1
   ซึ่งไม่ผ่าน WCAG AA (ดูหมายเหตุที่ตัวแปรสีด้านบนของไฟล์) */
.setup-percent {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-bold);
    color: var(--color-primary-strong);
    flex: none;
}

.setup-bar {
    height: 8px;
    border-radius: var(--radius-pill);
    background: var(--color-neutral-soft);
    overflow: hidden;
}

.setup-bar-fill {
    display: block;
    height: 100%;
    width: var(--setup-percent, 0%);
    border-radius: var(--radius-pill);
    background: var(--color-primary);
    transition: width var(--transition-base);
}

.setup-steps {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: var(--space-2);
    list-style: none;
    margin: 0;
    padding: 0;
    counter-reset: none;
}

.setup-step a {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-2);
    border-radius: var(--radius-base);
    text-align: center;
    text-decoration: none;
    color: var(--color-text-muted);
    transition: background var(--transition-base);
}

.setup-step a:hover { background: var(--color-surface-muted); }

.setup-step-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--space-5);
    height: var(--space-5);
    border-radius: var(--radius-pill);
    border: var(--border-width) solid var(--color-border-strong);
    background: var(--color-surface);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    flex: none;
}

.setup-step-label { font-size: var(--font-size-sm); }

.setup-step.is-done a { color: var(--color-text); }

.setup-step.is-done .setup-step-mark {
    background: var(--color-success-soft);
    border-color: var(--color-success);
    color: var(--color-success);
}

/* ------------------------------------------------- หน้าเปิดใช้เว็บไซต์ */

.launch-pages { list-style: none; margin: 0; padding: 0; }

.launch-page {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-top: var(--border-width) solid var(--color-border);
}

.launch-page-check { display: inline-flex; color: var(--color-success); flex: none; }

.launch-page-name {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
}

.launch-live {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3);
    border-radius: var(--radius-base);
    background: var(--color-success-soft);
    color: var(--color-success);
}

.launch-live-icon { display: inline-flex; flex: none; }

.launch-url {
    display: block;
    padding: var(--space-2) var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    background: var(--color-surface-muted);
    word-break: break-all;
    font-size: var(--font-size-sm);
}

.button-row { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* -------------------------------------------------------- editor layout */

.editor {
    display: grid;
    grid-template-columns: 320px minmax(0, 1fr);
    gap: var(--space-4);
    align-items: start;
}

.editor-panel {
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    position: sticky;
    top: calc(var(--topbar-height) + var(--space-3));
    max-height: calc(100vh - var(--topbar-height) - var(--space-5));
    overflow-y: auto;
}

.editor-canvas {
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    min-width: 0;
}

.section-list { display: flex; flex-direction: column; }

.section-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-bottom: var(--border-width) solid var(--color-border);
}

.section-item:last-child { border-bottom: 0; }

.section-item.is-hidden { background: var(--color-surface-muted); color: var(--color-text-muted); }

.section-item-title { font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); }

.section-item-type { font-size: var(--font-size-xs); color: var(--color-text-muted); }

.section-item-actions { display: flex; align-items: center; gap: var(--space-1); }

.preview-frame {
    width: 100%;
    height: 70vh;
    border: 0;
    display: block;
    background: var(--color-surface);
}

.preview-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-bottom: var(--border-width) solid var(--color-border);
    background: var(--color-surface-muted);
    flex-wrap: wrap;
}

.preview-frame.is-mobile { max-width: 420px; margin: 0 auto; border-left: var(--border-width) solid var(--color-border); border-right: var(--border-width) solid var(--color-border); }

/* --------------------------------------------------------- media grid */

.media-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: var(--space-3);
}

.media-item {
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    overflow: hidden;
    background: var(--color-surface);
    display: flex;
    flex-direction: column;
}

.media-thumb {
    aspect-ratio: 4 / 3;
    background: var(--color-neutral-soft);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.media-thumb img { width: 100%; height: 100%; object-fit: cover; }

.media-meta { padding: var(--space-2); font-size: var(--font-size-xs); color: var(--color-text-muted); display: flex; flex-direction: column; gap: var(--space-1); }

/* --------------------------------------------------------- auth layout */

/* ‼️ หน้าที่ยังไม่ล็อกอินทั้งชุดใช้กฎด้านล่างนี้ร่วมกัน — สมัคร / เข้าสู่ระบบ / ลืมรหัสผ่าน /
   ตั้งรหัสผ่านใหม่ เปิดติดกันแล้วต้องรู้ว่าเป็นชุดเดียวกัน ห้ามมีกฎเฉพาะหน้าใดหน้าหนึ่ง */

/* ‼️ พื้นหลังเป็นครีมอุ่น ไม่ใช่พื้นกรมท่าทึบแบบเดิม (Visual Standard 2026-08-23)
   เหตุผลเดียวกับแถบข้างของระบบจัดการ: กรมท่าเต็มครึ่งจอกินสัดส่วนสีเกิน 30%
   ตอนนี้กรมท่าย้ายไปอยู่ที่ตัวอักษรพาดหัวซึ่งเป็นจุดที่ต้องการน้ำหนักจริง */
.auth-body { background: var(--color-surface); }

.auth-shell {
    /* ‼️ dvh ไม่ใช่ vh — บนมือถือ vh นับรวมแถบที่อยู่ของเบราว์เซอร์ ทำให้ฟอร์มถูกดันตกจอ
       min-height ไม่ใช่ height เพื่อให้ยังเลื่อนได้เองเมื่อมี error หรือจอเตี้ยกว่ามาตรฐาน */
    min-height: 100dvh;
    display: grid;
    /* 43 / 57 ตามสัดส่วนที่อนุมัติ — แผงแบรนด์แคบกว่า ฟอร์มได้พื้นที่มากกว่า */
    grid-template-columns: minmax(0, 43fr) minmax(0, 57fr);
}

/* ------------------------------------------------- แผงแบรนด์ (ฝั่งซ้าย) */

.auth-aside {
    position: relative;
    overflow: hidden;
    background: var(--auth-aside-bg);
    color: var(--color-text);
    padding: var(--space-5) var(--space-6) 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: var(--space-4);
    border-right: var(--border-width) solid var(--color-border);
}

/* วงกลมนวลมุมบนขวาให้พื้นครีมไม่แบนเป็นแผ่นเดียว — วาดด้วย gradient ไม่ใช้ไฟล์ภาพ */
.auth-aside::before {
    content: "";
    position: absolute;
    inset: -34% -26% auto auto;
    width: 66%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: var(--auth-aside-glow);
    pointer-events: none;
}

/* ส่วนโค้งกรมท่ามุมล่างซ้าย — จุดเดียวที่สีรองของแบรนด์ยังเป็นพื้นที่ใหญ่ */
.auth-aside::after {
    content: "";
    position: absolute;
    left: -18%;
    bottom: -26%;
    width: 46%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: var(--color-secondary);
    opacity: .9;
    pointer-events: none;
}

.auth-aside-top {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    max-width: 30rem;
}

.auth-brand { display: inline-flex; align-items: center; gap: var(--space-2); color: inherit; text-decoration: none; }

.auth-brand-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--radius-base);
    /* ‼️ ตัวอักษรขาวบน --color-primary ได้ 3.58:1 ไม่ผ่าน AA — ต้องใช้ตัวเข้ม (design.md ข้อ 3.8) */
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-sm);
    letter-spacing: .02em;
}

.auth-brand-name { font-size: var(--font-size-lg); font-weight: var(--font-weight-bold); }

.auth-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    align-self: flex-start;
    margin: 0;
    padding: var(--space-2) var(--space-3);
    border: var(--border-width) solid var(--color-primary-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-sm);
    box-shadow: var(--shadow-sm);
}

.auth-badge .icon { color: var(--color-primary-strong); flex: none; }

.auth-headline {
    margin: 0;
    color: var(--color-secondary-text);
    font-size: var(--font-size-3xl);
    line-height: 1.25;
    /* ‼️ ภาษาไทยไม่มีช่องว่างระหว่างคำ เบราว์เซอร์จึงตัดบรรทัดตรงไหนก็ได้
       และมักเหลือคำสั้นๆ ค้างบรรทัดสุดท้ายคำเดียว (เช่น "ได้") ซึ่งอ่านแล้วสะดุด
       balance เกลี่ยความยาวของทุกบรรทัดให้ใกล้กัน · เบราว์เซอร์ที่ไม่รองรับก็ตัดแบบเดิม */
    text-wrap: balance;
}

/* ‼️ คำที่เน้นในพาดหัวใช้สีหลักของแบรนด์ ไม่ใช่สีใหม่นอกชุด
   และห้ามตัดคำกลางคำเน้น — ภาษาไทยไม่มีช่องว่างระหว่างคำ เบราว์เซอร์จึงตัดตรงไหนก็ได้
   ปล่อยไว้จะได้ "น่าเชื่อ / ถือ" คร่อมสองบรรทัดซึ่งอ่านแล้วสะดุด */
.auth-accent { color: var(--color-primary-strong); white-space: nowrap; }

.auth-subtitle { margin: 0; color: var(--color-text-muted-on-soft); max-width: 26rem; }

.auth-features {
    list-style: none;
    margin: var(--space-1) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.auth-features li { display: flex; align-items: flex-start; gap: var(--space-3); }

.auth-feature-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--radius-base);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    color: var(--color-primary-strong);
    box-shadow: var(--shadow-sm);
}

.auth-feature-text { display: flex; flex-direction: column; gap: 2px; }

.auth-feature-title { font-weight: var(--font-weight-bold); font-size: var(--font-size-sm); color: var(--color-secondary-text); }

.auth-feature-hint { color: var(--color-text-muted-on-soft); font-size: var(--font-size-xs); }

/* ‼️ ภาพเป็นภาพผลิตภัณฑ์จริงของระบบ (ตัวสร้างเว็บ + มุมมองมือถือ + รายงานผู้เข้าชม)
   ห้ามใช้ข้อมูลลูกค้าจริงในภาพ — ทุกตัวเลขในภาพเป็นค่าสมมุติที่วาดไว้ในไฟล์ภาพเอง
   ‼️ ต้องมี width/height เสมอ ไม่งั้นหน้าจะกระตุกตอนภาพโหลดเสร็จ */
.auth-artwork {
    position: relative;
    z-index: 1;
    display: block;
    width: 100%;
    max-width: 34rem;
    height: auto;
    margin: 0 auto;
}

/* ------------------------------------------------------- ฟอร์ม (ฝั่งขวา) */

.auth-main {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: var(--space-3) var(--space-4) var(--space-5);
    background: var(--color-surface);
}

.auth-topbar { width: 100%; display: flex; align-items: center; justify-content: flex-end; gap: var(--space-2); }

/* ‼️ การ์ดต้องไม่มี scroll ของตัวเอง — ถ้าเนื้อหาสูงเกิน ให้ทั้งหน้าเลื่อนแทน
   (ผู้ใช้ที่เลื่อนในการ์ดจะมองไม่เห็นว่ายังมีช่องเหลืออยู่ข้างล่าง) */
.auth-card {
    width: 100%;
    max-width: 28rem;
    margin: auto 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-5);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-xl);
    background: var(--color-surface);
    box-shadow: var(--shadow-lg);
    overflow: visible;
}

/* ‼️ ช่องกรอกของหน้าที่ยังไม่ล็อกอินสูงกว่าในระบบจัดการ (46px) ตามมาตรฐานที่อนุมัติ
   คุมด้วย token ตัวเดียว ไม่ได้ไล่ตั้งค่าทีละหน้า */
.auth-card .input,
.auth-card .select { min-height: var(--height-input-auth); height: var(--height-input-auth); }
.auth-card .btn-lg { height: var(--height-input-auth); }
.auth-card .field { gap: var(--space-1); }
.auth-card .input-affix .input { padding-left: 2.75rem; }

/* ‼️ จอเตี้ยบีบ "ระยะห่าง" เท่านั้น ไม่แตะขนาดตัวอักษรและไม่แตะความสูงของช่องกรอก
      เป้าหมายคือหน้าสมัครใช้งานอยู่ในหนึ่งหน้าจอโดยไม่ต้องเลื่อน
      แต่ตัวอักษรที่เล็กลงหรือช่องกรอกที่เตี้ยลง แลกมาด้วยการใช้งานที่แย่ลงจริง จึงไม่ทำ

   ‼️ เงื่อนไขเป็น max-height ไม่ใช่ max-width — ปัญหานี้เป็นเรื่องความสูงล้วน ๆ
      จอ 1920x1080 ไม่มีปัญหา ส่วนจอ 1366x768 มี ทั้งที่กว้างต่างกันมาก
      ถ้าผูกกับความกว้าง จะไปบีบจอกว้างที่ไม่ได้มีปัญหา และไม่ช่วยจอที่มีปัญหาจริง

   ‼️ 820px คือความสูงหน้าต่างที่ทำให้พื้นที่ที่เห็นจริงเหลือราว 666px
      ต่ำกว่านั้นฟอร์มสมัครเริ่มล้น (วัดจากเบราว์เซอร์จริงด้วย scrollHeight เทียบ clientHeight)
   ‼️ ใช้ 900px เพราะครอบจอโน้ตบุ๊กมาตรฐานทั้ง 1440x900 และ 1366x768 ซึ่งเป็นสองจอที่มีปัญหาจริง
      จอ 1080p ขึ้นไปไม่เข้าเงื่อนไข จึงยังได้ระยะห่างแบบเต็มตามเดิม */
@media (max-height: 900px) {
    .auth-card {
        gap: var(--space-2);
        padding: var(--space-4);
    }

    .auth-card .stack-4 { gap: var(--space-3); }

    .auth-head { gap: var(--space-1); }
}

/* ฟอร์มสมัครใช้งานจับคู่ช่องรหัสผ่านไว้แถวเดียวกันบนจอกว้าง — มือถือเรียงเดี่ยวเอง */
.auth-grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }

/* ‼️ จัดชิดขอบล่าง เพื่อให้ "ช่องกรอก" ของสองคอลัมน์ตรงแนวกันเสมอ แม้ป้ายยาวไม่เท่ากัน
      ภาษาอังกฤษมีป้ายที่ยาวกว่าภาษาไทยหลายจุด เช่น "Organization or business name"
      ซึ่งตกสองบรรทัด แล้วช่องกรอกฝั่งนั้นถูกดันต่ำลงจนไม่ตรงกับอีกฝั่ง — เห็นตอนดูภาพจริง
      ‼️ วิธีนี้ไม่เพิ่มความสูงเลย ต่างจากการกันที่ให้ป้ายสองบรรทัดทุกแถว
         ซึ่งจะกินความสูงเพิ่มทุกแถวรวมกันหลายสิบพิกเซล

   ‼️ ใช้กับแถวที่ทั้งสองช่องไม่มีอะไรต่อท้ายใต้ช่องกรอกเท่านั้น
      แถวรหัสผ่านใช้ไม่ได้ เพราะช่องซ้ายมีแถบวัดความแข็งแรงโผล่ขึ้นมาตอนพิมพ์
      ถ้าชิดล่าง ช่องขวาจะถูกดันลงตามทันทีที่เริ่มพิมพ์ */
.auth-grid-bottom { align-items: end; }

.auth-head { display: flex; flex-direction: column; gap: var(--space-2); }

.auth-head-center { align-items: center; text-align: center; }

.auth-card-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--radius-base);
    /* ‼️ เหตุผลเดียวกับ .auth-brand-mark — ตัวอักษรบนสีแบรนด์ต้องใช้ตัวเข้ม */
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    font-weight: var(--font-weight-bold);
}

.auth-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 50%;
    background: var(--color-primary-soft);
    color: var(--color-primary);
}

.auth-title { margin: 0; font-size: var(--font-size-2xl); }

.auth-lead { margin: 0; color: var(--color-text-muted); font-size: var(--font-size-sm); }

.auth-row-end { display: flex; justify-content: flex-end; font-size: var(--font-size-sm); }

.auth-note {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    margin: 0;
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    background: var(--color-surface-muted);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.auth-note-icon { display: inline-flex; flex: 0 0 auto; color: var(--color-info); }

.auth-foot { text-align: center; font-size: var(--font-size-sm); color: var(--color-text-muted); }

.auth-foot a { display: inline-flex; align-items: center; gap: var(--space-1); font-weight: var(--font-weight-bold); }

.auth-links { display: flex; justify-content: space-between; gap: var(--space-2); font-size: var(--font-size-sm); flex-wrap: wrap; }

/* ------------------------------- ช่องกรอกที่มีไอคอนนำหน้าและปุ่มดูรหัสผ่าน */

.input-affix { position: relative; display: block; }

.input-affix .input { padding-left: 2.75rem; }

.input-affix .input[type="password"],
.input-affix .input.has-reveal { padding-right: 2.75rem; }

.input-icon {
    position: absolute;
    top: 50%;
    left: var(--space-3);
    transform: translateY(-50%);
    display: inline-flex;
    color: var(--color-text-muted);
    pointer-events: none;
}

.input-reveal {
    position: absolute;
    top: 50%;
    right: var(--space-2);
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* ‼️ 2.25rem = 36px ผ่านเกณฑ์เป้าสัมผัสขั้นต่ำ 24px ของ WCAG 2.2 AA */
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: 0;
    border-radius: var(--radius-base);
    background: transparent;
    color: var(--color-text-muted);
    cursor: pointer;
}

.input-reveal:hover { color: var(--color-text); }

/* -------------------------------------- แถบความแข็งแรงของรหัสผ่าน */

/* ‼️ ซ่อนทั้งแถบจนกว่าจะเริ่มพิมพ์ — เส้นเทาลอยอยู่ใต้ช่องว่างๆ อ่านแล้วเหมือนเส้นขีดฆ่า
   JS เติม is-typing ให้เมื่อมีตัวอักษร (ปิด JS แล้วแถบนี้ไม่โผล่ ซึ่งถูกต้อง เพราะมันคำนวณด้วย JS) */
.pw-strength { display: none; flex-direction: column; gap: var(--space-1); }

.pw-strength.is-typing { display: flex; }

.pw-strength-track {
    display: block;
    height: .25rem;
    border-radius: var(--radius-pill);
    background: var(--color-border);
    overflow: hidden;
}

.pw-strength-bar {
    display: block;
    width: 0;
    height: 100%;
    border-radius: var(--radius-pill);
    background: var(--color-danger);
    transition: width .15s ease-out;
}

.pw-strength-bar.is-fair { background: var(--color-warning); }

.pw-strength-bar.is-strong { background: var(--color-success); }

.pw-strength-label { font-size: var(--font-size-xs); color: var(--color-text-muted); }

/* ==========================================================================
   ศูนย์ช่วยเหลือ (manual.md ข้อ 6)

   ‼️ สองหน้านี้เป็น "เอกสาร" ไม่ใช่ "หน้าจัดการข้อมูล" ความกว้างของบรรทัดจึงถูกจำกัด
      ไม่ใช่ยืดเต็มจอเหมือนหน้าตาราง — บรรทัดที่ยาวเกิน ~80 ตัวอักษรอ่านแล้วหลงบรรทัด
   ‼️ ทุกอย่างในสองหน้านี้ทำงานได้โดยไม่ต้องมี JavaScript
      ค้นหา = ฟอร์ม GET · เมนูพับได้ = <details> ของเบราว์เซอร์ · สารบัญ = ลิงก์ #id
   ========================================================================== */

.help-center {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: var(--space-5);
    align-items: start;
}

.help-main { min-width: 0; }

.help-hero-title { font-size: var(--font-size-3xl); margin: 0 0 var(--space-1); }

.help-hero-subtitle { color: var(--color-text-muted); font-size: var(--font-size-lg); }

/* ------------------------------------------------------------- ช่องค้นหา */

.help-search {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-card);
}

.help-search:focus-within { border-color: var(--color-primary); box-shadow: 0 0 0 3px var(--color-primary-soft); }

.help-search-icon { display: inline-flex; flex: none; padding-left: var(--space-2); color: var(--color-text-muted); }

/* ‼️ ช่องกรอกไม่มีขอบของตัวเอง — ขอบเป็นของกล่องทั้งใบ ไม่งั้นจะได้กรอบซ้อนกันสองชั้น */
.help-search-input {
    flex: 1 1 auto;
    min-width: 0;
    height: var(--height-input);
    border: 0;
    background: transparent;
    color: var(--color-text);
    font-family: inherit;
    font-size: var(--font-size-base);
}

.help-search-input:focus { outline: none; }

.help-search-submit { flex: none; }

.help-section-title {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-lg);
}

.help-section-mark { display: inline-flex; color: var(--color-primary-strong); }

.help-section-mark .icon { width: 20px; height: 20px; }

.help-results-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }

/* ------------------------------------------------------------- ผลค้นหา */

.help-results { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }

.help-result {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    color: var(--color-text);
    text-decoration: none;
    transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.help-result:hover { border-color: var(--color-primary); box-shadow: var(--shadow-card); text-decoration: none; }

.help-result-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }

.help-result-group { font-size: var(--font-size-xs); color: var(--color-primary-strong); font-weight: var(--font-weight-medium); }

.help-result-title { font-weight: var(--font-weight-medium); }

.help-result-summary { font-size: var(--font-size-sm); color: var(--color-text-muted); }

/* --------------------------------------------------- เริ่มต้นอย่างรวดเร็ว */

.help-quick {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-3);
    list-style: none;
    margin: 0;
    padding: 0;
    counter-reset: none;
}

.help-quick-card {
    position: relative;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-3);
    height: 100%;
    padding: var(--space-4) var(--space-3) var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    color: var(--color-text);
    text-decoration: none;
    transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.help-quick-card:hover { border-color: var(--color-primary); box-shadow: var(--shadow-card); text-decoration: none; }

/* ‼️ เลขลำดับอยู่มุมบนซ้าย ไม่ใช่ในแถวเดียวกับไอคอน — สามข้อนี้คือ "ลำดับที่ควรทำ"
      ถ้าวางปนกับไอคอนจะอ่านเหมือนเป็นของตกแต่งอีกชิ้น */
.help-quick-step {
    position: absolute;
    top: var(--space-2);
    left: var(--space-3);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--space-4);
    height: var(--space-4);
    border-radius: var(--radius-pill);
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-bold);
}

.help-quick-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--space-6);
    height: var(--space-6);
    flex: none;
    border-radius: var(--radius-base);
    background: var(--tint-brand-bg);
    color: var(--tint-brand-fg);
}

.help-quick-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.help-quick-title { font-weight: var(--font-weight-medium); }

.help-quick-summary {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    /* ‼️ คำอธิบายยาวไม่เท่ากันทุกใบ ตัดที่สองบรรทัดเพื่อให้การ์ดสามใบสูงเท่ากัน */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ----------------------------------------------------------- การ์ดหมวด */

.help-categories {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-3);
    align-items: stretch;
}

/* ‼️ การ์ดทุกใบสูงเท่ากันและรายการบทความยืดเต็มพื้นที่ที่เหลือ
      หมวดที่มีบทความน้อยกว่าจะได้กล่องสูงเท่ากัน แต่ต้องไม่เหลือช่องว่างกลางใบ
      จำนวนบทความจึงถูกดันไปติดขอบล่างเสมอ */
.help-category { display: flex; flex-direction: column; padding: var(--space-4); gap: var(--space-3); }

.help-category-head { display: flex; align-items: flex-start; gap: var(--space-3); }

.help-category-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--space-6);
    height: var(--space-6);
    flex: none;
    border-radius: var(--radius-pill);
}

.help-category-title { font-size: var(--font-size-base); }

.help-category-hint { font-size: var(--font-size-xs); color: var(--color-text-muted); line-height: var(--line-height-base); }

.help-category-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; flex: 1; }

.help-category-link {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) 0;
    color: var(--color-text);
    font-size: var(--font-size-sm);
    text-decoration: none;
    border-bottom: var(--border-width) solid var(--color-border);
}

.help-category-list li:last-child .help-category-link { border-bottom: 0; }

.help-category-link:hover { color: var(--color-primary-strong); text-decoration: none; }

.help-category-link .icon { flex: none; width: 16px; height: 16px; color: var(--color-text-muted); }

.help-category-link .icon:last-child { margin-left: auto; }

.help-category-link:hover .icon { color: var(--color-primary-strong); }

.help-category-more { color: var(--color-primary-strong); font-weight: var(--font-weight-medium); }

.help-category-foot {
    margin-top: auto;
    padding-top: var(--space-2);
    border-top: var(--border-width) solid var(--color-border);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

/* ------------------------------------------- แถบขวา: ความคืบหน้าของคุณ */

.help-side { position: sticky; top: var(--space-4); }

.help-progress { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4); }

.help-progress-label { font-weight: var(--font-weight-medium); }

.help-progress-count { display: flex; align-items: baseline; gap: 2px; color: var(--color-text-muted); }

.help-progress-count strong { font-size: var(--font-size-2xl); color: var(--color-primary-strong); line-height: 1; }

.help-progress-bar { height: 6px; border-radius: var(--radius-pill); background: var(--color-neutral-soft); overflow: hidden; }

.help-progress-bar span { display: block; height: 100%; width: var(--progress, 0%); background: var(--btn-primary-bg); }

.help-progress-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }

.help-progress-step { display: flex; align-items: center; gap: var(--space-2); font-size: var(--font-size-sm); }

.help-progress-step a { color: var(--color-text-muted); text-decoration: none; }

.help-progress-step a:hover { color: var(--color-text); }

/* ‼️ เครื่องหมายบอกสถานะสามแบบ ต่างกันด้วย "รูปร่าง + สี" ไม่ใช่สีอย่างเดียว
      เสร็จแล้ว = เครื่องหมายถูกบนพื้นเขียว · ข้อถัดไป = เลขบนพื้นส้ม · ที่เหลือ = เลขบนพื้นเทา */
.help-progress-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--space-4);
    height: var(--space-4);
    flex: none;
    border-radius: var(--radius-pill);
    background: var(--color-neutral-soft);
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
}

.help-progress-mark .icon { width: 12px; height: 12px; }

.help-progress-step.is-done .help-progress-mark { background: var(--tint-green-bg); color: var(--tint-green-fg); }
.help-progress-step.is-done a { color: var(--color-text); }

.help-progress-step.is-next .help-progress-mark { background: var(--btn-primary-bg); color: var(--btn-primary-fg); }
.help-progress-step.is-next a { color: var(--color-text); font-weight: var(--font-weight-medium); }

/* ==================================================== หน้าบทความคู่มือ */

/* ‼️ สัดส่วนสามคอลัมน์ยึดตามภาพต้นแบบ — เมนู 232 · เนื้อหาที่เหลือทั้งหมด · สารบัญ 222
      เดิมเมนูกับสารบัญกินไป 500px แล้วเว้นช่องอีก 48px เหลือเนื้อหาแค่ 45% ของพื้นที่
      ทั้งที่ต้นแบบให้เนื้อหา 55% · ผลคือภาพประกอบถูกย่อจนตัวหนังสือในภาพอ่านไม่ออก
      (วัดจากภาพจริงเทียบกับต้นแบบ 2026-08-31) */
.help-article-page {
    display: grid;
    grid-template-columns: 232px minmax(0, 1fr) 222px;
    gap: var(--space-5);
    align-items: start;
}

/* -------------------------------------------------------- เมนูซ้าย */

.help-article-nav {
    position: sticky;
    top: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    min-width: 0;
}

.help-nav-search {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 0 var(--space-2);
    height: var(--height-input);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    background: var(--color-surface);
    color: var(--color-text-muted);
}

.help-nav-search:focus-within { border-color: var(--color-primary); }

.help-nav-search input {
    flex: 1;
    min-width: 0;
    border: 0;
    background: transparent;
    color: var(--color-text);
    font-family: inherit;
    font-size: var(--font-size-sm);
}

.help-nav-search input:focus { outline: none; }

.help-nav-group { border-radius: var(--radius-base); }

.help-nav-group summary {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2);
    border-radius: var(--radius-base);
    cursor: pointer;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
    list-style: none;
}

/* ‼️ ซ่อนสามเหลี่ยมค่าเริ่มต้นของเบราว์เซอร์ แล้ววาดลูกศรของระบบเองแทน
      ไม่งั้นจะได้ตัวชี้สองอันในบรรทัดเดียว และหน้าตาต่างกันทุกเบราว์เซอร์ */
.help-nav-group summary::-webkit-details-marker { display: none; }

.help-nav-group summary:hover { background: var(--color-surface-muted); }

.help-nav-group summary:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

.help-nav-group[open] summary { color: var(--color-primary-strong); }

.help-nav-group-icon { display: inline-flex; flex: none; }

.help-nav-group-icon .icon { width: 18px; height: 18px; }

.help-nav-group-caret { display: inline-flex; flex: none; transition: transform var(--transition-base); }

.help-nav-group-caret .icon { width: 16px; height: 16px; }

.help-nav-group[open] .help-nav-group-caret { transform: rotate(180deg); }

.help-nav-list { list-style: none; margin: 0 0 var(--space-2); padding: 0; display: flex; flex-direction: column; }

.help-nav-link {
    display: block;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-base);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    text-decoration: none;
}

.help-nav-link:hover { background: var(--color-surface-muted); color: var(--color-text); text-decoration: none; }

/* ‼️ บทความที่กำลังอ่านต้องต่างจากรายการอื่นชัดเจน ไม่ใช่แค่ตัวหนา
      พื้นส้มอ่อน + ตัวอักษรส้ม + aria-current ที่โปรแกรมอ่านหน้าจอใช้ */
.help-nav-link.is-active {
    background: var(--color-primary-soft);
    color: var(--color-primary-strong);
    font-weight: var(--font-weight-medium);
}

/* ------------------------------------------------------- เนื้อบทความ */

.help-article-main { min-width: 0; }

.help-article-chip {
    background: var(--color-primary-soft);
    color: var(--color-primary-strong);
    align-self: flex-start;
}

.help-article-title { font-size: var(--font-size-2xl); line-height: var(--line-height-tight); }

.help-article-summary { color: var(--color-text-muted); font-size: var(--font-size-base); }

/* เวลาอ่านและวันที่ปรับปรุง — สองอย่างที่ผู้อ่านดูก่อนตัดสินใจว่าจะอ่านตอนนี้เลยไหม */
.help-article-meta {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex-wrap: wrap;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.help-article-meta span { display: inline-flex; align-items: center; gap: var(--space-1); }

.help-article-meta .icon { width: 16px; height: 16px; }

.help-article-nextprev { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }

.help-nextprev-card {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    color: var(--color-text);
    text-decoration: none;
    transition: border-color var(--transition-base);
}

.help-nextprev-card:hover { border-color: var(--color-primary); text-decoration: none; }

.help-nextprev-card.is-next { justify-content: flex-end; text-align: right; }

.help-nextprev-card .icon { flex: none; color: var(--color-text-muted); }

.help-nextprev-label { display: block; font-size: var(--font-size-xs); color: var(--color-text-muted); }

.help-nextprev-title {
    display: block;
    font-weight: var(--font-weight-medium);
    font-size: var(--font-size-sm);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.help-feedback {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-4);
    flex-wrap: wrap;
    padding: var(--space-3) var(--space-4);
}

.help-feedback-question { font-weight: var(--font-weight-medium); }

.help-feedback-actions { display: flex; align-items: center; gap: var(--space-2); }

.help-feedback-thanks { display: flex; align-items: center; gap: var(--space-2); color: var(--tint-green-fg); }

/* --------------------------------------------------------- สารบัญขวา */

.help-article-toc { min-width: 0; }

.help-toc-inner {
    position: sticky;
    top: var(--space-4);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

.help-toc-title { font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); margin-bottom: var(--space-2); }

.help-toc-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }

.help-toc-list a {
    display: flex;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    border-left: 2px solid transparent;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    text-decoration: none;
    line-height: var(--line-height-base);
}

.help-toc-list a:hover { color: var(--color-primary-strong); border-left-color: var(--color-primary); text-decoration: none; }

/* -------------------------------------------------------- manual pages */

.manual-layout { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: var(--space-4); align-items: start; }

.manual-article { line-height: var(--line-height-base); }

.manual-article h2 {
    font-size: var(--font-size-lg);
    margin-top: var(--space-5);
    /* ‼️ เว้นที่ให้หัวข้อพ้นแถบหัวที่เกาะอยู่ด้านบน ตอนกระโดดมาจากสารบัญ
          ไม่งั้นกดสารบัญแล้วหัวข้อจะไปอยู่ใต้แถบหัวพอดีจนมองไม่เห็น */
    scroll-margin-top: calc(var(--topbar-height) + var(--space-4));
}

.manual-article h2:first-child { margin-top: 0; }

.manual-article ol,
.manual-article ul { padding-left: var(--space-4); display: flex; flex-direction: column; gap: var(--space-1); }

.manual-article figure { margin: var(--space-3) 0; }

.manual-article figcaption { font-size: var(--font-size-sm); color: var(--color-text-muted); margin-top: var(--space-1); }

.manual-article img { border: var(--border-width) solid var(--color-border); border-radius: var(--radius-base); }

/* ------------------------------------------- ภาพตัดจากหน้าจอจริงในบทความ */

.manual-shot { margin: var(--space-3) 0 var(--space-4); }

/* ‼️ กรอบบาง มุมโค้ง เงาเบา — วาดด้วย CSS ไม่ใช่อบไว้ในไฟล์ภาพ
      เปลี่ยนหน้าตากรอบทีเดียวได้ทั้งระบบโดยไม่ต้องตัดภาพใหม่ทุกใบ
   ‼️ เป็น <button> จึงต้องล้างสไตล์ปุ่มของเบราว์เซอร์ออกให้หมดก่อน */
.manual-shot-frame {
    display: block;
    width: 100%;
    padding: 0;
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface-muted);
    box-shadow: var(--shadow-card);
    cursor: zoom-in;
    overflow: hidden;
    line-height: 0;
}

.manual-shot-frame:hover { border-color: var(--color-primary-border); }

.manual-shot-frame:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* ‼️ ภาพในกรอบไม่ต้องมีขอบของตัวเองอีก ขอบเป็นของกรอบ */
.manual-shot-frame img {
    display: block;
    width: 100%;
    height: auto;
    border: 0;
    border-radius: 0;
}

.manual-shot figcaption {
    margin-top: var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    line-height: var(--line-height-base);
}

/* ‼️ บทความที่ยังไม่มีภาพต้องบอกตรง ๆ ว่ารอจัดทำ ไม่ใช่กล่องสีเทาที่ดูเหมือนภาพจริง
      ผู้ใช้ที่เห็นกล่องเทาจะนึกว่าภาพโหลดไม่ขึ้นแล้วรอเก้อ */
.manual-shot-pending {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3);
    border: 1px dashed var(--color-border-strong);
    border-radius: var(--radius-base);
    background: var(--color-surface-muted);
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-sm);
}

/* ------------------------------------------------------ ภาพขยาย (lightbox) */

/* ‼️ ชั้นนี้ถูกสร้างโดย JavaScript เท่านั้น ปิด JavaScript แล้วจะไม่มีอะไรตรงนี้เลย
      และภาพในบทความยังอ่านออกครบเหมือนเดิม */
.lightbox {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
    background: var(--color-backdrop);
}

.lightbox img {
    max-width: 100%;
    max-height: calc(100vh - var(--space-7));
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-lg);
}

.lightbox-close {
    position: absolute;
    top: var(--space-3);
    right: var(--space-3);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--height-button);
    height: var(--height-button);
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
}

.lightbox-close:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* --------------------------------------------------------- misc blocks */

/* ‼️ ตารางนิยามเคยเป็น grid คอลัมน์ตายตัว (คอลัมน์แรกกว้างได้ถึง 200px)
   ปัญหาคือ grid ไม่ยอมย่อคอลัมน์แรกให้เล็กกว่าค่าที่ขอ พอกล่องแคบมาก
   คอลัมน์ค่าจึงเหลือ 0 แล้วป้ายสถานะข้างในดันล้นออกนอกการ์ด
   เจอจริงที่จอ 1024px: หักแถบข้าง 248px เหลือเนื้อที่ 754px การ์ดคอลัมน์ขวา
   จึงกว้างแค่ ~227px ล้นออกไป 6px — จอ 1440/820/390 ไม่เจอเพราะกว้างพอ
   หรือแคบพอจนกฎ 992px สั่งซ้อนบรรทัดไปแล้ว
   ‼️ ใช้ flex-wrap แทน เพราะมันวัดจาก "พื้นที่จริงของกล่อง" ไม่ใช่ความกว้างจอ
      กว้างพอ = หัวข้อกับค่าอยู่บรรทัดเดียวกันเหมือนเดิม
      แคบเกิน = ตัดบรรทัดเองอัตโนมัติ ไม่ต้องพึ่ง media query */
/* ‼️ เปลี่ยนจาก flex-wrap เป็น grid สองคอลัมน์ "หัวข้อ | ค่า" หนึ่งคู่ต่อหนึ่งแถว
   เหตุผล: flex-wrap ยัดหลายคู่ในบรรทัดเดียวเมื่อกล่องกว้าง แล้วอ่านไม่ออกว่าค่าไหนคู่กับหัวข้อไหน
           (เจอจริงที่หน้าเครื่องมือระบบ: "29 ตัวในซอร์ส" ไปอยู่ใต้หัวข้อ "สภาพแวดล้อม")
   ‼️ คอลัมน์ค่าเป็น minmax(0, 1fr) จึงหดได้จนสุด — ไม่กลับไปเป็นบั๊กล้นกรอบที่ 1024px แบบ grid เดิม */
.definition-list {
    display: grid;
    grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
    gap: var(--space-2) var(--space-3);
    font-size: var(--font-size-sm);
    margin: 0;
}

.definition-list dt { min-width: 0; color: var(--color-text-muted); }
.definition-list dd { min-width: 0; margin: 0; word-break: break-word; }

/* ‼️ ตัวแปรของ .code-block สำหรับคำสั่งที่คนต้อง "คัดลอกไปวาง"
      ตัวหลักใช้ overflow-x: auto ซึ่งถูกสำหรับโค้ดที่แค่อ่าน
      แต่คำสั่ง cron ที่ยาวกว่าจอ จะถูกตัดที่ขอบจนคนไม่รู้ว่ายังมีต่อ
      แล้วคัดลอกไปไม่ครบ · เจอจากภาพหน้าจอจริง 2026-08-27
   ‼️ ตัดคำที่ตำแหน่งไหนก็ได้ เพราะ path กับ argument ไม่มีช่องว่างให้ตัด */
.code-block--wrap {
    white-space: pre-wrap;
    word-break: break-all;
    overflow-x: visible;
}

.code-block {
    background: var(--color-secondary);
    color: var(--color-text-inverse);
    padding: var(--space-3);
    border-radius: var(--radius-base);
    font-family: var(--font-family-mono);
    font-size: var(--font-size-sm);
    overflow-x: auto;
    white-space: pre;
}

.progress {
    height: var(--space-2);
    background: var(--color-neutral-soft);
    border-radius: var(--radius-pill);
    overflow: hidden;
}

.progress-bar { height: 100%; width: var(--progress, 0%); background: var(--color-primary); }

.progress-bar.is-success { background: var(--color-success); }
.progress-bar.is-warning { background: var(--color-warning); }
.progress-bar.is-danger { background: var(--color-danger); }

.avatar {
    width: var(--space-5);
    height: var(--space-5);
    border-radius: var(--radius-pill);
    background: var(--color-primary-soft);
    color: var(--color-primary-strong);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-bold);
    flex: none;
}

.lang-switch { display: inline-flex; gap: var(--space-1); background: var(--color-neutral-soft); padding: var(--space-1); border-radius: var(--radius-pill); }

.lang-switch a {
    padding: 0 var(--space-2);
    height: var(--space-4);
    display: inline-flex;
    align-items: center;
    border-radius: var(--radius-pill);
    font-size: var(--font-size-xs);
    color: var(--color-neutral);   /* ต้องอ่านออกบนพื้น --color-neutral-soft ของตัวสลับภาษา */
}

.lang-switch a:hover { text-decoration: none; color: var(--color-text); }

.lang-switch a.is-active { background: var(--color-surface); color: var(--color-text); font-weight: var(--font-weight-medium); box-shadow: var(--shadow-sm); }

.org-switch { display: flex; align-items: center; gap: var(--space-2); }

.menu-dropdown { position: relative; }

.menu-dropdown-panel {
    position: absolute;
    right: 0;
    top: calc(100% + var(--space-1));
    min-width: 220px;
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    box-shadow: var(--shadow-lg);
    padding: var(--space-1);
    z-index: 30;
}

.menu-dropdown-panel[hidden] { display: none; }

.menu-dropdown-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    color: var(--color-text);
    width: 100%;
    background: none;
    border: 0;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
}

.menu-dropdown-item:hover { background: var(--color-surface-muted); text-decoration: none; }

.error-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
    text-align: center;
}

.error-code { font-size: var(--font-size-2xl); color: var(--color-primary); font-weight: var(--font-weight-bold); }


/* ------------------------------------------------- แถบสถานะผู้ให้บริการ

   ‼️ ใช้ token ล้วน ไม่มีค่าสีดิบ · โหมดมืดจึงตามมาเองโดยไม่ต้องเขียนชุดที่สอง
      ค่าดิบที่นี่จะกลายเป็นแถบสีอ่อนบนพื้นเข้มในโหมดมืด ซึ่งอ่านไม่ออก */

.provider-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
}

.provider-strip-name {
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
}

/* ‼️ จุดสถานะเป็นของประกอบ ห้ามใช้แทนข้อความ
      สีอย่างเดียวสื่อกับคนตาบอดสีและโปรแกรมอ่านหน้าจอไม่ได้
      ทุกที่ที่ใช้จุดนี้ต้องมีข้อความกำกับเสมอ */
.status-dot {
    width: var(--space-1);
    height: var(--space-1);
    border-radius: var(--radius-pill);
    background: currentColor;
    opacity: .45;
    flex: none;
}

.status-dot.is-on { opacity: 1; }

.reference-code {
    /* ‼️ ต้องกำหนดสีตัวอักษรเอง ห้ามรับทอดจากพ่อแม่
          กล่องนี้มีพื้นเป็น --color-neutral-soft ซึ่งเข้มกว่าพื้นการ์ด
          ถ้าอยู่ใน .text-muted จะกลายเป็นเทาบนเทา = 4.32:1 ไม่ผ่าน WCAG AA (ต้อง 4.5)
          พบด้วย check-screens.php ที่หน้าเครื่องมือระบบ 2026-08-27 · ตอนนี้ได้ 13.9:1
          ‼️ เป็นรหัสอ้างอิงที่คนต้องอ่านแล้วเทียบทีละตัวอักษร จางไม่ได้ตั้งแต่ต้น */
    color: var(--color-text);
    display: inline-block;
    font-family: var(--font-family-mono);
    background: var(--color-neutral-soft);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
}

/* ‼️ ปุ่มสองใบที่อยู่คู่กันในช่องตาราง — ต้องอ่านครบทั้งคำเหมือนปุ่มท้ายการ์ด
      ใช้กติกาเดียวกับ .site-card-footer โดยตั้งใจ: กว้างพอ = บรรทัดเดียว
      แคบแล้วขึ้นบรรทัดใหม่ ไม่ใช่หดจนข้อความถูกตัด */
/* ‼️ แถวของ "สิ่งที่ต้องดำเนินการ" — ข้อความซ้าย ปุ่มขวา
      เจอจากภาพหน้าจอจริง 2026-08-27: ตอนแรกลืมเขียน class นี้
      แถวจึงกองซ้อนกันชิดซ้ายทั้งหมดจนอ่านไม่ออกว่าปุ่มเป็นของข้อไหน
      ‼️ ชุดตรวจอัตโนมัติจับไม่ได้ เพราะไม่ล้นขอบและ contrast ผ่าน
         เป็นตัวอย่างว่าทำไมต้องเปิดภาพดูด้วยตาจริง */
.action-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) 0;
    border-bottom: var(--border-width) solid var(--color-border);
}

/* แถวสุดท้ายไม่ต้องมีเส้นคั่น ไม่งั้นจะเหมือนมีของต่ออยู่ข้างล่าง */
.action-row:last-child { border-bottom: 0; padding-bottom: 0; }

.action-row-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
    flex: 1 1 20rem;
}
.action-pair {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.action-pair > * { flex: 0 1 auto; min-width: max-content; }

/* ---------------------------------------------- แถบเมนูย่อยของหน้าเครื่องมือระบบ
   ‼️ เป็นลิงก์จริง ไม่ใช่แท็บที่ซ่อนการ์ดด้วย JavaScript
      จึงต้องมีสถานะ :focus-visible ที่มองเห็นได้ เพราะเดินด้วยคีย์บอร์ดได้จริง */
.subnav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    border-bottom: var(--border-width) solid var(--color-border);
    margin-bottom: var(--space-4);
}

.subnav-item {
    padding: var(--space-2) var(--space-3);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    margin-bottom: calc(var(--border-width) * -1);
    white-space: nowrap;
}

.subnav-item:hover { color: var(--color-text); }

/* ‼️ ไม่พึ่งสีอย่างเดียว — มีเส้นใต้หนาเป็นสัญญาณที่สอง
      คนที่แยกสีไม่ได้ต้องรู้ได้ว่าอยู่หน้าไหน */
.subnav-item.is-active {
    /* ‼️ ข้อความต้องใช้ --color-primary-strong ไม่ใช่ --color-primary
          สีแบรนด์บนพื้นขาวได้ contrast ไม่ถึงเกณฑ์ ตามที่ token เตือนไว้เอง
          ส่วนเส้นใต้ใช้สีแบรนด์ได้ เพราะเป็นงานตกแต่ง ไม่ใช่ข้อความที่ต้องอ่าน */
    color: var(--color-primary-strong);
    border-bottom-color: var(--color-primary);
}

.sidebar-toggle { display: none; }

/* ---------------------------------------------------------- responsive */

@media (max-width: 1200px) {
    .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .editor { grid-template-columns: 280px minmax(0, 1fr); }

    /* ‼️ ศูนย์ช่วยเหลือลดจากสามคอลัมน์เหลือสองก่อน — ตัดสารบัญออกจากแถวก่อนเสมอ
          เพราะเป็นทางลัด ส่วนเมนูซ้ายคือสิ่งที่บอกว่า "มีบทความอะไรบ้าง" ซึ่งสำคัญกว่า
          สารบัญไม่ได้หายไป แค่ไหลลงไปอยู่ท้ายเนื้อหา */
    .help-article-page { grid-template-columns: 232px minmax(0, 1fr); gap: var(--space-4); }
    .help-article-toc { grid-column: 1 / -1; }
    .help-toc-inner { position: static; }

    .help-quick { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .help-categories { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 992px) {
    .app { grid-template-columns: minmax(0, 1fr); }

    .sidebar {
        position: fixed;
        left: 0;
        top: 0;
        width: var(--sidebar-width);
        z-index: 95;
        transform: translateX(-100%);
        transition: transform var(--transition-base);
    }

    .sidebar.is-open { transform: translateX(0); }

    .sidebar-toggle { display: inline-flex; }

    .grid-2,
    .grid-3,
    .grid-sidebar,
    .form-grid-2 { grid-template-columns: minmax(0, 1fr); }

    .editor { grid-template-columns: minmax(0, 1fr); }

    .editor-panel { position: static; max-height: none; }

    .manual-layout { grid-template-columns: minmax(0, 1fr); }

    /* ‼️ ศูนย์ช่วยเหลือบนจอแคบ: ไหลลงมาเป็นคอลัมน์เดียวตามลำดับที่ต้องอ่าน
          แผงความคืบหน้าไปอยู่ท้ายสุด เพราะเนื้อหาคู่มือคือสิ่งที่คนเปิดหน้านี้มาหา */
    .help-center { grid-template-columns: minmax(0, 1fr); }
    .help-side { position: static; }

    .help-article-page { grid-template-columns: minmax(0, 1fr); }
    .help-article-nav { position: static; }
    .help-toc-inner { position: static; }

    /* ‼️ จอแคบซ้อนเป็นคอลัมน์เดียว และแผงแบรนด์ย่อเหลือเฉพาะแบรนด์กับพาดหัว
       ภาพประกอบกับรายการคุณสมบัติถูกซ่อน เพื่อให้ผู้ใช้ไม่ต้องเลื่อนผ่านงานโฆษณายาวๆ
       ก่อนจะถึงฟอร์ม — ซึ่งคือสิ่งเดียวที่เขาเปิดหน้านี้มาทำ */
    /* ‼️ แถวบนสูงตามเนื้อหา แถวล่างกินที่เหลือ — ถ้าไม่กำหนด สองแถวจะหารความสูงจอกันคนละครึ่ง
       แล้วแผงแบรนด์จะเหลือพื้นกรมท่าว่างเปล่ายาวเป็นคืบก่อนถึงฟอร์ม */
    .auth-shell { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr; }

    .auth-aside {
        padding: var(--space-5) var(--space-4);
        gap: var(--space-4);
        justify-content: flex-start;
    }

    .auth-headline { font-size: var(--font-size-2xl); }

    .auth-artwork { display: none; }

    /* ‼️ จอแคบไม่ต้องจัดฟอร์มไว้กลางแนวตั้ง — ผู้ใช้เลื่อนหน้าจออยู่แล้ว
       การดันการ์ดลงไปกลางจอทำให้เปิดมาแล้วเห็นแต่พื้นที่ว่างก่อนถึงช่องกรอก */
    .auth-main { padding: var(--space-4) var(--space-3) var(--space-7); }

    .auth-card { margin: 0; }
}

@media (max-width: 640px) {
    .auth-features,
    .auth-subtitle { display: none; }

    .auth-aside { padding: var(--space-4) var(--space-3); }

    .auth-card { padding: var(--space-5) var(--space-4); box-shadow: var(--shadow-sm); }

    /* ปุ่มแจ้งปัญหาลอยอยู่มุมล่างขวา — เว้นที่ท้ายฟอร์มไม่ให้ทับปุ่มหลัก */
    .auth-main { padding-bottom: var(--space-8); }
}

@media (max-width: 640px) {
    .content { padding: var(--space-3) var(--space-3) var(--space-7); }

    /* จอแคบแสดงเฉพาะอักษรย่อของผู้ใช้ — กันแถบบนล้นจนแถบภาษาหลุดขอบจอ */
    .topbar-user-name { display: none; }

    .page-header { flex-direction: column; align-items: stretch; }

    .page-header-actions .btn { flex: 1 1 auto; }

    .grid-4 { grid-template-columns: minmax(0, 1fr); }

    /* จอมือถือใช้ 2 คอลัมน์ — ถ้าเรียงเดี่ยวต้องเลื่อนผ่านการ์ดสรุป 4 ใบก่อนถึงตาราง */
    .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* ‼️ ศูนย์ช่วยเหลือบนมือถือ: ทุกอย่างเรียงเดี่ยว และปุ่มค้นหาลงมาอยู่ใต้ช่องกรอก
          ถ้าคงไว้แถวเดียวกัน ช่องกรอกจะเหลือกว้างไม่ถึงครึ่งจนอ่านคำที่พิมพ์ไม่ออก */
    .help-quick,
    .help-categories { grid-template-columns: minmax(0, 1fr); }

    .help-search { flex-wrap: wrap; }
    .help-search-input { flex: 1 1 100%; order: 1; padding: 0 var(--space-2); }
    .help-search-icon { order: 0; }
    .help-search-submit { order: 2; width: 100%; }

    .help-hero-title { font-size: var(--font-size-2xl); }
    .help-article-title { font-size: var(--font-size-xl); }

    /* ‼️ ก่อนหน้า/ถัดไป เรียงลงมา — สองใบข้างกันบนจอ 360px เหลือใบละ ~160px
          ซึ่งไม่พอแสดงชื่อบทความเลยแม้แต่คำเดียว */
    .help-article-nextprev { grid-template-columns: minmax(0, 1fr); }
    .help-nextprev-card.is-next { justify-content: flex-start; text-align: left; flex-direction: row-reverse; }

    .help-feedback { flex-direction: column; gap: var(--space-2); align-items: stretch; text-align: center; }
    .help-feedback-actions { justify-content: center; }

    .list-toolbar { flex-direction: column; align-items: stretch; }

    .support-fab { right: var(--space-3); bottom: var(--space-3); }

    /* จอมือถือ: หัวข้อกับค่าเรียงบนล่าง ไม่ใช่ซ้ายขวา — ค่ายาวๆ จะได้ไม่ถูกบีบจนขึ้นบรรทัดทีละคำ */
    .definition-list { grid-template-columns: minmax(0, 1fr); gap: var(--space-1); }

    .definition-list dt { margin-top: var(--space-2); }

    .modal { max-height: 96vh; }
}

@media print {
    .sidebar,
    .topbar,
    .support-fab,
    .page-header-actions { display: none; }

    body { background: var(--color-surface); }
}

/* ---------------------------------------------------------------- แถบสวมสิทธิ์
   ‼️ ทีมงานแพลตฟอร์มกำลังดูระบบในฐานะลูกค้าตัวอย่าง — ต้องเห็นชัดทุกหน้า
      ไม่งั้นจะลืมตัวแล้วเข้าใจว่ากำลังดูระบบของตัวเอง
   ‼️ พื้น --color-warning กับตัวอักษรขาวได้ contrast 5.33:1 ผ่าน WCAG AA
      ปุ่มกลับใช้พื้นขาวกับตัวอักษร --color-warning ได้ค่าเดียวกัน */
.impersonation-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    background: var(--solid-warning-bg);
    color: var(--solid-warning-fg);
    font-size: var(--font-size-sm);
}

.impersonation-bar-text {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
}

.impersonation-bar-hint { opacity: 0.9; }

.impersonation-bar-button {
    background: var(--color-text-inverse);
    color: var(--color-warning);
    border-color: var(--color-text-inverse);
}

.impersonation-bar-button:hover {
    background: var(--color-warning-soft);
    color: var(--color-warning);
}

/* ‼️ บนจอแคบให้ข้อความย่อลงแทนที่จะดันปุ่มตกขอบ */
@media (max-width: 640px) {
    .impersonation-bar-hint { display: none; }
}

/* ============================================================================
   หน้าแนะนำผลิตภัณฑ์ (สาธารณะ) — คลาสขึ้นต้นด้วย mk- ทั้งหมด
   ‼️ ใช้เฉพาะหน้าแรกและคลังแม่แบบ ไม่ปนกับระบบจัดการ จึงแยกบล็อกไว้ท้ายไฟล์
   ‼️ พื้นสีเข้มทุกก้อนต้องตั้ง background-color เป็นสีทึบด้วยเสมอ ไม่ใช่ gradient อย่างเดียว
      ถ้าตั้งแต่ gradient ตัวตรวจ contrast จะอ่านพื้นไม่เจอ แล้วไปเทียบกับพื้นขาวของ body แทน
      ซึ่งทำให้ตัวอักษรสีขาวถูกรายงานว่าไม่ผ่านทั้งที่จริงผ่าน
   ============================================================================ */

.mk-body { background: var(--color-surface); }

/* ‼️ ตราสินค้าบนพื้นขาว — ห้ามใช้ .sidebar-brand ตรงๆ เพราะตัวอักษรของมันเป็นสีขาว
   (ออกแบบไว้สำหรับแถบข้างพื้นเข้ม) วางบนพื้นขาวแล้วได้ contrast 1.00 คือมองไม่เห็นเลย */
.mk-brand {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-text);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-lg);
    letter-spacing: .02em;
    text-decoration: none;
}

.mk-brand:hover { color: var(--color-text); text-decoration: none; }

/* ‼️ ตัวอักษร OW ในกล่องสีส้มต้องเป็นสีขาว (5.19:1) — ถ้าปล่อยให้สืบทอดสีเข้มจาก .mk-brand
   จะได้ 3.01:1 ซึ่งไม่ผ่าน AA และเป็นตราสินค้าที่อยู่บนทุกหน้าสาธารณะ */
/* ‼️ ต้องจับคู่กับ --btn-primary-bg เสมอ ไม่ใช่ขาวตายตัว — ไม่งั้นพอพื้นเปลี่ยนเฉด ตัวอักษรจะไม่ตาม */
.mk-brand .sidebar-brand-mark { color: var(--btn-primary-fg); }

/* -------------------------------------------------------------- แถบบนสุด */

.mk-topbar {
    position: sticky;
    top: 0;
    z-index: 30;
    background: var(--color-surface);
    border-bottom: var(--border-width) solid var(--color-border);
}

.mk-topbar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
    padding: var(--space-3) var(--space-4);
}

.mk-nav {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex: 1 1 auto;
    justify-content: center;
    min-width: 0;
}

.mk-nav-link {
    position: relative;
    padding: var(--space-2) 0;
    color: var(--color-text);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
    white-space: nowrap;
}

.mk-nav-link:hover { color: var(--color-primary-strong); }

.mk-nav-link.is-active { color: var(--color-primary-strong); }

.mk-nav-link.is-active::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--space-1);
    border-radius: var(--radius-pill);
    background: var(--color-primary);
}

.mk-topbar-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.mk-lang {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-pill);
}

.mk-lang-icon {
    display: inline-flex;
    color: var(--color-text-muted-on-soft);
}

.mk-lang a {
    padding: 0 var(--space-1);
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}

.mk-lang a.is-active { color: var(--color-text); }

/* ------------------------------------------------------------- ส่วนหัวใหญ่ */

.mk-hero {
    position: relative;
    overflow: hidden;
    /* ‼️ ต้องมีสีทึบคู่กับ gradient เสมอ — ดูเหตุผลที่หัวบล็อก */
    background-color: var(--color-hero);
    background-image: linear-gradient(140deg, var(--color-hero) 0%, var(--color-hero-deep) 55%, var(--color-hero) 100%);
    color: var(--color-text-inverse);
    padding: var(--space-8) var(--space-4) var(--space-7);
}

.mk-hero-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    align-items: center;
    gap: var(--space-6);
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
}

.mk-hero-copy { min-width: 0; }

.mk-hero-title {
    margin: 0 0 var(--space-4);
    font-size: var(--font-size-3xl);
    line-height: 1.18;
    letter-spacing: -0.01em;
}

.mk-hero-title-line { display: block; }

/* ‼️ วลีที่เน้นต้องไม่ถูกตัดกลาง ไม่งั้นหัวเรื่องจะกลายเป็นสามบรรทัดและผิดจากแบบ */
.mk-accent {
    color: var(--color-primary-on-dark);
    white-space: nowrap;
}

.mk-hero-text {
    margin: 0 0 var(--space-5);
    max-width: 34em;
    color: var(--color-text-on-dark-muted);
    font-size: var(--font-size-lg);
}

.mk-hero-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}

.mk-btn-ghost {
    background: transparent;
    border-color: var(--color-text-inverse);
    color: var(--color-text-inverse);
}

.mk-btn-ghost:hover {
    background: var(--color-text-inverse);
    color: var(--color-hero);
}

.mk-hero-points {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    color: var(--color-text-on-dark-muted);
    font-size: var(--font-size-sm);
}

.mk-hero-check {
    display: inline-flex;
    color: var(--color-success-on-dark);
}

/* ------------------------------------------------- กรอบจอคอมพิวเตอร์และมือถือ */

.mk-hero-visual {
    position: relative;
    min-width: 0;
    padding-bottom: var(--space-6);
}

.mk-device {
    overflow: hidden;
    border: var(--border-width) solid var(--color-device-edge);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-device);
}

.mk-device-bar {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-3);
    background: var(--color-surface-muted);
    border-bottom: var(--border-width) solid var(--color-border);
}

.mk-device-dot {
    width: var(--space-2);
    height: var(--space-2);
    border-radius: var(--radius-pill);
    background: var(--color-border-strong);
}

.mk-device-shot,
.mk-phone-shot {
    display: block;
    width: 100%;
    height: auto;
}

.mk-phone {
    position: absolute;
    right: var(--space-5);
    bottom: 0;
    width: 31%;
    max-width: 168px;
    overflow: hidden;
    padding: var(--space-2) var(--space-1);
    border-radius: var(--radius-lg);
    background: var(--color-secondary);
    box-shadow: var(--shadow-device);
}

.mk-phone-notch {
    display: block;
    width: 40%;
    height: var(--space-1);
    margin: 0 auto var(--space-1);
    border-radius: var(--radius-pill);
    background: var(--color-border-strong);
}

.mk-phone-shot {
    border-radius: var(--radius-sm);
    /* ‼️ ครอปให้เป็นทรงมือถือ ไม่ใช่ย่อภาพจอคอมทั้งใบจนอ่านไม่ออก */
    aspect-ratio: 9 / 16;
    object-fit: cover;
    object-position: top center;
}

/* ------------------------------------------------------ แถวภาพย่อของแม่แบบ */

.mk-thumbs {
    display: flex;
    gap: var(--space-3);
    width: 100%;
    max-width: var(--content-max);
    margin: var(--space-6) auto 0;
    padding: 0 0 var(--space-2);
    list-style: none;
    overflow-x: auto;
    scroll-snap-type: x proximity;
}

.mk-thumb {
    flex: 0 0 auto;
    width: 172px;
    scroll-snap-align: start;
}

.mk-thumb a {
    display: block;
    overflow: hidden;
    border-radius: var(--radius-base);
    background: var(--color-surface);
    box-shadow: var(--shadow-device);
    text-decoration: none;
}

.mk-thumb img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    object-position: top center;
}

.mk-thumb-label {
    display: block;
    padding: var(--space-2);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    text-align: center;
    /* ‼️ ชื่อแม่แบบบางตัวยาว ต้องตัดด้วย … ไม่ใช่ดันการ์ดให้สูงไม่เท่ากัน */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* -------------------------------------------- แถบจุดเด่น (คร่อมขอบล่างส่วนหัว) */

.mk-strip-wrap {
    width: 100%;
    max-width: var(--content-max);
    margin: calc(var(--space-6) * -1) auto 0;
    padding: 0 var(--space-4);
    position: relative;
    z-index: 2;
}

.mk-strip {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: var(--space-4);
    margin: 0;
    padding: var(--space-5);
    list-style: none;
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
}

.mk-strip-item {
    display: grid;
    gap: var(--space-1);
    min-width: 0;
}

.mk-strip-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--size-strip-icon);
    height: var(--size-strip-icon);
    margin-bottom: var(--space-1);
    border-radius: var(--radius-base);
    background: var(--color-secondary-soft);
    color: var(--color-secondary-text);
}

.mk-strip-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-bold);
}

.mk-strip-text {
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-xs);
    line-height: var(--line-height-base);
}

/* --------------------------------------------------------- ส่วนเนื้อหาทั่วไป */

.mk-section { padding: var(--space-8) var(--space-4); }

.mk-section-muted { background: var(--color-bg); }

.mk-section-inner {
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
}

.mk-section-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
}

.mk-section-head-center {
    text-align: center;
    margin-bottom: var(--space-5);
}

.mk-section-title {
    margin: 0;
    font-size: var(--font-size-3xl);
}

.mk-section-hint {
    margin: 0;
    color: var(--color-text-muted-on-soft);
}

/* ------------------------------------------------------- การ์ดแม่แบบและราง */

.mk-rail-wrap { position: relative; }

.mk-rail {
    display: flex;
    gap: var(--space-3);
    margin: 0;
    padding: 0 0 var(--space-3);
    list-style: none;
    overflow-x: auto;
    scroll-behavior: smooth;
    scroll-snap-type: x proximity;
}

.mk-tpl-card {
    position: relative;
    flex: 0 0 auto;
    width: var(--size-tpl-card);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
    scroll-snap-align: start;
}

.mk-tpl-badge {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    padding: var(--space-1) var(--space-3);
    border-bottom-right-radius: var(--radius-base);
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-bold);
}

.mk-tpl-media { display: block; }

.mk-tpl-media img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    object-position: top center;
}

.mk-tpl-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    flex: 1 1 auto;
    padding: var(--space-3);
}

.mk-tpl-category {
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-xs);
}

.mk-tpl-name {
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
}

.mk-tpl-hint {
    margin: 0;
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-sm);
}

.mk-tpl-link {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    gap: var(--space-1);
    /* ‼️ ดันลงล่างสุดเสมอ ลิงก์ของทุกใบในแถวจึงอยู่ระดับเดียวกันแม้ชื่อจะยาวไม่เท่ากัน */
    margin-top: auto;
    padding-top: var(--space-2);
    color: var(--color-primary-strong);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    text-decoration: none;
}

.mk-tpl-link:hover { text-decoration: underline; }

.mk-rail-arrow {
    position: absolute;
    top: var(--size-rail-arrow-top);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--size-rail-arrow);
    height: var(--size-rail-arrow);
    padding: 0;
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-text);
    box-shadow: var(--shadow-base);
    cursor: pointer;
}

.mk-rail-arrow:hover { border-color: var(--color-border-strong); }

.mk-rail-prev { left: calc(var(--size-rail-arrow) / -2); }
.mk-rail-next { right: calc(var(--size-rail-arrow) / -2); }

/* คลังแม่แบบเต็มหน้า — การ์ดชุดเดียวกับหน้าแรก แต่จัดเป็นตาราง ไม่ใช่ราง */
.mk-tpl-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
}

.mk-tpl-grid .mk-tpl-card { width: auto; }

/* ----------------------------------------------- แถบความน่าเชื่อถือ (พื้นเข้ม) */

.mk-trust {
    background-color: var(--color-hero);
    background-image: linear-gradient(120deg, var(--color-hero-deep) 0%, var(--color-hero) 70%);
    color: var(--color-text-inverse);
    padding: var(--space-8) var(--space-4);
}

.mk-trust-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    gap: var(--space-6);
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
}

.mk-trust-title {
    margin: 0 0 var(--space-2);
    font-size: var(--font-size-3xl);
}

.mk-trust-text {
    margin: 0 0 var(--space-5);
    color: var(--color-text-on-dark-muted);
}

.mk-trust-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
}

.mk-stat {
    display: grid;
    gap: var(--space-1);
    justify-items: start;
    min-width: 0;
}

.mk-stat-icon {
    display: inline-flex;
    color: var(--color-primary-on-dark);
}

.mk-stat-value {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
}

.mk-stat-label {
    color: var(--color-text-on-dark-muted);
    font-size: var(--font-size-xs);
    line-height: var(--line-height-base);
}

/* ภาพสามใบ: ใบสูงด้านซ้าย และสองใบซ้อนกันด้านขวา
   ‼️ ต้องมี aspect-ratio ที่ตัวตาราง — ไม่งั้นความสูงของแถวจะมาจากเนื้อหา
      ส่วนเนื้อหา (img) ขอความสูง 100% ของแถว กลายเป็นวงกลมที่แก้ไม่ตก แล้วยุบเหลือศูนย์
      อาการคือภาพทั้งสามใบหายไปเฉยๆ โดยที่ HTML ถูกต้องทุกอย่าง */
.mk-collage {
    display: grid;
    grid-template-columns: 1.25fr 1fr;
    grid-template-rows: repeat(2, minmax(0, 1fr));
    aspect-ratio: 5 / 4;
    gap: var(--space-3);
    min-width: 0;
}

.mk-collage img {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: var(--radius-lg);
    object-fit: cover;
}

.mk-collage-tall { grid-row: span 2; }

/* ------------------------------------------------------------------ ราคา */

/* ‼️ stretch ไม่ใช่ start — การ์ด Custom มีรายการยาวกว่าการ์ดที่มีราคา
   ถ้าปล่อยให้สูงตามเนื้อหา ปุ่มของสามใบจะอยู่คนละระดับกันจนแถวดูไม่เป็นชุดเดียว */
.mk-price-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--space-4);
    align-items: stretch;
    margin: 0;
    padding: 0;
    list-style: none;
}

.mk-price-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-5) var(--space-4) var(--space-4);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}

/* ปุ่มของทุกใบอยู่ระดับเดียวกันเสมอ ไม่ว่ารายการข้างบนจะยาวไม่เท่ากัน */
.mk-price-card > .btn {
    margin-top: auto;
}

/* ‼️ ตัวที่เน้นใช้สีรองของแบรนด์ (กรมท่า) ไม่ใช่สีใหม่นอกชุด — ทิศทางธีมล็อกไว้ที่ CLAUDE.md ข้อ 1 */
.mk-price-card.is-featured {
    border-color: var(--color-secondary);
    box-shadow: var(--shadow-lg);
}

.mk-price-badge {
    position: absolute;
    top: calc(var(--space-3) * -1);
    left: 50%;
    transform: translateX(-50%);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-pill);
    background: var(--color-secondary);
    color: var(--color-text-inverse);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-bold);
    white-space: nowrap;
}

.mk-price-name {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-bold);
}

.mk-price-value {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    color: var(--color-text);
}

.mk-price-list {
    display: grid;
    gap: var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: var(--font-size-sm);
}

.mk-price-list li {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
}

.mk-price-check {
    display: inline-flex;
    flex: 0 0 auto;
    color: var(--color-success);
}

/* ‼️ การ์ด Custom ไม่มีราคา จึงต้องมีบรรทัดบอกว่าคืออะไรแทนที่ตัวเลข
   ไม่งั้นคนอ่านจะเห็นแค่คำว่า "ติดต่อเรา" ลอยอยู่โดยไม่รู้ว่าได้อะไร */
.mk-price-tagline {
    margin: 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.mk-price-card-custom {
    border-style: dashed;
}

/* --------------------------------------------- การ์ดที่มีผลกับระบบทั้งระบบ */

/* ‼️ ใช้กับกล่องที่ "กดแล้วเปลี่ยนสถานะของทั้งระบบ" เท่านั้น เช่น รัน migration หรือลบชุดข้อมูล
   ต้องต่างจากการ์ดธรรมดาให้เห็นทันทีจากหางตา ไม่ใช่ต้องอ่านหัวข้อก่อนถึงจะรู้ว่าอันตราย
   ใช้สีเตือนของชุดสี ไม่ใช่สีแดงใหม่นอกระบบ */
.card-danger-zone {
    border-color: var(--color-warning);
    background: var(--color-warning-soft);
}

.card-danger-zone .card-header {
    border-bottom-color: var(--color-warning);
}

/* ------------------------------------------------------------- ติดต่อเรา */

.mk-contact {
    display: grid;
    justify-items: center;
    gap: var(--space-4);
    text-align: center;
}

/* ------------------------------------------------------- แถบคำมั่นปิดท้าย */

.mk-promise {
    background: var(--color-primary-soft);
    border-top: var(--border-width) solid var(--color-primary-border);
    padding: var(--space-5) var(--space-4);
}

.mk-promise-inner {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-4);
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
    padding: 0;
    list-style: none;
}

.mk-promise-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
}

.mk-promise-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: var(--size-strip-icon);
    height: var(--size-strip-icon);
    border-radius: var(--radius-base);
    background: var(--color-surface);
    color: var(--color-primary-strong);
}

.mk-promise-title {
    display: block;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-bold);
}

.mk-promise-text {
    display: block;
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-xs);
}

/* ------------------------------------------------------------------ ท้ายหน้า */

.mk-footer {
    background: var(--color-surface);
    border-top: var(--border-width) solid var(--color-border);
    padding: var(--space-6) var(--space-4) var(--space-4);
}

.mk-footer-inner {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
}

.mk-footer-inner p { max-width: 46em; color: var(--color-text-muted-on-soft); }

.mk-footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
}

.mk-footer-links a,
.mk-footer-bottom a {
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-sm);
    text-decoration: none;
}

.mk-footer-links a:hover,
.mk-footer-bottom a:hover { color: var(--color-primary-strong); }

.mk-footer-bottom {
    align-items: center;
    margin-top: var(--space-4);
    padding-top: var(--space-3);
    border-top: var(--border-width) solid var(--color-border);
    color: var(--color-text-muted-on-soft);
}

/* ‼️ จอกว้าง: หกช่องพอดีความกว้างเนื้อหา ไม่ใช่ความกว้างคงที่แล้วล้นหรือเหลือช่องว่าง */
@media (min-width: 1100px) {
    .mk-thumb,
    .mk-rail .mk-tpl-card { width: calc((100% - var(--space-3) * 5) / 6); }
}
/* -------------------------------------------------------------- จอแคบลง */

@media (max-width: 1100px) {
    .mk-nav { display: none; }
    .mk-strip { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .mk-trust-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 920px) {
    .mk-hero { padding-top: var(--space-6); }
    .mk-hero-inner { grid-template-columns: minmax(0, 1fr); }
    .mk-hero-title { font-size: var(--font-size-3xl); }
    .mk-trust-inner { grid-template-columns: minmax(0, 1fr); }
    .mk-rail-arrow { display: none; }
    .mk-promise-inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .mk-footer-inner { flex-direction: column; }
}

@media (max-width: 640px) {
    /* ‼️ แถบบนใส่ในบรรทัดเดียวไม่พอที่ 390px — ตราสินค้าแถวหนึ่ง ปุ่มอีกแถวหนึ่ง
       ห้ามแก้ด้วยการซ่อนปุ่มเข้าสู่ระบบ เพราะคนที่เป็นลูกค้าอยู่แล้วจะเข้าระบบจากมือถือไม่ได้ */
    .mk-topbar-inner {
        flex-wrap: wrap;
        justify-content: center;
        gap: var(--space-2);
        padding: var(--space-2) var(--space-3);
    }
    .mk-topbar-actions { flex: 1 1 100%; justify-content: center; }

    /* ‼️ จอแคบต้องยอมให้วลีที่เน้นขึ้นบรรทัดใหม่ ไม่งั้นหัวเรื่องจะดันหน้าให้เลื่อนแนวนอน */
    .mk-accent { white-space: normal; }

    .mk-hero { padding: var(--space-5) var(--space-3) var(--space-6); }
    .mk-hero-title { font-size: var(--font-size-2xl); }
    .mk-hero-text { font-size: var(--font-size-base); }
    .mk-hero-actions .btn { width: 100%; }
    .mk-section { padding: var(--space-6) var(--space-3); }
    .mk-section-title { font-size: var(--font-size-2xl); }
    .mk-section-head { flex-direction: column; align-items: stretch; }
    .mk-strip-wrap { padding: 0 var(--space-3); }
    .mk-strip { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
    .mk-trust { padding: var(--space-6) var(--space-3); }
    .mk-trust-title { font-size: var(--font-size-2xl); }
    .mk-trust-stats { gap: var(--space-3); }
    .mk-promise-inner { grid-template-columns: minmax(0, 1fr); }
    .mk-collage { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; aspect-ratio: auto; }
    .mk-collage-tall { grid-row: auto; }
    .mk-collage img { aspect-ratio: 16 / 9; height: auto; }
}

/* ‼️ การ์ดในคลังแม่แบบต้องสูงเท่ากันทุกใบ ไม่งั้นแถวจะเหลื่อมและดูไม่เป็นระเบียบ
   คำอธิบายยาวไม่เท่ากัน จึงตัดที่สองบรรทัดแล้วดันปุ่มลงล่างสุดเสมอ */
.template-grid .template-card {
    display: flex;
    flex-direction: column;
}

.template-grid .template-card .card-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}

.template-card-hint {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 42px;
}

.template-card-actions { margin-top: auto; }

/* ‼️ แถบเข้าดูข้อมูลลูกค้าแบบอ่านอย่างเดียว — ใช้สีข้อมูล ไม่ใช่สีเตือน
   เพราะเป็นสถานะที่ปลอดภัยกว่าการสวมสิทธิ์ แต่ยังต้องเห็นชัดตลอดเวลา
   #FFFFFF บน --color-info (#1F5F9E) = 6.29:1 ผ่าน WCAG AA */
.support-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    background: var(--solid-info-bg);
    color: var(--solid-info-fg);
    font-size: var(--font-size-sm);
}

.support-bar-button {
    background: var(--color-text-inverse);
    color: var(--color-info);
    border-color: var(--color-text-inverse);
}

.support-bar-button:hover {
    background: var(--color-info-soft);
    color: var(--color-info);
}

/* ============================================================================
   DESIGN SYSTEM v2 — ส่วนประกอบกลางที่เพิ่มตาม Visual Standard ที่อนุมัติ 2026-08-23
   ‼️ ทุกอย่างในบล็อกนี้เป็น "ส่วนประกอบที่ใช้ซ้ำ" เท่านั้น ห้ามเพิ่มกฎเฉพาะหน้าใดหน้าหนึ่ง
      ถ้าหน้าไหนต้องการหน้าตาต่างออกไป ให้เพิ่ม modifier ที่นี่แล้วให้ทุกหน้าใช้ร่วมกันได้
   ============================================================================ */

/* -------------------------------------------------- แถบสลับค่าแบบปุ่มติดกัน
   ใช้กับ: สลับภาษา · เลือกช่วงเวลา · สลับชุดข้อมูลของกราฟ
   ‼️ ทุกตัวเลือกต้องเป็นลิงก์จริง (เปลี่ยน query string) ไม่ใช่ JS ที่ซ่อนข้อมูลไว้ */
.segmented {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    background: var(--color-neutral-soft);
    padding: var(--space-1);
    border-radius: var(--radius-pill);
    max-width: 100%;
    overflow-x: auto;
}

.segmented > * {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-1);
    height: var(--space-5);
    padding: 0 var(--space-3);
    border: 0;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--color-text-muted-on-soft);
    font-family: inherit;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
    cursor: pointer;
}

.segmented > *:hover { color: var(--color-text); text-decoration: none; }

.segmented > .is-active {
    background: var(--color-surface);
    color: var(--color-primary-strong);
    box-shadow: var(--shadow-sm);
}

.segmented-sm > * { height: var(--space-4); padding: 0 var(--space-2); font-size: var(--font-size-xs); }

/* -------------------------------------------------------- ตัวเลือกในกล่อง
   select ที่ต้องดูเป็น "ตัวควบคุม" ไม่ใช่ช่องกรอก — ใช้บนแถบบนและหัวการ์ด */
.select-inline {
    height: var(--height-control-sm);
    padding: 0 var(--space-3);
    border-radius: var(--radius-pill);
    border: var(--border-width) solid var(--color-border-strong);
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: var(--font-size-sm);
    min-height: 0;
    max-width: 220px;
}

/* ------------------------------------------------------- ปุ่มผู้ใช้บนแถบบน */
.topbar-user { gap: var(--space-2); padding: 0 var(--space-2); height: var(--height-button); }
.topbar-user .icon-chevron { width: var(--font-size-sm); height: var(--font-size-sm); opacity: .6; }

.topbar-divider {
    width: var(--border-width);
    height: var(--space-4);
    background: var(--color-border);
    flex: none;
}

/* ------------------------------------------------------------ หัวการ์ดย่อย */
.card-header-tight { padding: var(--space-3) var(--space-4); border-bottom: 0; }

/* ----------------------------------------------------- แถบตัวเลขในหัวกราฟ
   ‼️ ทุกตัวเลขต้องมาจากชุดข้อมูลเดียวกับกราฟด้านล่าง (design.md ข้อ 5.11) */
.stat-strip {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    padding: 0 var(--space-4) var(--space-3);
}

.stat-strip-item {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding-right: var(--space-4);
    border-right: var(--border-width) solid var(--color-border);
    min-width: 0;
    flex: 1 1 120px;
}

.stat-strip-item:last-child { border-right: 0; padding-right: 0; }

.stat-strip-label { font-size: var(--font-size-xs); color: var(--color-text-muted); }
.stat-strip-value { font-size: var(--font-size-lg); font-weight: var(--font-weight-bold); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------------ กราฟ
   ‼️ กราฟทั้งหมดเป็น SVG ที่ PHP วาดจากข้อมูลจริง ไม่มีไลบรารีภายนอก (กฎเหล็กข้อ 11)
      ไม่มี animation และไม่มีสามมิติ ตาม design.md ข้อ 5.4 */
.chart { display: block; width: 100%; height: auto; }

.chart-grid-line { stroke: var(--chart-grid); stroke-width: 1; }
.chart-axis-text { fill: var(--color-text-muted); font-size: 11px; font-family: var(--font-family); }
.chart-line { fill: none; stroke: var(--chart-1); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart-area { fill: var(--color-primary-soft); opacity: .8; }
.chart-dot { fill: var(--color-surface); stroke: var(--chart-1); stroke-width: 2; }

.chart-frame { padding: 0 var(--space-4) var(--space-4); }

.chart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    padding: 0 var(--space-4) var(--space-4);
    font-size: var(--font-size-sm);
}

/* วงแหวนสัดส่วน + รายการกำกับ (ต้องมีข้อความและตัวเลขเสมอ ห้ามสื่อด้วยสีอย่างเดียว) */
.donut-layout {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex-wrap: wrap;
}

.donut { width: 168px; height: 168px; flex: none; }
.donut-center-value { fill: var(--color-text); font-size: 26px; font-weight: 600; font-family: var(--font-family); }
.donut-center-label { fill: var(--color-text-muted); font-size: 11px; font-family: var(--font-family); }

.legend-list { list-style: none; padding: 0; margin: 0; flex: 1 1 180px; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }

.legend-row { display: flex; align-items: center; gap: var(--space-2); font-size: var(--font-size-sm); min-width: 0; }
.legend-swatch { width: var(--space-2); height: var(--space-2); border-radius: var(--radius-pill); flex: none; }
.legend-label { flex: 1 1 auto; min-width: 0; color: var(--color-text); }
.legend-value { color: var(--color-text); font-weight: var(--font-weight-medium); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------ การ์ดทางลัด
   ‼️ ทุกใบต้องเป็นลิงก์ไปหน้าที่มีอยู่จริง ห้ามสร้างทางลัดไปหน้าที่ยังไม่มี */
.tile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--space-3); }

.tile {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    color: var(--color-text);
    min-width: 0;
    transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.tile:hover { border-color: var(--color-primary-border); box-shadow: var(--shadow-card); text-decoration: none; color: var(--color-text); }

.tile-icon {
    width: var(--space-6);
    height: var(--space-6);
    border-radius: var(--radius-lg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    background: var(--tint-brand-bg);
    color: var(--tint-brand-fg);
}

.tile-icon .icon { width: var(--space-4); height: var(--space-4); }
.tile-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tile-title { font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); }
.tile-hint { font-size: var(--font-size-xs); color: var(--color-text-muted); }

/* --------------------------------------------------------- รายการที่ต้องดูแล
   ตัวเลขทางขวาคือ "จำนวนที่ต้องจัดการ" — เป็น 0 ได้ และต้องแสดง 0 ตามจริง */
.attention-list { display: flex; flex-direction: column; gap: var(--space-2); list-style: none; padding: 0; margin: 0; }

.attention-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    color: var(--color-text);
    min-width: 0;
}

a.attention-item:hover { border-color: var(--color-primary-border); text-decoration: none; color: var(--color-text); }

.attention-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.attention-title { font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); }
.attention-hint { font-size: var(--font-size-xs); color: var(--color-text-muted); }
.attention-count { font-size: var(--font-size-lg); font-weight: var(--font-weight-bold); font-variant-numeric: tabular-nums; flex: none; }

/* --------------------------------------------------------- การ์ดเว็บไซต์
   ภาพย่อคือภาพจริงของแม่แบบที่เว็บนั้นใช้ ถ้าไม่มีให้แสดงกรอบเปล่าพร้อมไอคอน */
.site-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(264px, 1fr)); gap: var(--space-3); }

.site-card {
    display: flex;
    flex-direction: column;
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    overflow: hidden;
    min-width: 0;
}

.site-card-media {
    position: relative;
    aspect-ratio: 16 / 10;
    background: var(--color-surface-muted);
    border-bottom: var(--border-width) solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-border-strong);
    overflow: hidden;
}

.site-card-media img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.site-card-media > .icon { width: var(--space-6); height: var(--space-6); }

.site-card-badges {
    position: absolute;
    top: var(--space-2);
    left: var(--space-2);
    right: var(--space-2);
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-2);
}

.site-card-body { padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.site-card-title { font-size: var(--font-size-base); font-weight: var(--font-weight-medium); margin: 0; }
.site-card-host { font-size: var(--font-size-xs); color: var(--color-text-muted); }

.site-card-stats { display: flex; gap: var(--space-4); margin-top: var(--space-2); flex-wrap: wrap; }
.site-card-stat { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.site-card-stat-label { font-size: var(--font-size-xs); color: var(--color-text-muted); display: flex; align-items: center; gap: var(--space-1); }
.site-card-stat-label .icon { width: var(--font-size-sm); height: var(--font-size-sm); }
.site-card-stat-value { font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); font-variant-numeric: tabular-nums; }

.site-card-footer {
    display: flex;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3) var(--space-3);
    margin-top: auto;
}

/* ‼️ ปุ่มท้ายการ์ดต้องอ่านครบทั้งคำ ไม่ใช่ถูกตัดเป็น "เปิดเว็บไซต์จ..."
      คำที่ถูกตัดคือคำที่บอกความหมายพอดี ("จริง" ในปุ่มเปิดเว็บไซต์จริง)

   ค่าเดิม flex: 1 1 0 บังคับให้ปุ่มสองใบแบ่งความกว้างเท่ากันและหดได้จนถึงศูนย์
   พอการ์ดกว้างราว 264-380px ตามกริด minmax(264px, 1fr) ข้อความไทยสองปุ่มรวมไอคอน
   ก็เกินความกว้างอยู่ดี ทั้งคู่จึงหดจนโดนตัดพร้อมกัน

   วิธีแก้คือให้ขึ้นบรรทัดใหม่แทนการหด
     flex-wrap: wrap        กว้างพอ = บรรทัดเดียว · แคบ = ซ้อนสองบรรทัดอย่างเป็นระเบียบ
     flex: 1 1 auto         ยังยืดเต็มความกว้างได้เมื่อขึ้นบรรทัดของตัวเอง
     min-width: max-content ไม่ยอมหดต่ำกว่าข้อความของตัวเอง = ตัวกระตุ้นให้ wrap ทำงาน

   ‼️ ไม่เลือกวิธีขยาย minmax เป็น 320px เพราะจะลดจำนวนคอลัมน์บนจอกว้าง
      ทั้งที่ปัญหาเกิดเฉพาะช่วงแคบ · แก้จุดหนึ่งแล้วทำอีกจุดแย่ลงไม่ใช่การแก้
   ‼️ ไม่เลือกวิธีย่อข้อความให้สั้นลง — เป็นการซ่อนปัญหา layout ด้วยการทำให้ข้อความแย่ลง
   ‼️ span.truncate ใน site-card.php ยังอยู่เป็นด่านสุดท้าย เผื่อภาษาที่ยาวกว่านี้ */
.site-card-footer { flex-wrap: wrap; }
.site-card-footer > * { flex: 1 1 auto; min-width: max-content; }

/* ------------------------------------------------- แถบเครื่องมือของหน้ารายการ
   ค้นหา + ตัวกรอง + เรียงลำดับ + ล้างค่า อยู่ในฟอร์ม GET เดียวกันเสมอ
   ‼️ ต้องกรอง/แบ่งหน้าที่ฝั่งเซิร์ฟเวอร์ ห้ามโหลดทั้งหมดมากรองในเบราว์เซอร์ (design.md ข้อ 5.5) */
.toolbar {
    display: flex;
    align-items: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    margin-bottom: var(--space-3);
}

.toolbar-search { flex: 1 1 240px; min-width: 0; }
.toolbar-field { flex: 0 1 180px; min-width: 0; }
.toolbar-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.toolbar .field { gap: var(--space-1); }

.result-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-bottom: var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.chip-row { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

.chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    height: var(--space-4);
    padding: 0 var(--space-2);
    border-radius: var(--radius-pill);
    background: var(--color-neutral-soft);
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-xs);
}

.chip .icon { width: var(--font-size-xs); height: var(--font-size-xs); }

/* ------------------------------------------------------- เมนูคำสั่งประจำแถว
   ‼️ 1-2 คำสั่งวางตรงได้ เกินกว่านั้นต้องยุบลงเมนูนี้ (design.md ข้อ 5.6) */
.row-menu { position: relative; display: inline-flex; }

.row-menu-panel {
    position: absolute;
    right: 0;
    top: calc(100% + var(--space-1));
    min-width: 200px;
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    box-shadow: var(--shadow-pop);
    padding: var(--space-1);
    z-index: 40;
    text-align: left;
}

.row-menu-panel[hidden] { display: none; }
.row-menu-panel form { margin: 0; }

.row-menu-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2);
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--color-text);
    font-family: inherit;
    font-size: var(--font-size-sm);
    text-align: left;
    cursor: pointer;
}

.row-menu-item:hover { background: var(--color-surface-muted); text-decoration: none; color: var(--color-text); }
.row-menu-item .icon { width: var(--icon-size); height: var(--icon-size); flex: none; }
.row-menu-item.is-danger { color: var(--color-danger); }
.row-menu-item.is-danger:hover { background: var(--color-danger-soft); color: var(--color-danger); }
.row-menu-divider { height: var(--border-width); background: var(--color-border); margin: var(--space-1) 0; }

/* --------------------------------------------------- ตารางที่กลายเป็นการ์ด
   ‼️ บนมือถือห้ามซ่อนคอลัมน์ทิ้ง ต้องพลิกเป็นการ์ดที่ยังเห็นข้อมูลครบ (design.md ข้อ 6)
      หัวคอลัมน์เดิมมาจาก data-label ที่ PHP ใส่ให้ในทุก <td> */
/* ‼️ ตารางทุกตัวในระบบพลิกเป็นการ์ดบนมือถือโดยปริยาย — ไม่ต้องไปเติมคลาสทีละหน้า
   หัวคอลัมน์ของแต่ละช่องมาจาก data-label ที่ JS เติมให้จาก <th> ตรงคอลัมน์นั้น
   ตารางที่ไม่ควรพลิก (เช่น ตารางที่มีคอลัมน์เดียวหรือใช้จัดวาง) ใส่คลาส .table-flat กำกับ */
@media (max-width: 720px) {
    .table:not(.table-flat) thead { display: none; }
    .table:not(.table-flat), .table:not(.table-flat) tbody, .table:not(.table-flat) tr, .table:not(.table-flat) td { display: block; width: 100%; }

    .table:not(.table-flat) tr {
        height: auto;
        border: var(--border-width) solid var(--color-border);
        border-radius: var(--radius-lg);
        padding: var(--space-2);
        margin-bottom: var(--space-2);
        background: var(--color-surface);
    }

    .table:not(.table-flat) tr:hover { background: var(--color-surface); }

    .table:not(.table-flat) td {
        display: flex;
        align-items: flex-start;
        justify-content: space-between;
        gap: var(--space-3);
        border-bottom: 0;
        padding: var(--space-1) var(--space-2);
        text-align: left;
    }

    .table:not(.table-flat) td::before {
        content: attr(data-label);
        flex: 0 0 38%;
        color: var(--color-text-muted);
        font-size: var(--font-size-xs);
    }

    .table:not(.table-flat) td.cell-actions { justify-content: flex-end; }
    .table:not(.table-flat) td.cell-actions::before { content: ""; flex: 0; }
    .table:not(.table-flat) .cell-numeric { text-align: left; }
    .table:not(.table-flat) tr:last-child td { border-bottom: 0; }
}

/* -------------------------------------------------------- สถานะกำลังโหลด */
.skeleton {
    background: linear-gradient(90deg, var(--color-neutral-soft) 25%, var(--color-surface-muted) 37%, var(--color-neutral-soft) 63%);
    background-size: 400% 100%;
    animation: skeleton-sweep 1.4s ease infinite;
    border-radius: var(--radius-sm);
    display: block;
}

.skeleton-text { height: var(--font-size-sm); margin-bottom: var(--space-2); }
.skeleton-title { height: var(--font-size-lg); width: 40%; margin-bottom: var(--space-3); }
.skeleton-block { height: var(--space-7); }

@keyframes skeleton-sweep { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

/* ------------------------------------------------------------ สถานะผิดพลาด
   ‼️ ต้องบอกสาเหตุและวิธีแก้ ไม่ใช่แค่ "เกิดข้อผิดพลาด" (design.md ข้อ 3.5) */
.error-state { text-align: center; padding: var(--space-6) var(--space-4); }

.error-state-icon {
    width: var(--space-7);
    height: var(--space-7);
    border-radius: var(--radius-pill);
    background: var(--color-danger-soft);
    color: var(--color-danger);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: var(--space-3);
}

.error-state h3 { color: var(--color-text); }
.error-state p { color: var(--color-text-muted); }

/* ================================================== ฟอร์ม: ส่วนขยาย v2 == */

.form-section { padding-bottom: var(--space-4); }
.form-section + .form-section { border-top: var(--border-width) solid var(--color-border); padding-top: var(--space-4); }
.form-section-head { margin-bottom: var(--space-3); }
.form-section-head h3 { margin-bottom: var(--space-1); font-size: var(--font-size-base); }
.form-section-head p { margin: 0; font-size: var(--font-size-sm); color: var(--color-text-muted); }

.form-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.field-optional { font-size: var(--font-size-xs); color: var(--color-text-muted); font-weight: var(--font-weight-normal); margin-left: var(--space-1); }
.field-label-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }

.char-counter { font-size: var(--font-size-xs); color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
.char-counter.is-over { color: var(--color-danger); font-weight: var(--font-weight-medium); }

.input.is-success, .select.is-success, .textarea.is-success { border-color: var(--color-success); }
.input.is-warning, .select.is-warning, .textarea.is-warning { border-color: var(--color-warning); }
.field-success { font-size: var(--font-size-xs); color: var(--color-success); display: flex; align-items: center; gap: var(--space-1); }
.field-warning { font-size: var(--font-size-xs); color: var(--color-warning); display: flex; align-items: center; gap: var(--space-1); }
.field-error { display: flex; align-items: center; gap: var(--space-1); }
.field-success .icon, .field-warning .icon, .field-error .icon { width: var(--font-size-sm); height: var(--font-size-sm); flex: none; }

/* อ่านอย่างเดียว — ต้องแยกจากช่องที่ปิดใช้งานด้วยสายตา (ยังคัดลอกค่าได้) */
.input[readonly], .textarea[readonly] {
    background: var(--color-surface-muted);
    border-style: dashed;
    color: var(--color-text);
}

.field.is-loading .input,
.field.is-loading .select,
.field.is-loading .textarea { opacity: .6; pointer-events: none; }

/* สวิตช์เปิด/ปิด */
.switch { display: flex; align-items: center; gap: var(--space-3); cursor: pointer; font-size: var(--font-size-sm); }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }

.switch-track {
    position: relative;
    width: 44px;
    height: 24px;
    border-radius: var(--radius-pill);
    background: var(--color-border-strong);
    flex: none;
    transition: background var(--transition-base);
}

.switch-track::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 20px;
    height: 20px;
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
    transition: transform var(--transition-base);
}

.switch input:checked + .switch-track { background: var(--btn-primary-bg); }
.switch input:checked + .switch-track::after { transform: translateX(20px); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.switch input:disabled + .switch-track { background: var(--color-neutral-soft); }
.switch-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.switch-hint { font-size: var(--font-size-xs); color: var(--color-text-muted); }

.check-card {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    background: var(--color-surface);
    font-size: var(--font-size-sm);
    cursor: pointer;
}

.check-card:hover { border-color: var(--color-primary-border); }
.check-card:has(input:checked) { border-color: var(--color-primary); background: var(--color-primary-soft); }
.check-card input { margin-top: 3px; accent-color: var(--color-primary); flex: none; }

/* ช่องกรอกที่มีคำนำหน้า/ต่อท้ายติดกัน เช่น slug ของหน้าเว็บ */
.input-joined { display: flex; align-items: stretch; width: 100%; }

.input-joined > .input-joined-affix {
    display: inline-flex;
    align-items: center;
    padding: 0 var(--space-2);
    background: var(--color-surface-muted);
    border: var(--border-width) solid var(--color-border-strong);
    color: var(--color-text-muted-on-soft);
    font-size: var(--font-size-sm);
    white-space: nowrap;
}

.input-joined > .input-joined-affix:first-child { border-radius: var(--radius-base) 0 0 var(--radius-base); border-right: 0; }
.input-joined > .input-joined-affix:last-child { border-radius: 0 var(--radius-base) var(--radius-base) 0; border-left: 0; }
.input-joined > .input { border-radius: 0; min-width: 0; }
.input-joined > .input:first-child { border-radius: var(--radius-base) 0 0 var(--radius-base); }
.input-joined > .input:last-child { border-radius: 0 var(--radius-base) var(--radius-base) 0; }

/* ช่องกรอกป้ายกำกับหลายค่า — ค่าจริงส่งเป็นข้อความคั่นจุลภาคช่องเดียว
   ‼️ ปิด JavaScript แล้วยังใช้ได้ (กลายเป็นช่องข้อความธรรมดา) */
.tag-input {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1);
    min-height: var(--height-input);
    padding: var(--space-1);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-base);
    background: var(--color-surface);
    cursor: text;
}

.tag-input:focus-within { border-color: var(--color-primary); box-shadow: 0 0 0 3px var(--color-primary-soft); }

.tag-input-entry {
    flex: 1 1 100px;
    min-width: 80px;
    border: 0;
    outline: none;
    font-family: inherit;
    font-size: var(--font-size-sm);
    background: transparent;
    color: var(--color-text);
    height: var(--space-5);
}

.tag-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    height: var(--space-4);
    padding: 0 var(--space-1) 0 var(--space-2);
    border-radius: var(--radius-pill);
    background: var(--color-primary-soft);
    color: var(--color-primary-strong);
    font-size: var(--font-size-xs);
}

.tag-chip button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--space-3);
    height: var(--space-3);
    border: 0;
    border-radius: var(--radius-pill);
    background: transparent;
    color: inherit;
    cursor: pointer;
    padding: 0;
}

.tag-chip button:hover { background: var(--color-primary-border); }
.tag-chip .icon { width: 12px; height: 12px; }

.repeater { display: flex; flex-direction: column; gap: var(--space-2); }

.repeater-row {
    display: flex;
    align-items: flex-end;
    gap: var(--space-2);
    padding: var(--space-2);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    background: var(--color-surface-muted);
}

.repeater-row > .field { flex: 1 1 160px; min-width: 0; }

/* แถบปุ่มบันทึกที่ติดขอบล่าง — ต้องไม่บังเนื้อหาบรรทัดสุดท้าย */
.sticky-actions {
    position: sticky;
    bottom: 0;
    z-index: 15;
    background: var(--color-surface);
    border-top: var(--border-width) solid var(--color-border);
    padding: var(--space-3) var(--space-4);
    margin: var(--space-4) calc(var(--space-4) * -1) calc(var(--space-4) * -1);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.sticky-actions .sticky-actions-note { margin-right: auto; font-size: var(--font-size-sm); color: var(--color-text-muted); }

/* ปุ่มที่กำลังส่งฟอร์ม — กันกดซ้ำและบอกว่ากำลังทำงานอยู่ */
.btn.is-busy { position: relative; color: transparent !important; pointer-events: none; }

.btn.is-busy::after {
    content: "";
    position: absolute;
    width: var(--space-3);
    height: var(--space-3);
    border: 2px solid var(--color-text-inverse);
    border-top-color: transparent;
    border-radius: var(--radius-pill);
    animation: spin 700ms linear infinite;
}

.btn-secondary.is-busy::after,
.btn-ghost.is-busy::after { border-color: var(--color-text); border-top-color: transparent; }

/* ขอบเขตที่มีคำสั่งกำลังทำงานอยู่ — แถวในตาราง การ์ด หรือกลุ่มปุ่ม
   ‼️ ต้องเห็นได้แม้เมนูที่กดปุ่มไปนั้นปิดไปแล้ว · ไม่งั้นผู้ใช้จะไม่เหลืออะไรให้ดูเลย
      แล้วกดคำสั่งเดิมซ้ำเพราะคิดว่าครั้งแรกไม่ติด
   ‼️ ห้ามเปลี่ยนขนาดหรือระยะห่าง · ใช้เฉพาะความทึบและสีพื้น
      ถ้าแถวขยับตอนกด ตัวชี้เมาส์จะไปอยู่เหนือแถวอื่นทันทีและกดผิดแถว */
[data-busy-scope].is-busy-scope { cursor: progress; }

tr[data-busy-scope].is-busy-scope > td { background: var(--color-surface-muted); }

[data-busy-scope].is-busy-scope a:not(.btn),
[data-busy-scope].is-busy-scope .row-menu-trigger { opacity: 0.55; pointer-events: none; }

/* ลิงก์ที่ถูกปิดชั่วคราว — ปิดด้วย aria-disabled ไม่ใช่ถอด href
   ‼️ ถอด href ออกแล้วโปรแกรมอ่านหน้าจอจะไม่เห็นว่าเคยมีลิงก์อยู่ตรงนี้ */
a.btn.is-disabled { pointer-events: none; opacity: 0.6; }

/* =========================================== อัปโหลดไฟล์ (ส่วนประกอบกลาง)
   ‼️ ช่อง <input type="file"> ของเบราว์เซอร์ยังอยู่ในฟอร์มจริงเสมอ
      ถูกซ่อนเฉพาะเมื่อ JavaScript ทำงาน (คลาส is-enhanced) — ปิด JS แล้วยังอัปโหลดได้
   ‼️ การตรวจไฟล์ฝั่งเบราว์เซอร์เป็นแค่การช่วยผู้ใช้ ฝั่งเซิร์ฟเวอร์ยังตรวจซ้ำทุกครั้ง */
.uploader { display: flex; flex-direction: column; gap: var(--space-3); }

.uploader-drop {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-5) var(--space-4);
    border: 2px dashed var(--color-border-strong);
    border-radius: var(--radius-lg);
    background: var(--color-surface-muted);
    text-align: center;
    cursor: pointer;
    transition: border-color var(--transition-base), background var(--transition-base);
}

.uploader-drop:hover { border-color: var(--color-primary); background: var(--color-primary-soft); }
.uploader-drop.is-dragover { border-color: var(--color-primary); background: var(--color-primary-soft); border-style: solid; }
.uploader-drop.is-invalid { border-color: var(--color-danger); background: var(--color-danger-soft); }

.uploader-icon {
    width: var(--space-6);
    height: var(--space-6);
    border-radius: var(--radius-pill);
    background: var(--color-primary-soft);
    color: var(--color-primary-strong);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.uploader-title { font-size: var(--font-size-sm); font-weight: var(--font-weight-medium); color: var(--color-text); }
.uploader-hint { font-size: var(--font-size-xs); color: var(--color-text-muted-on-soft); margin: 0; }

.uploader-rules {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-1) var(--space-3);
    list-style: none;
    padding: 0;
    margin: 0;
    font-size: var(--font-size-xs);
    color: var(--color-text-muted-on-soft);
}

.uploader-rules li { display: flex; align-items: center; gap: var(--space-1); }
.uploader-rules .icon { width: var(--font-size-sm); height: var(--font-size-sm); flex: none; }

.uploader.is-enhanced .uploader-native { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

.uploader-list { display: flex; flex-direction: column; gap: var(--space-2); list-style: none; padding: 0; margin: 0; }

.uploader-item {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    background: var(--color-surface);
    min-width: 0;
}

.uploader-item.is-error { border-color: var(--color-danger); background: var(--color-danger-soft); }
.uploader-item.is-done { border-color: var(--color-success); }

.uploader-thumb {
    width: var(--space-6);
    height: var(--space-6);
    border-radius: var(--radius-base);
    background: var(--color-neutral-soft);
    color: var(--color-text-muted-on-soft);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex: none;
}

.uploader-thumb img { width: 100%; height: 100%; object-fit: cover; }

.uploader-info { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.uploader-name { font-size: var(--font-size-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uploader-meta { font-size: var(--font-size-xs); color: var(--color-text-muted); }
.uploader-item-actions { display: flex; align-items: center; gap: var(--space-1); flex: none; }

.uploader-progress { height: 4px; border-radius: var(--radius-pill); background: var(--color-neutral-soft); overflow: hidden; margin-top: var(--space-1); }
.uploader-progress > span { display: block; height: 100%; width: 0; background: var(--color-primary); transition: width var(--transition-base); }
.uploader-progress.is-error > span { background: var(--color-danger); }
.uploader-progress.is-done > span { background: var(--color-success); }

.uploader-total { display: flex; align-items: center; gap: var(--space-2); font-size: var(--font-size-sm); color: var(--color-text-muted); }
.uploader-total .progress { flex: 1 1 auto; }

/* ========================================================== ลิ้นชักด้านข้าง
   ‼️ ใช้กับงานที่มีหลายช่องแต่ไม่คุ้มจะเปลี่ยนหน้า — ห้ามซ้อนลิ้นชักในลิ้นชัก */
.drawer-backdrop {
    position: fixed;
    inset: 0;
    background: var(--color-backdrop);
    z-index: 88;
}

.drawer-backdrop[hidden], .drawer[hidden] { display: none; }

.drawer { border-left: var(--border-width) solid var(--color-border); }

.drawer-header {
    padding: var(--space-3) var(--space-4);
    border-bottom: var(--border-width) solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
}

.drawer-header h2 { margin: 0; font-size: var(--font-size-lg); }
.drawer-body { padding: var(--space-4); overflow-y: auto; flex: 1 1 auto; }

.drawer-footer {
    padding: var(--space-3) var(--space-4);
    border-top: var(--border-width) solid var(--color-border);
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* ================================================================ ทัวร์แนะนำ
   ‼️ ขั้นตอนของทัวร์มาจาก PHP ตาม role ที่ล็อกอินอยู่ ทุกบรรทัดผ่าน __() */
.tour-backdrop { position: fixed; inset: 0; background: var(--color-backdrop-strong); z-index: 96; display: flex; align-items: center; justify-content: center; padding: var(--space-3); }
.tour-backdrop[hidden] { display: none; }

.tour-card {
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: 100%;
    max-width: 520px;
    overflow: hidden;
}

.tour-media {
    background: var(--color-primary-soft);
    color: var(--color-primary-strong);
    padding: var(--space-5);
    display: flex;
    align-items: center;
    justify-content: center;
}

.tour-media .icon { width: var(--space-7); height: var(--space-7); }
.tour-body { padding: var(--space-4); }
.tour-body h2 { font-size: var(--font-size-lg); }
.tour-body p { color: var(--color-text-muted); margin-bottom: 0; }

.tour-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-top: var(--border-width) solid var(--color-border);
    flex-wrap: wrap;
}

.tour-dots { display: flex; align-items: center; gap: var(--space-1); }
.tour-dot { width: var(--space-2); height: var(--space-2); border-radius: var(--radius-pill); background: var(--color-border-strong); transition: width var(--transition-base), background var(--transition-base); }
.tour-dot.is-active { background: var(--color-primary); width: var(--space-4); }

/* ============================================================== responsive */

@media (max-width: 992px) {
    /* จอกลางลงมาไม่มีโหมดย่อ — ปุ่มเดียวกันกลายเป็นปุ่มเปิดลิ้นชักแทน */
    .app.is-rail { grid-template-columns: minmax(0, 1fr); }
    .app.is-rail .sidebar { padding: var(--space-4) var(--space-3); }
    .app.is-rail .sidebar-brand { justify-content: flex-start; }
    .app.is-rail .sidebar-brand > span,
    .app.is-rail .sidebar-link > span,
    .app.is-rail .sidebar-section-title,
    .app.is-rail .sidebar-card-title span,
    .app.is-rail .sidebar-card-text,
    .app.is-rail .sidebar-card .btn span { display: inline; }
    .app.is-rail .sidebar-link { justify-content: flex-start; padding-left: var(--space-3); }
    .app.is-rail .sidebar-link::before { display: block; }
    .app.is-rail .sidebar-card { padding: var(--space-3); text-align: left; }

    .form-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .donut-layout { justify-content: center; }
}

@media (max-width: 640px) {
    .form-grid-3 { grid-template-columns: minmax(0, 1fr); }
    .stat-strip-item { border-right: 0; padding-right: 0; flex-basis: 42%; }
    .toolbar { padding: var(--space-2); }
    .toolbar-field, .toolbar-search { flex-basis: 100%; }
    .toolbar-actions { width: 100%; }
    .toolbar-actions .btn { flex: 1 1 auto; }
    .site-card-grid { grid-template-columns: minmax(0, 1fr); }
    .tile-grid { grid-template-columns: minmax(0, 1fr); }
    .sticky-actions { margin: var(--space-3) calc(var(--space-3) * -1) calc(var(--space-3) * -1); padding: var(--space-2) var(--space-3); }
    .sticky-actions .btn { flex: 1 1 auto; }
    .sticky-actions .sticky-actions-note { flex-basis: 100%; margin-bottom: var(--space-1); }
    .repeater-row { flex-wrap: wrap; }
    .donut { width: 140px; height: 140px; }
    .drawer { width: 100%; }
}

/* ======================================= หน้าที่ยังไม่ล็อกอิน: กฎเพิ่มเติม v2
   ‼️ ต้องอยู่ท้ายไฟล์เพื่อทับกฎ responsive ชุดเดิมของ auth ที่เขียนไว้ก่อนหน้า
   เป้าหมายความสูง: ที่ 1366x768 สถานะปกติต้องเห็นครบโดยไม่ต้องเลื่อน
   และห้ามใช้ overflow:hidden หรือ transform:scale() มาบังคับ */

/* จอเตี้ย (แล็ปท็อป 768px ลงมา) — บีบระยะห่างแทนการย่อขนาดตัวอักษรทั้งหน้า */
@media (min-width: 993px) and (max-height: 820px) {
    .auth-aside { padding: var(--space-4) var(--space-5) 0; gap: var(--space-3); }
    .auth-aside-top { gap: var(--space-2); }
    .auth-headline { font-size: var(--font-size-2xl); }
    .auth-features { gap: var(--space-2); }
    .auth-feature-icon { width: 2.25rem; height: 2.25rem; }
    /* ‼️ 22rem ไม่ใช่ 28rem — วัดจริงที่ 1366x768 แล้วคอลัมน์ซ้ายยังสูง 654px เทียบกับพื้นที่ 610px
          ตัวที่ดันความสูงคือแผงแบรนด์ ไม่ใช่การ์ดฟอร์ม (การ์ดสูงแค่ 538px ซึ่งพอดีอยู่แล้ว)
          ‼️ นี่คือการย่อ "ขนาดที่แสดง" ของภาพประกอบตามจอ ไม่ใช่การเปลี่ยนเป็นภาพอื่น
             และไม่ได้ย่อตัวอักษรหรือความสูงของช่องกรอกซึ่งกระทบการใช้งานจริง */
    .auth-artwork { max-width: 22rem; }
    .auth-main { padding: var(--space-2) var(--space-4) var(--space-4); }
    .auth-card { padding: var(--space-4); gap: var(--space-3); }
    .auth-title { font-size: var(--font-size-xl); }
}

/* จอเตี้ยมาก — ตัดคำอธิบายรองของรายการคุณสมบัติออกก่อน แล้วค่อยตัดภาพ */
@media (min-width: 993px) and (max-height: 700px) {
    .auth-feature-hint { display: none; }
    .auth-artwork { display: none; }
    .auth-aside { justify-content: flex-start; }
}

@media (max-width: 992px) {
    /* แท็บเล็ต: ลดข้อความและภาพผลิตภัณฑ์ก่อน แต่ยังคงแถบแบรนด์ไว้ */
    .auth-aside::after { display: none; }
    .auth-aside { border-right: 0; border-bottom: var(--border-width) solid var(--color-border); }
    .auth-headline { font-size: var(--font-size-2xl); }
}

@media (max-width: 640px) {
    /* มือถือ: เหลือแถบแบรนด์บางๆ กับฟอร์มเต็มความกว้าง และต้องเลื่อนได้เมื่อคีย์บอร์ดเปิด */
    .auth-shell { min-height: 100dvh; }
    .auth-aside { padding: var(--space-3); gap: 0; }
    .auth-aside::before { display: none; }
    .auth-headline { display: none; }
    .auth-badge { display: none; }
    .auth-card { padding: var(--space-4); box-shadow: none; border-radius: var(--radius-lg); }
    .auth-grid-2 { grid-template-columns: minmax(0, 1fr); }
}

/* สีของวงแหวนและจุดกำกับ — ไล่ตามลำดับเท่านั้น (ค่าจริงอยู่ที่ :root ข้างบน) */
.donut-slice-s1 { stroke: var(--chart-1); }
.donut-slice-s2 { stroke: var(--chart-2); }
.donut-slice-s3 { stroke: var(--chart-3); }
.donut-slice-s4 { stroke: var(--chart-4); }
.donut-slice-s5 { stroke: var(--chart-5); }

.legend-swatch-s1 { background: var(--chart-1); }
.legend-swatch-s2 { background: var(--chart-2); }
.legend-swatch-s3 { background: var(--chart-3); }
.legend-swatch-s4 { background: var(--chart-4); }
.legend-swatch-s5 { background: var(--chart-5); }

/* ‼️ ปุ่มแจ้งปัญหาลอยอยู่มุมขวาล่างทุกหน้า — บนหน้าที่ยังไม่ล็อกอินมันจะไปทับบรรทัดล่างสุดของการ์ด
   เว้นที่ให้มันด้วยการดันการ์ดขึ้น ไม่ใช่ย้ายปุ่มไปที่อื่น (ปุ่มต้องอยู่ตำแหน่งเดิมทุกหน้าของระบบ) */
@media (min-width: 993px) {
    .auth-main { padding-bottom: var(--space-7); }
}

/* จอเตี้ยบีบระยะห่างในการ์ดลงอีกขั้น เพื่อให้ฟอร์มสมัคร (5 ช่อง) พอดี 768px โดยไม่ต้องตัดช่องใดออก */
@media (min-width: 993px) and (max-height: 820px) {
    .auth-card { gap: var(--space-2); }
    .auth-head { gap: var(--space-1); }
    .auth-card-mark { width: 2.25rem; height: 2.25rem; }
    .auth-topbar { margin-bottom: var(--space-1); }
}

/* ‼️ ปุ่มแรก (แก้ไข) ยืดได้ ปุ่มที่สอง (เปิดเว็บ) กว้างตามข้อความ
   ถ้าแบ่งครึ่งเท่ากัน ข้อความภาษาอังกฤษที่ยาวกว่าจะถูกตัดหายทันที */
.site-card-footer > *:first-child { flex: 1 1 auto; }
.site-card-footer > *:last-child { flex: 0 1 auto; }
.site-card-footer > * { min-width: 0; }

/* ‼️ การ์ดรูปในคลังต้องกว้างพอให้ช่องคำอธิบายภาพใช้งานได้จริง
   ของเดิม 160px ทำให้ช่องกรอกเหลือความกว้างไม่ถึงครึ่งคำ */
.media-grid { grid-template-columns: repeat(auto-fill, minmax(212px, 1fr)); }
.media-item { border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }
.media-thumb { aspect-ratio: 3 / 2; }
.media-meta { padding: var(--space-3); gap: var(--space-2); }
.media-meta .input { font-size: var(--font-size-xs); }

/* ‼️ เมนูคำสั่งประจำแถวที่อยู่ในตารางซึ่งเลื่อนแนวนอนได้ ต้อง "ลอย" ออกมานอกกรอบ
   ไม่งั้นแถวท้ายๆ จะถูกกรอบตัดจนกดคำสั่งไม่ได้ · ตำแหน่งคำนวณจาก JS ตอนเปิด */
.row-menu-panel.is-floating { position: fixed; }

/* แถบตัวเลขที่อยู่ใน card-body อยู่แล้ว ไม่ต้องเว้นระยะซ้ำอีกชั้น */
.card-body > .stat-strip { padding: 0; }

/* ================================================================ โหมดมืด
   ‼️ ไม่มี CSS ชุดที่สอง — โหมดมืดคือการเขียนทับ token ชุดเดิมเท่านั้น
      กฎทุกบรรทัดในไฟล์นี้อ้าง var(--…) อยู่แล้ว จึงเปลี่ยนตามได้ทั้งระบบโดยไม่ต้องแตะกฎใดเลย
      ถ้าวันไหนมีคนเขียนค่าสีดิบลงในกฎ จุดนั้นจะค้างเป็นสีของโหมดสว่างทันที (ห้ามทำ)

   ‼️ ขอบเขต: ระบบจัดการและหน้าที่ยังไม่ล็อกอินเท่านั้น
      เว็บไซต์ของลูกค้า, Editor canvas, Preview และเว็บที่ publish แล้ว ใช้ site.css คนละไฟล์
      และไม่มี attribute data-theme บน <html> จึงไม่ได้รับผลจากบล็อกนี้โดยโครงสร้าง

   ‼️ พื้นเป็นกรมท่า/สเลท ไม่ใช่ดำสนิท — ดำสนิทกับตัวอักษรขาวได้ contrast สูงเกินจนอ่านนาน ๆ แล้วล้า
      และทำให้แบรนด์กรมท่าหายไปทั้งหมด

   ‼️ ทุกคู่สีในบล็อกนี้ตรวจด้วย WCAG 2.1 แล้ว ตัวเลขกำกับไว้ท้ายบรรทัดที่สำคัญ
      ตรวจซ้ำอัตโนมัติด้วย scripts/check-screens.php ซึ่งเดินทั้งสองธีม */
:root[data-theme="dark"] {
    /* ---- สีแบรนด์ ----
       ‼️ กลับด้านจากโหมดสว่าง: ที่นั่น --color-primary-strong คือส้ม "เข้มขึ้น" เพื่อให้อ่านออกบนพื้นขาว
          ที่นี่ต้องส้ม "สว่างขึ้น" ด้วยเหตุผลเดียวกันแต่กลับทาง (#FF8A3D บนการ์ด = 6.94:1)
          ส้มแบรนด์ตัวจริง #E8590C บนพื้นเข้มได้ 3.96:1 จึงใช้เป็นตัวอักษรไม่ได้ ใช้ได้แค่เป็นพื้น */
    --color-primary:        #E8590C;
    --color-primary-strong: #FF8A3D;
    --color-primary-hover:  #FFA463;
    --color-primary-soft:   #33200F;
    --color-primary-border: #5A3218;
    /* ‼️ ยังเป็นกรมท่าในโหมดนี้ เพราะถูกใช้เป็น "พื้น" (ปุ่มลอย, บล็อกโค้ด, รูปทรงตกแต่งของหน้าล็อกอิน)
          สว่างขึ้นแค่พอให้แยกออกจากพื้นหน้า · ที่ใช้เป็น "ตัวอักษร" ใช้ --color-secondary-text แทน
    --color-secondary:      #22304E;
    --color-secondary-soft: #1C2740;

    /* ---- พื้นเข้มของหน้าแนะนำผลิตภัณฑ์ ----
       ‼️ ชุดนี้ถูกออกแบบมาสำหรับพื้นกรมท่าอยู่แล้ว จึงแทบไม่ต้องแก้
          ยกเว้น --color-device-edge ที่เป็นเส้นขอบอุปกรณ์บนพื้นสว่าง */
    --color-device-edge: #3A4763;

    /* ---- พื้นผิว ---- */
    --color-bg:            #0E1626;
    --color-surface:       #162034;
    --color-surface-muted: #1B2740;
    /* เส้นตกแต่งไม่ต้องผ่าน 3:1 (ไม่ใช่ขอบเขตของ control) แต่ต้องมองเห็นว่ามีเส้น */
    --color-border:        #2A3652;
    /* ‼️ ตัวนี้เป็นขอบของช่องกรอกและปุ่ม จึงต้องผ่าน 1.4.11 ที่ 3:1
       #6B7A95 บนช่องกรอก = 3.43:1 · บนการ์ด = 3.75:1 · บนพื้นแอป = 4.17:1 */
    --color-border-strong: #6B7A95;
    --color-text:          #E7ECF5;   /* บนการ์ด 13.73:1 */
    --color-text-muted:    #A3B0C6;   /* บนการ์ด 7.43:1 · บนพื้นนุ่ม 6.79:1 */
    --color-text-muted-on-soft: #B3BFD3;   /* บนพื้นนุ่ม 8.02:1 */
    --color-text-inverse:  #FFFFFF;

    /* ---- สี semantic ----
       ‼️ ยังสงวนไว้สื่อสถานะเท่านั้น ห้ามเอาไปตกแต่ง เหมือนโหมดสว่างทุกประการ
          ค่าเดิมของโหมดสว่างเป็นเฉดเข้มทั้งชุด ซึ่งบนพื้นมืดอ่านไม่ออกเลย จึงต้องสว่างขึ้นทั้งชุด */
    --color-success:      #6FD6AE;   /* บนการ์ด 9.23:1 · บนพื้นของตัวเอง 9.03:1 */
    --color-success-soft: #10261E;
    --color-warning:      #F0BE5C;   /* 9.47:1 · 9.24:1 */
    --color-warning-soft: #2A2110;
    --color-danger:       #FF8A8A;   /* 7.17:1 · 7.53:1 */
    --color-danger-soft:  #2E1418;
    --color-info:         #7FB6EA;   /* 7.58:1 · 7.30:1 */
    --color-info-soft:    #12243A;
    --color-neutral:      #B3BFD3;   /* 8.77:1 · 7.98:1 */
    --color-neutral-soft: #1E2839;

    /* ---- เงา ----
       ‼️ เงาสีเทาโปร่งบนพื้นมืดมองไม่เห็นเลย ต้องเป็นสีดำและทึบกว่าเดิม
          ไม่งั้นการ์ดทุกใบจะดูแบนติดกันไปหมดจนแยกไม่ออกว่าอะไรซ้อนอยู่บนอะไร */
    --shadow-sm:     0 1px 2px rgba(0, 0, 0, .40);
    --shadow-base:   0 2px 8px rgba(0, 0, 0, .45);
    --shadow-lg:     0 12px 32px rgba(0, 0, 0, .55);
    --shadow-device: 0 24px 60px rgba(0, 0, 0, .65);
    --shadow-card:   0 1px 2px rgba(0, 0, 0, .30), 0 1px 3px rgba(0, 0, 0, .35);
    --shadow-pop:    0 8px 24px rgba(0, 0, 0, .50);

    /* ---- โทนสีของชิปไอคอน ----
       ‼️ ข้อยกเว้นที่ผู้ใช้อนุมัติไว้ (CLAUDE.md ข้อ 1.5) ยังเป็นแบบเดิม: ต่างกันได้เฉพาะชิปไอคอน
          พื้นการ์ดทุกใบยังเป็นสีเดียวกันหมด และในโหมดนี้คือ --color-surface */
    --tint-brand-bg:  #33200F;  --tint-brand-fg:  #FF8A3D;
    --tint-green-bg:  #10261E;  --tint-green-fg:  #6FD6AE;
    --tint-violet-bg: #1E1938;  --tint-violet-fg: #B7A6F5;
    --tint-blue-bg:   #12243A;  --tint-blue-fg:   #7FB6EA;
    --tint-slate-bg:  #1E2839;  --tint-slate-fg:  #B3BFD3;

    /* ---- สีของกราฟ ----
       ‼️ ลำดับต้องเหมือนโหมดสว่างเป๊ะ ๆ (ส้ม → ม่วง → เขียว → น้ำเงิน → เทา)
          ผู้ใช้ที่จำได้ว่า "เส้นส้มคือผู้เข้าชม" ต้องจำแบบเดิมได้ในทั้งสองธีม */
    --chart-1: #FF8A3D;
    --chart-2: #A48BF5;
    --chart-3: #6FD6AE;
    --chart-4: #7FB6EA;
    --chart-5: #64728C;
    --chart-grid: #26314A;

    /* ---- ค่าที่ยกขึ้นมาเป็น token ---- */
    /* ‼️ ทึบขึ้นกว่าโหมดสว่าง เพราะพื้นข้างหลังเข้มอยู่แล้ว ถ้าใช้ความทึบเท่าเดิม
          จะแยกไม่ออกว่าอะไรอยู่หน้าอะไร แล้ว modal จะดูเหมือนเป็นส่วนหนึ่งของหน้า */
    --color-backdrop:        rgba(4, 8, 16, .70);
    --color-backdrop-strong: rgba(4, 8, 16, .76);
    /* แผงแบรนด์ของหน้าล็อกอิน — พื้นครีมกลายเป็นกรมท่าไล่เฉด ยังเป็นแบรนด์เดิม */
    --auth-aside-bg:   linear-gradient(160deg, #16223C 0%, #101A2E 46%, #1D2438 100%);
    --auth-aside-glow: radial-gradient(circle, rgba(232, 89, 12, .22), transparent 64%);
}

/* ‼️ ปุ่มหลักเป็นจุดเดียวที่ใช้สีแบรนด์เป็น "พื้น" ไม่ใช่ "ตัวอักษร"
      จึงต้องมี token ของตัวเอง ไม่งั้นในโหมดมืดปุ่มจะกลายเป็นส้มสว่างพร้อมตัวอักษรขาว = 2.1:1
      ค่าของโหมดสว่างเท่ากับพฤติกรรมเดิมทุกประการ หน้าตาโหมดสว่างจึงไม่เปลี่ยนแม้แต่พิกเซลเดียว */
:root {
    --btn-primary-bg:       var(--color-primary-strong);
    --btn-primary-bg-hover: var(--color-primary-hover);
    --btn-primary-fg:       var(--color-text-inverse);
    /* สีรองของแบรนด์เมื่อใช้เป็นตัวอักษร — ค่าเท่ากับพฤติกรรมเดิมทุกประการ */
    --color-secondary-text: var(--color-secondary);
    /* สี semantic เมื่อใช้เป็น "พื้นที่มีตัวอักษรทับ" — ค่าเท่ากับพฤติกรรมเดิมทุกประการ */
    --solid-danger-bg:  var(--color-danger);
    --solid-danger-fg:  var(--color-text-inverse);
    --solid-warning-bg: var(--color-warning);
    --solid-warning-fg: var(--color-text-inverse);
    --solid-info-bg:    var(--color-info);
    --solid-info-fg:    var(--color-text-inverse);
}

:root[data-theme="dark"] {
    /* ส้มแบรนด์เต็ม ๆ กับตัวอักษรเกือบดำ = 5.29:1 (hover 7.28:1)
       เลือกทางนี้แทนการทำให้ปุ่มมืดลง เพราะปุ่มหลักต้องเด่นที่สุดในหน้าเสมอ */
    --btn-primary-bg:       #E8590C;
    --btn-primary-bg-hover: #FF7A2E;
    --btn-primary-fg:       #1A0E04;
    /* ‼️ สีรองของแบรนด์เมื่อใช้เป็นตัวอักษร ต้องสว่างขึ้นจนอ่านออกบนพื้นมืด
          ส่วนที่ใช้เป็นพื้น (ปุ่มลอย, บล็อกโค้ด) ยังเป็นกรมท่าเหมือนเดิม */
    --color-secondary-text: #C6D3EA;
    /* ‼️ ยังเป็นเฉดเข้มเหมือนโหมดสว่าง เพราะมีตัวอักษรขาวทับอยู่
          ถ้าใช้เฉดสว่างเดียวกับตัวอักษร (--color-danger ฯลฯ) ปุ่มลบจะได้ 2.27:1
          สว่างขึ้นเล็กน้อยเฉพาะเท่าที่ยังคุมตัวอักษรขาวให้ผ่าน AA ได้ */
    --solid-danger-bg:  #D13B3B;   /* ขาวบนพื้นนี้ 4.77:1 */
    --solid-danger-fg:  #FFFFFF;
    --solid-warning-bg: #92610F;   /* 5.33:1 */
    --solid-warning-fg: #FFFFFF;
    --solid-info-bg:    #2A6FB5;   /* 5.20:1 */
    --solid-info-fg:    #FFFFFF;
}

.btn-primary {
    background: var(--btn-primary-bg);
    border-color: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
}

.btn-primary:hover {
    background: var(--btn-primary-bg-hover);
    border-color: var(--btn-primary-bg-hover);
    color: var(--btn-primary-fg);
}

/* ================================================================ ปุ่มสลับธีม
   ‼️ ไอคอนทั้งสองอยู่ในหน้าพร้อมกันตั้งแต่แรก แล้วซ่อนทีละตัวตาม data-theme
      ถ้าให้ JavaScript สร้างไอคอนตอนกด จะเห็นไอคอนหายไปหนึ่งเฟรมทุกครั้ง */
.theme-toggle { flex: none; }
.theme-toggle .theme-toggle-sun,
.theme-toggle .theme-toggle-moon { display: none; line-height: 0; }

/* โหมดสว่างอยู่ → โชว์ดวงจันทร์ เพราะปุ่มบอก "ผลลัพธ์หลังกด" ไม่ใช่สถานะตอนนี้ */
:root:not([data-theme="dark"]) .theme-toggle .theme-toggle-moon { display: inline-flex; }
:root[data-theme="dark"] .theme-toggle .theme-toggle-sun { display: inline-flex; }

/* ‼️ ปุ่มนี้อยู่บนแถบบนของหน้าที่ยังไม่ล็อกอินด้วย ซึ่งไม่มีพื้นการ์ดรองอยู่
      จึงต้องมีสีตัวอักษรของตัวเองไม่พึ่งบริบท */
.auth-topbar .theme-toggle { color: var(--color-text-muted); }
.auth-topbar .theme-toggle:hover { color: var(--color-text); background: var(--color-neutral-soft); }

/* ============================================ ช่องเลือกที่ค้นหาได้ (combobox)
   ‼️ ส่วนประกอบกลางตัวเดียวของทั้งระบบ · ห้ามสร้างแบบอื่นกระจายตามหน้า
   ‼️ ทุกค่าเป็น token — โหมดมืดจึงเปลี่ยนตามเองโดยไม่มีกฎเพิ่มแม้แต่บรรทัดเดียว
   ‼️ .is-enhanced ถูกใส่โดย JS เท่านั้น · ปิด JS แล้วจะเหลือ <select> ปกติที่ใช้งานได้ครบ */
.combobox { position: relative; }

/* ‼️ ห้ามใช้ display:none กับ <select> ตัวจริง
      เบราว์เซอร์ปฏิเสธการ submit เมื่อ field ที่ required อยู่ในสภาพ "โฟกัสไม่ได้"
      แล้วขึ้นแค่ error ใน console โดยผู้ใช้ไม่เห็นอะไรเลย
      จึงย่อให้เหลือ 1px โปร่งใสแทน — ยังโฟกัสได้ ยัง validate ได้ ยังถูกส่งไปกับฟอร์ม */
.combobox.is-enhanced > select {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: 0;
    border: 0;
    opacity: 0;
    pointer-events: none;
}

.combobox-control {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    width: 100%;
    min-height: var(--height-input);
    padding: 0 var(--space-1) 0 var(--space-2);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-base);
    background: var(--color-surface);
    cursor: text;
    transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.combobox-control:hover { border-color: var(--color-text-muted); }

.combobox.is-open .combobox-control,
.combobox-control:focus-within {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-soft);
}

.combobox.has-error .combobox-control { border-color: var(--color-danger); }

/* ‼️ ปิดใช้งานต้องดูออกว่ากดไม่ได้ โดยไม่พึ่งสีอย่างเดียว — เคอร์เซอร์เปลี่ยนด้วย */
.combobox.is-disabled .combobox-control {
    background: var(--color-neutral-soft);
    border-color: var(--color-border);
    cursor: not-allowed;
}

.combobox-input {
    flex: 1 1 auto;
    min-width: 0;
    height: calc(var(--height-input) - 2px);
    border: 0;
    outline: none;
    background: transparent;
    color: var(--color-text);
    font-family: inherit;
    font-size: var(--font-size-sm);
    text-overflow: ellipsis;
}

.combobox-input:disabled { cursor: not-allowed; }

/* ‼️ ตอนยังไม่พิมพ์ค้นหา ช่องนี้แสดง "ค่าที่เลือกอยู่" เป็น placeholder
      จึงต้องเข้มเท่าข้อความจริง ไม่ใช่สีจาง ๆ แบบ placeholder ทั่วไป
      ถ้าจางผู้ใช้จะอ่านว่ายังไม่ได้เลือกอะไร ทั้งที่เลือกไว้แล้ว */
.combobox-input::placeholder { color: var(--color-text-muted); opacity: 1; }
.combobox-input.has-selection::placeholder { color: var(--color-text); opacity: 1; }

.combobox-button,
.combobox-clear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 32px ผ่านเกณฑ์เป้าสัมผัสของ WCAG 2.2 AA (24px) พร้อมระยะเผื่อ */
    width: 32px;
    height: 32px;
    flex: none;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-text-muted);
    cursor: pointer;
}

.combobox-button:hover,
.combobox-clear:hover { background: var(--color-neutral-soft); color: var(--color-text); }

.combobox-button:focus-visible,
.combobox-clear:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }

.combobox.is-disabled .combobox-button,
.combobox.is-disabled .combobox-clear { cursor: not-allowed; }

.combobox-button .icon,
.combobox-clear .icon { width: var(--font-size-sm); height: var(--font-size-sm); }

.combobox.is-open .combobox-button .icon { transform: rotate(180deg); }

.combobox-list {
    position: absolute;
    z-index: 60;
    left: 0;
    right: 0;
    top: calc(100% + var(--space-1));
    max-height: 280px;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    box-shadow: var(--shadow-pop);
    padding: var(--space-1);
    list-style: none;
    margin: 0;
}

.combobox-list[hidden] { display: none; }

/* ‼️ JS เปลี่ยนเป็น fixed ตอนเปิด แล้วคำนวณตำแหน่งเอง (วิธีเดียวกับเมนูประจำแถวของตาราง)
      เพราะรายการอาจอยู่ในการ์ด แผง หรือ modal ที่ overflow ตัดขอบ
      และต้องพลิกขึ้นบนเองเมื่อที่ด้านล่างไม่พอ — ตำแหน่งจริงมาจาก JS ไม่ใช่ที่นี่ */
.combobox-list.is-floating { position: fixed; right: auto; }

.combobox-option {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    color: var(--color-text);
    cursor: pointer;
    min-height: 36px;
}

.combobox-option:hover,
.combobox-option.is-active { background: var(--color-surface-muted); }

/* ‼️ ตัวที่เลือกอยู่ต้องดูออกโดยไม่พึ่งสีอย่างเดียว จึงมีเครื่องหมายถูกกำกับด้วย */
.combobox-option.is-selected {
    background: var(--color-primary-soft);
    color: var(--color-primary-strong);
    font-weight: var(--font-weight-medium);
}

.combobox-option-check { flex: none; width: var(--font-size-sm); height: var(--font-size-sm); opacity: 0; }
.combobox-option.is-selected .combobox-option-check { opacity: 1; }

.combobox-option-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ‼️ บรรทัดรองของตัวเลือก (รหัส · อีเมล) — มีไว้แยกรายการที่ชื่อซ้ำกันออกจากกัน
      ต้องเป็นบล็อกของตัวเอง ไม่ใช่ต่อท้ายบรรทัดแรก ไม่งั้นชื่อยาวจะดันข้อมูลระบุตัวตนหายไปกับ ellipsis */
.combobox-option-meta {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-top: 1px;
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

/* ‼️ ตัวเลือกสองบรรทัดต้องจัดชิดบน ไม่ใช่กึ่งกลาง เพื่อให้เครื่องหมายถูกตรงกับชื่อ */
.combobox-option:has(.combobox-option-meta) { align-items: flex-start; }

/* ‼️ เน้นเฉพาะส่วนที่ตรงกับที่พิมพ์ ให้เห็นว่าทำไมรายการนี้ถึงขึ้นมา
      สร้างด้วย DOM node ไม่ใช่ innerHTML — ป้ายชื่อจากภายนอกจึงกลายเป็นแท็กไม่ได้ */
.combobox-option mark {
    background: transparent;
    color: inherit;
    font-weight: var(--font-weight-bold);
    text-decoration: underline;
}

.combobox-status {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

/* ‼️ ค้นหาไม่สำเร็จต้องดูต่างจาก "ไม่พบรายการ" — สองอย่างนี้ผู้ใช้ต้องทำต่อคนละแบบ
      ใช้สีสถานะจริงตามระบบสี ไม่ใช่สีตกแต่ง */
.combobox-status.is-error { color: var(--tint-red-fg); }

@media (max-width: 640px) {
    /* ‼️ บนมือถือรายการต้องไม่ล้นจอ — จำกัดตามความสูงจอจริง ไม่ใช่ค่าคงที่
          และแต่ละแถวสูงขึ้นเพราะกดด้วยนิ้ว ไม่ใช่เมาส์ */
    .combobox-list { max-height: min(50dvh, 280px); }
    .combobox-option { min-height: 44px; }
}

/* ============================================ ตัวเลือกรูปภาพ (media picker)
   ‼️ ใช้ token ชุดเดียวกับทั้งระบบ แต่มี class เป็นของตัวเอง ไม่ยืม .combobox-*
      เพราะ combobox ถูก freeze แล้ว — ถ้าผูกกัน การแก้หน้าตาฝั่งรูปภาพจะทำ dropdown ทั้งระบบพัง
   ‼️ .is-enhanced ถูกใส่โดย JS เท่านั้น · ปิด JS แล้วจะเหลือ <select> + รูปที่เลือกอยู่ ซึ่งส่งฟอร์มได้ครบ */
.media-picker { position: relative; }

/* ‼️ เหตุผลเดียวกับ combobox: ห้าม display:none กับ <select> ที่ required
      ไม่งั้นเบราว์เซอร์จะปฏิเสธการ submit เงียบ ๆ โดยผู้ใช้ไม่เห็นอะไรเลย */
.media-picker.is-enhanced > select {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: 0;
    border: 0;
    opacity: 0;
    pointer-events: none;
}

/* ปิด JS = ไม่มีปุ่ม ต้องบอกตรง ๆ · เปิด JS = ซ่อนคำอธิบายนั้นเพราะกดปุ่มได้แล้ว */
.media-picker.is-enhanced ~ .media-picker-nojs,
.field:has(.media-picker.is-enhanced) > .media-picker-nojs { display: none; }

.media-picker-current {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    min-height: 64px;
    padding: var(--space-2);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-base);
    background: var(--color-surface);
}

.media-picker.has-error .media-picker-current { border-color: var(--color-danger); }

.media-picker-thumb {
    flex: none;
    width: 48px;
    height: 48px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    background: var(--color-surface-muted);
}

.media-picker-thumb-empty {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
}

.media-picker-current-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.media-picker-current-label { font-size: var(--font-size-sm); color: var(--color-text); }

.media-picker-actions { display: flex; gap: var(--space-1); flex: none; }

/* ---------------------------------------------------------------- แผงเลือก */
.media-picker-panel {
    position: absolute;
    z-index: 60;
    left: 0;
    right: 0;
    top: calc(100% + var(--space-1));
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    max-height: 380px;
    padding: var(--space-2);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    box-shadow: var(--shadow-pop);
}

.media-picker-panel[hidden] { display: none; }

/* ‼️ JS เปลี่ยนเป็น fixed แล้วคำนวณตำแหน่งเอง — แผงอาจอยู่ในการ์ดที่ overflow ตัดขอบ
      และต้องพลิกขึ้นบนเมื่อที่ด้านล่างไม่พอ (วิธีเดียวกับเมนูประจำแถวของตาราง) */
.media-picker-panel.is-floating { position: fixed; right: auto; }

.media-picker-results {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.media-picker-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    cursor: pointer;
    min-height: 48px;
}

.media-picker-item:hover,
.media-picker-item.is-active { background: var(--color-surface-muted); }

/* ‼️ ตัวที่เลือกอยู่ต้องดูออกโดยไม่พึ่งสีอย่างเดียว จึงมีเครื่องหมายถูกกำกับ */
.media-picker-item.is-selected {
    background: var(--color-primary-soft);
    color: var(--color-primary-strong);
    font-weight: var(--font-weight-medium);
}

.media-picker-item-check { flex: none; width: var(--font-size-sm); height: var(--font-size-sm); opacity: 0; }
.media-picker-item.is-selected .media-picker-item-check { opacity: 1; }

.media-picker-item-thumb {
    flex: none;
    width: 36px;
    height: 36px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    background: var(--color-surface-muted);
}

.media-picker-item-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.media-picker-item-label { font-size: var(--font-size-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.media-picker-item-hint { font-size: var(--font-size-xs); color: var(--color-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.media-picker-item mark {
    background: transparent;
    color: inherit;
    font-weight: var(--font-weight-bold);
    text-decoration: underline;
}

/* ------------------------------------------------------- สถานะของเครือข่าย */
.media-picker-status {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding: var(--space-4) var(--space-3);
    text-align: center;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.media-picker-status.is-error { color: var(--color-danger); }
.media-picker-status[hidden] { display: none; }

.media-picker-more { flex: none; }

@media (max-width: 640px) {
    /* ‼️ บนมือถือแผงต้องไม่ล้นจอ และแต่ละแถวใหญ่พอให้กดด้วยนิ้ว */
    .media-picker-panel { max-height: min(60dvh, 380px); }
    .media-picker-item { min-height: 56px; }
}

/* ------------------------------------------ แถบรายละเอียดของงานตามเวลา
   ‼️ อยู่ในตารางเดียวกับแถวของงาน จึงต้องแยกออกจากแถวปกติด้วยพื้นหลัง
      ไม่ใช่ด้วยเส้นขอบเพิ่ม — ตารางนี้มีเส้นแบ่งแถวอยู่แล้ว การเพิ่มเส้นทำให้อ่านยากขึ้น */
.cron-toggle-col { width: var(--height-button); }

.cron-toggle .icon { transition: transform var(--transition-base); }
.cron-toggle.is-open .icon { transform: rotate(90deg); }

.cron-detail-row > td {
    background: var(--color-surface-muted);
    padding: var(--space-4);
}

.cron-panel {
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    padding: var(--space-3);
    min-width: 0;
}

.cron-panel-title {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-bold);
    margin: 0 0 var(--space-2);
}

/* คำอธิบายว่างานนี้ทำอะไร — อยู่เหนือแผงตัวเลข เพราะต้องอ่านก่อนจะเข้าใจตัวเลขข้างล่าง
   ‼️ จำกัดความกว้างไว้ ข้อความยาวเต็มจอกว้างอ่านยากกว่าที่คิด ตาต้องกวาดกลับไกลเกินไป */
.cron-about {
    max-width: 78ch;
    margin: 0 0 var(--space-3);
}

.cron-rate { margin-top: var(--space-3); display: flex; flex-direction: column; gap: var(--space-1); }

.cron-recent { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }

.cron-recent li {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    justify-content: space-between;
    flex-wrap: wrap;
}

/* ‼️ ผลลัพธ์ของงานเป็นข้อความยาวคำเดียวได้ (เช่น key=value ต่อกันรัว ๆ)
      ต้องบังคับตัดคำ ไม่งั้นการ์ดจะยืดจนดันการ์ดใบอื่นเสียทรง */
.cron-output {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-xs);
    margin: 0;
    overflow-wrap: anywhere;
}

.cron-output.is-error { color: var(--color-danger); }

.cron-panel-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-4);
}

.cron-panel-footer-end { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

.cron-schedule-form { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

/* ‼️ ช่อง cron ยาวแค่ห้าช่อง ไม่ต้องกินความกว้างทั้งแถว
      ถ้าปล่อยให้ยืดเต็ม ปุ่มบันทึกจะถูกดันตกบรรทัดบนจอแคบโดยไม่จำเป็น */
.cron-schedule-input { max-width: 220px; font-family: var(--font-family-mono); }

@media (max-width: 640px) {
    .cron-detail-row > td { padding: var(--space-3); }
    .cron-schedule-form { width: 100%; }
    .cron-schedule-input { max-width: none; flex: 1 1 100%; }
}

/* ------------------------------------------------- หน้ารายการเว็บไซต์
   ‼️ แถบสรุปแนวนอนแถวเดียว — เตี้ยกว่าการ์ด KPI สี่ใบ จึงไม่ดันรายการเว็บไซต์ตกใต้พับหน้า
      บนจอแคบจะพับเป็นสองแถวเองโดยไม่ต้องมี media query แยก */
.summary-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-4);
}

.summary-strip-item { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }

.summary-strip-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--space-5);
    height: var(--space-5);
    border-radius: var(--radius-base);
    flex: none;
}

.summary-strip-icon.tint-brand  { background: var(--tint-brand-bg);  color: var(--tint-brand-fg); }
.summary-strip-icon.tint-green  { background: var(--tint-green-bg);  color: var(--tint-green-fg); }
.summary-strip-icon.tint-violet { background: var(--tint-violet-bg); color: var(--tint-violet-fg); }
.summary-strip-icon.tint-blue   { background: var(--tint-blue-bg);   color: var(--tint-blue-fg); }

.summary-strip-text { display: flex; flex-direction: column; min-width: 0; font-size: var(--font-size-sm); }
.summary-strip-value { font-size: var(--font-size-lg); font-weight: var(--font-weight-medium); font-variant-numeric: tabular-nums; }

/* ‼️ ตัวเลขข้างชื่อแท็บต้องอ่านออกโดยไม่ต้องพึ่งสี — ใช้พื้นอ่อนกับตัวอักษรเข้ม */
.subnav-count {
    display: inline-block;
    margin-inline-start: var(--space-1);
    padding: 0 var(--space-1);
    border-radius: var(--radius-sm);
    background: var(--color-surface-muted);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    font-variant-numeric: tabular-nums;
}

.subnav-item.is-active .subnav-count { background: var(--tint-brand-bg); color: var(--tint-brand-fg); }

/* ‼️ สถานะโดเมน/ใบรับรองบนการ์ด — สีสื่อสถานะจริงเท่านั้น ห้ามเอาไปตกแต่ง */
.site-card-states { list-style: none; margin: var(--space-2) 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }

.site-card-state {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    min-width: 0;
}

.site-card-state .icon { width: var(--font-size-sm); height: var(--font-size-sm); flex: none; }
.site-card-state.is-ready .icon   { color: var(--color-success); }
.site-card-state.is-warning .icon { color: var(--color-warning); }
.site-card-state.is-danger .icon  { color: var(--color-danger); }
.site-card-state.is-muted .icon   { color: var(--color-text-muted); }

/* ‼️ เว็บเดียวต้องไม่ได้การ์ดผอมลอยมุมซ้าย และต้องไม่ยืดเต็มจอจนภาพย่อบิด
      จำกัดความกว้างของคอลัมน์แทน — 1, 2 และ 3+ เว็บจึงได้สัดส่วนเดียวกัน */
.site-card-grid.is-single { grid-template-columns: minmax(0, 420px); }

.help-strip {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    flex-wrap: wrap;
}

.help-strip-icon { display: inline-flex; color: var(--color-text-muted); flex: none; }
.help-strip-text { flex: 1 1 240px; min-width: 0; font-size: var(--font-size-sm); }

@media (max-width: 640px) {
    .summary-strip { gap: var(--space-3); }
    .help-strip .btn { flex: 1 1 100%; justify-content: center; }
}

/* ------------------------------------------------------------------ ลิ้นชัก
   ‼️ เปิด/ปิดด้วย URL ไม่ใช่ JavaScript (ดูเหตุผลที่ partials/drawer.php)
      CSS ที่นี่จึงไม่มี state ใดๆ ให้ต้องซิงก์กับสคริปต์ */
.drawer-layer { position: fixed; inset: 0; z-index: 60; display: flex; justify-content: flex-end; }

.drawer-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    display: block;
}

.drawer {
    position: relative;
    width: min(420px, 100%);
    max-width: 100%;
    background: var(--color-surface);
    border-inline-start: var(--border-width) solid var(--color-border);
    box-shadow: var(--shadow-lg, 0 10px 40px rgba(0, 0, 0, 0.15));
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-bottom: var(--border-width) solid var(--color-border);
}

.drawer-body { padding: var(--space-4); overflow-y: auto; }

.drawer-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }

.drawer-list-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2);
    border-radius: var(--radius-base);
    background: var(--color-surface-muted);
    min-width: 0;
}

/* ‼️ จอแคบให้เต็มความกว้าง — ลิ้นชักผอมบนมือถืออ่านยากกว่าหน้าเต็ม */
@media (max-width: 640px) {
    .drawer { width: 100%; border-inline-start: 0; }
}

/* --------------------------------------------------- แถวที่มีภาพย่อในตาราง */
.row-media { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }

.row-thumb {
    width: 64px;
    height: 44px;
    border-radius: var(--radius-base);
    background: var(--color-surface-muted);
    border: var(--border-width) solid var(--color-border);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--color-border-strong);
    overflow: hidden;
    flex: none;
}

.row-thumb img { width: 100%; height: 100%; object-fit: cover; }
.row-media-text { display: flex; flex-direction: column; min-width: 0; }
.row-actions { display: flex; align-items: center; gap: var(--space-1); justify-content: flex-end; }

/* ‼️ การ์ด KPI ที่กดกรองได้ — ต้องดูออกว่ากดได้ และต้องรู้ว่ากำลังเลือกอันไหนอยู่
      ตัวที่เลือกใช้ขอบสีแบรนด์ ไม่ใช่พื้นสีแบรนด์ เพราะพื้นสีเข้มทำให้ตัวเลขอ่านยากลง */
.kpi.is-link { text-decoration: none; color: inherit; transition: border-color .12s ease, background-color .12s ease; }
.kpi.is-link:hover { border-color: var(--color-border-strong); }
.kpi.is-active { border-color: var(--color-primary); box-shadow: inset 0 0 0 1px var(--color-primary); }

/* ==========================================================================
   ตัวช่วยสร้างเว็บไซต์ 3 ขั้น (/websites/create)

   ‼️ ไม่มี <style> ในหน้าและไม่มีไฟล์ CSS แยก — ทุกอย่างอยู่ที่นี่ (กฎเหล็กข้อ 8)
   ‼️ ทุกสีมาจาก token ชุดเดียวกับทั้งระบบ โหมดมืดจึงทำงานเองโดยไม่ต้องเขียนกฎซ้ำ
   ========================================================================== */

/* ------------------------------------------------------- แถบขั้นตอน 3 ขั้น */

.wizard-steps {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
}

.wizard-step {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    flex: none;
}

/* ‼️ เส้นเชื่อมระหว่างขั้นวาดด้วย ::after ของขั้นที่ไม่ใช่ขั้นสุดท้าย
      ไม่ได้ใช้ element แยกเหมือนของเดิม เพราะ element เปล่าใน <ol> ทำให้โครงสร้าง
      ที่โปรแกรมอ่านหน้าจอได้ยินมีรายการเกินมาโดยไม่มีความหมาย */
.wizard-step:not(:last-child) { flex: 1 1 auto; }

.wizard-step:not(:last-child)::after {
    content: "";
    flex: 1 1 var(--space-6);
    height: var(--border-width);
    background: var(--color-border);
    margin-left: var(--space-2);
}

.wizard-step-mark {
    width: var(--space-5);
    height: var(--space-5);
    border-radius: var(--radius-pill);
    background: var(--color-neutral-soft);
    color: var(--color-text-muted-on-soft);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: var(--font-weight-medium);
    flex: none;
}

.wizard-step-mark .icon { width: 16px; height: 16px; }

.wizard-step-label { white-space: nowrap; }

.wizard-step.is-active { color: var(--color-text); font-weight: var(--font-weight-medium); }
.wizard-step.is-active .wizard-step-mark { background: var(--btn-primary-bg); color: var(--btn-primary-fg); }

.wizard-step.is-done .wizard-step-mark { background: var(--color-success-soft); color: var(--color-success); }
.wizard-step.is-done:not(:last-child)::after { background: var(--color-border-strong); }

/* -------------------------------------------------------------- โครงหน้า */

.wizard-card { overflow: hidden; }

/* ‼️ ฝั่งซ้ายเป็นฟอร์ม ฝั่งขวาเป็นตัวอย่าง — สัดส่วนคงที่เพื่อให้กรอบตัวอย่าง
      กว้างพอที่จะอ่านออกว่าเป็นเว็บอะไร ไม่ใช่ภาพจิ๋วที่ดูไม่รู้เรื่อง */
.wizard-split {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
}

.wizard-split-review { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }

.wizard-panel { padding: var(--space-4); min-width: 0; }

.wizard-panel-preview,
.wizard-panel-side {
    background: var(--color-surface-muted);
    border-left: var(--border-width) solid var(--color-border);
}

.wizard-panel-title {
    font-size: var(--font-size-lg);
    margin: 0;
}

.wizard-preview-caption {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.wizard-side-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
}

.wizard-side-header h3 { font-size: var(--font-size-base); }

/* ------------------------------------------------------- แถบปุ่มท้ายหน้า */

.wizard-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin-top: var(--space-4);
    padding: var(--space-3) var(--space-4);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
}

.wizard-footer-note {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    min-width: 0;
}

.wizard-footer-note .icon { flex: none; }

.wizard-footer-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-left: auto;
}

.wizard-footer-create {
    flex-direction: column;
    align-items: flex-end;
    gap: var(--space-1);
}

/* ‼️ แถบยืนยันของขั้น "เลือกหน้าตา" เกาะขอบล่างจอ — รายการแม่แบบยาวกว่าหนึ่งจอเสมอ
      ของเดิมต้องเลื่อนลงไปสุดถึงจะรู้ว่าเลือกอะไรไว้และกดต่อยังไง
   ‼️ ใช้ sticky ไม่ใช่ fixed จะได้กว้างเท่าเนื้อหาเอง ไม่ต้องรู้ความกว้างของแถบเมนู
      (แนวทางเดียวกับ .form-actionbar ของหน้าสินค้า) */
.wizard-actionbar {
    position: sticky;
    bottom: 0;
    /* ‼️ ต้องอยู่เหนือปุ่มลอย "แจ้งปัญหา" (z-index 70) ไม่งั้นปุ่มนั้นจะทับปุ่ม "ถัดไป" ที่มุมขวาล่าง */
    z-index: 75;
    box-shadow: var(--shadow-pop);
}

.wizard-actionbar-status {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
    font-size: var(--font-size-sm);
    color: var(--color-text);
}

/* ‼️ ชื่อแม่แบบยาวได้ไม่จำกัด บนจอแคบต้องย่อด้วยจุดไข่ปลา ไม่ใช่ดันปุ่ม "ถัดไป" ตกขอบ */
.wizard-actionbar-status span:not(.wizard-actionbar-mark) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ‼️ ชิปนี้บอก "สถานะสำเร็จ" จริง จึงใช้โทนเขียวได้ตาม design.md ข้อ 5.3
      คู่สีมาจาก --tint-green-* ซึ่งผ่าน AA ทั้งโหมดสว่างและมืด */
.wizard-actionbar-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: var(--space-5);
    height: var(--space-5);
    border-radius: var(--radius-pill);
    background: var(--tint-green-bg);
    color: var(--tint-green-fg);
}

.wizard-actionbar-mark .icon { width: 18px; height: 18px; }

/* ‼️ ยกปุ่มลอยขึ้นพ้นแถบยืนยัน เพื่อให้ยังกด "แจ้งปัญหา" ได้ในหน้าที่มีแถบนี้ */
body:has(.wizard-actionbar) .support-fab { bottom: calc(var(--space-6) + var(--space-5)); }

/* --------------------------------------------- ตัวกรองแม่แบบ (ปุ่มเม็ดยา) */

.wizard-filters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.wizard-filter {
    display: inline-flex;
    align-items: center;
    min-height: var(--height-button);
    padding: 0 var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: var(--font-size-sm);
    text-decoration: none;
    transition: border-color var(--transition-base), background var(--transition-base);
}

.wizard-filter:hover { border-color: var(--color-primary); text-decoration: none; }

.wizard-filter.is-active {
    background: var(--btn-primary-bg);
    border-color: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    font-weight: var(--font-weight-medium);
}

/* --------------------------------------------------------- การ์ดแม่แบบ */

.template-picker {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: var(--space-4);
    /* ‼️ เว้นที่ให้แถวสุดท้ายพ้นแถบยืนยันที่เกาะขอบล่างจอ ไม่งั้นการ์ดใบท้ายถูกบังตลอด */
    padding-bottom: var(--space-5);
}

.template-option {
    position: relative;
    display: flex;
    flex-direction: column;
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    overflow: hidden;
    transition: border-color var(--transition-base), box-shadow var(--transition-base), background var(--transition-base);
}

.template-option:hover { border-color: var(--color-primary-border); }

/* ‼️ สถานะ "เลือกแล้ว" ต้องต่างจากการ์ดปกติหลายทางพร้อมกัน ของเดิมต่างแค่สีเส้นขอบ
      ผู้ใช้กดแล้วยังไม่แน่ใจว่าเลือกติดหรือยัง (เจ้าของระบบแจ้งเอง 2026-08-30)
   ‼️ วงในวาดด้วย box-shadow แบบ inset ไม่ใช่ border-width: 2px
      เพราะการเปลี่ยนความหนาเส้นขอบทำให้การ์ดขยับ 1px ทุกครั้งที่กดเลือก
   ‼️ .is-selected มาจากเซิร์ฟเวอร์และจาก JavaScript ส่วน :has() คือด่านสำรองตอนปิด JavaScript
      ต้องห่อด้วย :is() เพราะเบราว์เซอร์ที่ไม่รู้จัก :has() จะทิ้งทั้งกฎถ้าเขียนคั่นด้วยจุลภาคเฉย ๆ */
.template-option:is(.is-selected, :has(.template-option-input:checked)) {
    border-color: var(--color-primary);
    background: var(--color-primary-soft);
    box-shadow: inset 0 0 0 2px var(--color-primary), 0 0 0 4px var(--color-primary-soft);
}

/* ‼️ radio ตัวจริงที่ยังโฟกัสได้ ห้าม display:none — ไม่งั้น Tab และปุ่มลูกศรใช้ไม่ได้ทั้งกลุ่ม */
.template-option-input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
    pointer-events: none;
}

/* ‼️ ป้ายกำกับครอบแค่ภาพกับชื่อ ปุ่ม "ดูตัวอย่างเต็มหน้า" อยู่นอกป้าย
      ถ้าครอบทั้งใบ การกดลิงก์จะไปสลับตัวเลือกด้วยทุกครั้ง */
.template-option-choice {
    position: relative;
    display: block;
    cursor: pointer;
}

/* ‼️ วงโฟกัสของการ์ด — radio ถูกซ่อนไว้ คนที่เดินด้วยคีย์บอร์ดจึงมองไม่เห็นเลย
      ว่าตอนนี้อยู่การ์ดใบไหน (WCAG 2.4.7 ไม่ผ่าน · ยืนยันด้วยการวัดจริง 2026-08-30) */
.template-option:has(input:focus-visible) {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

/* ป้าย "เลือกแล้ว" มุมบนซ้าย — เป็นข้อความจริง ไม่ใช่บอกสถานะด้วยสีอย่างเดียว (WCAG 1.4.1) */
.template-option-flag {
    position: absolute;
    top: var(--space-2);
    left: var(--space-2);
    z-index: 2;
    display: none;
    align-items: center;
    gap: var(--space-1);
    height: var(--height-control-sm);
    padding: 0 var(--space-3) 0 var(--space-2);
    border-radius: var(--radius-pill);
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
}

.template-option-flag .icon { width: 16px; height: 16px; }

.template-option-media { position: relative; display: block; }

/* เครื่องหมายถูกในวงกลม มุมบนขวาของภาพตัวอย่าง */
.template-option-check {
    position: absolute;
    top: var(--space-2);
    right: var(--space-2);
    z-index: 2;
    display: none;
    align-items: center;
    justify-content: center;
    width: var(--space-5);
    height: var(--space-5);
    border-radius: var(--radius-pill);
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    box-shadow: var(--shadow-base);
}

.template-option-check .icon { width: 18px; height: 18px; }

.template-option:is(.is-selected, :has(.template-option-input:checked)) .template-option-flag,
.template-option:is(.is-selected, :has(.template-option-input:checked)) .template-option-check {
    display: inline-flex;
}

.template-option-name {
    display: block;
    padding: var(--space-3) var(--space-3) 0;
    font-weight: var(--font-weight-medium);
}

/* ‼️ สองปุ่มกว้างเท่ากัน — ของเดิมมีแต่ปุ่ม "ดูตัวอย่างเต็มหน้า"
      การ์ดที่ยังไม่ถูกเลือกจึงไม่มีปุ่มให้กดเลือกเลยสักใบ ต้องเดาเอาว่าให้กดที่รูป */
.template-option-actions {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-2);
    padding: var(--space-3);
    margin-top: auto;
}

.template-option-actions .btn { width: 100%; }

/* ปุ่มเลือกเป็น <label> ไม่ใช่ <button> จึงต้องบอกเองว่ากดได้ */
.template-option-pick { cursor: pointer; }

.template-option-pick-on { display: none; align-items: center; gap: var(--space-2); }
.template-option-pick-on .icon { width: var(--icon-size); height: var(--icon-size); }

.template-option:is(.is-selected, :has(.template-option-input:checked)) .template-option-pick {
    background: var(--btn-primary-bg);
    border-color: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
}

.template-option:is(.is-selected, :has(.template-option-input:checked)) .template-option-pick-on { display: inline-flex; }
.template-option:is(.is-selected, :has(.template-option-input:checked)) .template-option-pick-off { display: none; }

/* ‼️ วงโฟกัสของ .choice เดิมด้วย — ใช้ร่วมกันทั้งระบบ ไม่ใช่เฉพาะหน้านี้
      ของเดิม radio ถูกซ่อนสนิทและไม่มีกฎ focus ที่ไหนเลย คนที่เดินด้วยคีย์บอร์ด
      จึงไม่เห็นว่าอยู่การ์ดใบไหนตลอดทุกหน้าที่ใช้ .choice */
.choice:has(input:focus-visible) {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

/* ------------------------------------------ กรอบเบราว์เซอร์ + หน้าตัวอย่าง */

.browser-frame {
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
}

.browser-frame-bar {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    height: var(--space-5);
    padding: 0 var(--space-3);
    background: var(--color-surface-muted);
    border-bottom: var(--border-width) solid var(--color-border);
}

.browser-frame-dots { display: flex; gap: 5px; flex: none; }

.browser-frame-dots > span {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-pill);
    background: var(--color-border-strong);
}

.browser-frame-address {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    flex: 1 1 auto;
    min-width: 0;
    height: 18px;
    padding: 0 var(--space-2);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

.browser-frame-address .icon-xs { width: 12px; height: 12px; flex: none; }

/*  ‼️ หน้าตัวอย่างถูก render ที่ความกว้างเดสก์ท็อปคงที่แล้วย่อลงให้พอดีกรอบ
       ถ้าปล่อยให้ iframe กว้างเท่ากรอบจริง เว็บลูกค้าจะสลับไป layout แท็บเล็ต
       ซึ่งไม่ใช่สิ่งที่ผู้ใช้กำลังจะได้
    ‼️ --preview-scale ตั้งค่าตั้งต้นไว้ให้พอดีกับความกว้างที่พบบ่อยที่สุด
       แล้ว app.js คำนวณค่าจริงทับให้อีกที — ปิด JavaScript แล้วยังเห็นหน้าตัวอย่างครบ */
.browser-frame-body {
    --preview-width: 1280px;
    --preview-height: 900px;
    --preview-scale: .55;

    position: relative;
    overflow: hidden;
    background: var(--color-surface-muted);
    height: calc(var(--preview-height) * var(--preview-scale));
}

.browser-frame-view {
    position: absolute;
    top: 0;
    left: 0;
    width: var(--preview-width);
    height: var(--preview-height);
    border: 0;
    transform: scale(var(--preview-scale));
    transform-origin: top left;
}

.browser-frame-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: var(--space-4);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    text-align: center;
}

/* ------------------------------------------------- สลับเดสก์ท็อป / มือถือ */

.preview-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.preview-devices {
    display: inline-flex;
    padding: var(--space-1);
    gap: var(--space-1);
    background: var(--color-neutral-soft);
    border-radius: var(--radius-base);
}

.preview-device {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    min-height: var(--space-5);
    padding: 0 var(--space-3);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted-on-soft);
    cursor: pointer;
}

.preview-device input { position: absolute; opacity: 0; pointer-events: none; }

.preview-device:has(input:checked) {
    background: var(--color-surface);
    color: var(--color-text);
    font-weight: var(--font-weight-medium);
    box-shadow: var(--shadow-sm);
}

.preview-device:has(input:focus-visible) {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

/* ‼️ สลับด้วย CSS ล้วน หน้าตัวอย่างจึงไม่ถูกโหลดใหม่ตอนกดสลับ
      และค่าที่เลือกไม่ถูกส่งไปฝั่งเซิร์ฟเวอร์ เพราะเป็นเรื่องการแสดงผลล้วน */
.wizard-panel:has(.preview-device input[value="mobile"]:checked) .browser-frame {
    max-width: 390px;
    margin-inline: auto;
}

.wizard-panel:has(.preview-device input[value="mobile"]:checked) .browser-frame-body {
    --preview-width: 390px;
    --preview-height: 780px;
    --preview-scale: 1;
    height: var(--preview-height);
}

/* ------------------------------------------------------ สรุปก่อนกดสร้าง */

.wizard-summary {
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    gap: var(--space-2) var(--space-3);
    margin: 0;
    font-size: var(--font-size-sm);
}

.wizard-summary dt {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-text-muted);
    font-weight: var(--font-weight-normal);
}

.wizard-summary dt .icon { flex: none; width: 16px; height: 16px; }

.wizard-summary dd {
    margin: 0;
    text-align: right;
    font-weight: var(--font-weight-medium);
    overflow-wrap: anywhere;
}

.wizard-summary-color {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    font-family: var(--font-family-mono);
}

.wizard-swatch {
    width: 16px;
    height: 16px;
    border-radius: var(--radius-sm);
    background: var(--swatch, var(--color-border));
    border: var(--border-width) solid var(--color-border-strong);
    flex: none;
}

/* ------------------------------------------------------------- จอแคบลง */

@media (max-width: 1024px) {
    .wizard-split,
    .wizard-split-review { grid-template-columns: minmax(0, 1fr); }

    .wizard-panel-preview,
    .wizard-panel-side {
        border-left: 0;
        border-top: var(--border-width) solid var(--color-border);
    }
}

@media (max-width: 768px) {
    /* ‼️ บนจอแคบ ป้ายชื่อขั้นกินที่จนแถบล้นขอบ — เหลือไว้เฉพาะขั้นที่กำลังทำอยู่
          ตัวเลขของขั้นอื่นยังอยู่ครบ ผู้ใช้จึงยังเห็นว่าทั้งหมดมีกี่ขั้น */
    .wizard-step:not(.is-active) .wizard-step-label { display: none; }

    .wizard-footer { flex-direction: column; align-items: stretch; }
    .wizard-footer-actions { margin-left: 0; }
    .wizard-footer-actions .btn { flex: 1 1 auto; justify-content: center; }
    .wizard-footer-create { align-items: stretch; }

    /* ‼️ แถบยืนยันบนจอแคบ: ข้อความย่อได้ แต่ปุ่ม "ถัดไป" ต้องอยู่ในสายตาเสมอ */
    .wizard-actionbar { padding: var(--space-3); }

    .template-picker { grid-template-columns: minmax(0, 1fr); }

    /* ‼️ ปุ่มสองใบเรียงกันบนการ์ดกว้าง ~330px แล้วข้อความไทยยาวกว่าช่อง ปุ่มจึงล้นออกนอกการ์ด
          จอแคบให้เรียงลงมาแทน กดง่ายกว่าและไม่มีอะไรถูกตัด */
    .template-option-actions { grid-template-columns: minmax(0, 1fr); }

    .wizard-summary { grid-template-columns: minmax(0, 1fr); gap: var(--space-1) 0; }
    .wizard-summary dd { text-align: left; margin-bottom: var(--space-2); }
    .wizard-summary-color { justify-content: flex-start; }
}

/* ==========================================================================
   เติม OMC Token (/tokens/top-up)

   ‼️ ยอดชำระคือตัวเลขที่เด่นที่สุดของหน้า — เป็นตัวเลขเดียวที่ลูกค้าเอาไปโอนจริง
   ‼️ ไม่มีสีของโบนัสหรือส่วนลด เพราะระบบไม่มีสองอย่างนั้น
   ========================================================================== */

.topup {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: var(--space-4);
    align-items: start;
}

.topup-main { min-width: 0; }

/* ‼️ สรุปรายการติดขอบบนตอนเลื่อน — ยอดชำระต้องอยู่ในสายตาตลอดที่กำลังเลือกจำนวน */
.topup-summary { position: sticky; top: var(--space-4); }

/* ------------------------------------------------------------ ยอดคงเหลือ

   ‼️ อยู่ในช่อง actions ของหัวหน้าจอ ระดับเดียวกับชื่อหน้า ไม่ใช่การ์ดเต็มความกว้าง
      ยอดคงเหลือเป็นข้อมูลประกอบการตัดสินใจ ไม่ใช่เนื้อหาหลักของหน้า */

.topup-balance {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

.topup-balance-body { display: flex; flex-direction: column; gap: 2px; }

.topup-balance-label { font-size: var(--font-size-sm); color: var(--color-text-muted); }

.topup-balance-icon {
    width: var(--size-strip-icon);
    height: var(--size-strip-icon);
    border-radius: var(--radius-base);
    background: var(--tint-brand-bg);
    color: var(--tint-brand-fg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.topup-balance-value {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
}

.topup-balance-value span {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-normal);
    color: var(--color-text-muted);
    margin-left: var(--space-1);
}

/* --------------------------------------------------------- การ์ดแพ็ก Token */

.topup-packs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
    gap: var(--space-3);
}

.topup-pack {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    color: var(--color-text);
    text-align: center;
    text-decoration: none;
    transition: border-color var(--transition-base), background var(--transition-base);
}

.topup-pack:hover { border-color: var(--color-primary); text-decoration: none; }

.topup-pack:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

.topup-pack.is-active {
    border-color: var(--color-primary);
    background: var(--color-primary-soft);
}

.topup-pack-check {
    position: absolute;
    top: calc(var(--space-2) * -1);
    right: calc(var(--space-2) * -1);
    width: var(--space-4);
    height: var(--space-4);
    border-radius: var(--radius-pill);
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.topup-pack-check .icon { width: 14px; height: 14px; }

.topup-pack-icon { color: var(--color-primary); }

.topup-pack-amount {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
}

/* ‼️ หน่วยขึ้นบรรทัดใหม่บนการ์ดแคบ ตัวเลขจึงไม่ถูกบีบจนอ่านยาก */
.topup-pack-amount span {
    display: block;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
}

.topup-pack-price {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.topup-pack.is-active .topup-pack-price { color: var(--color-primary-strong); }

/* --------------------------------------------------------- ระบุจำนวนเอง */

.topup-custom {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
}

.topup-custom .field { flex: 1 1 auto; min-width: 0; margin: 0; }

/* ‼️ ปุ่มคำนวณใหม่ต้องอยู่ระดับเดียวกับกรอบ ไม่ใช่ระดับ label */
.topup-custom > .btn { margin-top: calc(var(--space-4) + var(--space-1)); flex: none; }

/* ------------------------------------------------------- ช่องทางชำระเงิน */

.topup-method {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    background: var(--color-surface-muted);
}

.topup-method-icon {
    width: var(--size-strip-icon);
    height: var(--size-strip-icon);
    border-radius: var(--radius-base);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    color: var(--color-text-muted);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.topup-method-title { font-weight: var(--font-weight-medium); }

/* ---------------------------------------------------------- สรุปรายการ */

.topup-lines {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-2) var(--space-3);
    margin: 0;
    font-size: var(--font-size-sm);
}

.topup-lines dt { color: var(--color-text-muted); font-weight: var(--font-weight-normal); }
.topup-lines dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }

.topup-total {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2);
    padding-top: var(--space-3);
    border-top: var(--border-width) solid var(--color-border);
}

.topup-total-label { font-size: var(--font-size-sm); color: var(--color-text-muted); }

/* ‼️ ตัวเลขที่ใหญ่ที่สุดของหน้า — ลูกค้าต้องอ่านเจอโดยไม่ต้องหา */
.topup-total-value {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    color: var(--color-primary-strong);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.topup-note {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

.topup-note .icon { flex: none; width: 16px; height: 16px; }

/* --------------------------------------------------- ขั้นตอนการเติม 3 ขั้น */

.topup-flow {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-4);
    list-style: none;
    margin: 0;
    padding: 0;
    counter-reset: topup-flow;
}

.topup-flow-step {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    min-width: 0;
}

.topup-flow-icon {
    width: var(--size-strip-icon);
    height: var(--size-strip-icon);
    border-radius: var(--radius-pill);
    background: var(--tint-brand-bg);
    color: var(--tint-brand-fg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.topup-flow-body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }

.topup-flow-title {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    font-weight: var(--font-weight-medium);
}

.topup-flow-number { color: var(--color-primary-strong); }

.topup-flow-hint { font-size: var(--font-size-sm); color: var(--color-text-muted); }

/* ------------------------------------------------------------- จอแคบลง */

@media (max-width: 1024px) {
    /* ‼️ บนจอแคบ สรุปรายการและปุ่มยืนยันต้องอยู่ "หลัง" ส่วนเลือกจำนวน
          ผู้ใช้ต้องเลือกก่อนแล้วค่อยเห็นยอด ไม่ใช่เห็นยอดของค่าที่ยังไม่ได้เลือก */
    .topup { grid-template-columns: minmax(0, 1fr); }
    .topup-summary { position: static; }

    .topup-flow { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
}

@media (max-width: 600px) {
    .topup-packs { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* ‼️ ปุ่มคำนวณใหม่ลงมาอยู่ใต้ช่อง ไม่งั้นช่องกรอกจะแคบจนพิมพ์เลขสี่หลักแล้วอ่านไม่ออก */
    .topup-custom { flex-direction: column; align-items: stretch; }
    .topup-custom > .btn { margin-top: 0; }
}

/* ==========================================================================
   กระเป๋า OMC Token (/tokens)

   ‼️ สามถังต้องแยกกันให้เห็น ห้ามยุบเป็นยอดเดียว — ยอดพร้อมใช้กว้างกว่าอีกสองใบ
      เพราะเป็นยอดเดียวที่ตอบคำถาม "ตอนนี้ซื้อของได้ไหม"
   ‼️ พื้นการ์ดทุกใบขาวเหมือนกัน ต่างกันแค่โทนของชิปไอคอน (ข้อยกเว้นที่อนุมัติไว้
      ใน CLAUDE.md ข้อ 1.5) ห้ามระบายพื้นการ์ดคนละสี
   ========================================================================== */

.wallet-buckets {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-3);
}

.wallet-bucket {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-4);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    min-width: 0;
}

.wallet-bucket-main { border-color: var(--color-primary-border); }

.wallet-bucket-icon {
    width: var(--size-strip-icon);
    height: var(--size-strip-icon);
    border-radius: var(--radius-base);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.wallet-bucket-body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }

.wallet-bucket-label { font-size: var(--font-size-sm); color: var(--color-text-muted); }

.wallet-bucket-value {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
}

.wallet-bucket-value span {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-normal);
    color: var(--color-text-muted);
    margin-left: var(--space-2);
}

.wallet-bucket-hint { font-size: var(--font-size-sm); color: var(--color-text-muted); }

.wallet-bucket-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-primary-strong);
    text-decoration: none;
}

.wallet-bucket-link:hover { text-decoration: underline; }
.wallet-bucket-link .icon { width: 16px; height: 16px; }

/* ‼️ อีกสองใบไม่มีลิงก์ จึงให้ตัวเลขเล็กกว่าใบหลักเล็กน้อยเพื่อไม่แย่งสายตา */
.wallet-bucket:not(.wallet-bucket-main) .wallet-bucket-value { font-size: var(--font-size-xl); }

/* ------------------------------------------------- แท็บของประวัติการเคลื่อนไหว */

.wallet-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.wallet-tab {
    display: inline-flex;
    align-items: center;
    min-height: var(--height-button);
    padding: 0 var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: var(--font-size-sm);
    text-decoration: none;
    transition: border-color var(--transition-base), background var(--transition-base);
}

.wallet-tab:hover { border-color: var(--color-primary); text-decoration: none; }

.wallet-tab.is-active {
    background: var(--color-primary-soft);
    border-color: var(--color-primary);
    color: var(--color-primary-strong);
    font-weight: var(--font-weight-medium);
}

/* --------------------------------------------------------- ตัวกรองช่วงวันที่

   ‼️ แท็บกับช่วงวันที่อยู่แถวเดียวกันบนจอกว้าง — ประวัติคือเนื้อหาหลักของการ์ดใบนี้
      ตัวกรองจึงต้องไม่กินความสูงไปสองแถวก่อนที่ผู้ใช้จะได้เห็นข้อมูลสักแถว */

.wallet-toolbar {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.wallet-range {
    display: flex;
    align-items: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.wallet-range .field { margin: 0; flex: 0 1 150px; min-width: 0; }
.wallet-range .field-label { font-size: var(--font-size-xs); }
.wallet-range .input { height: var(--height-button); }

.wallet-range-actions { display: flex; gap: var(--space-2); }

/* -------------------------------------------------------- สรุปการใช้งาน */

.wallet-usage {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-3);
    margin: 0;
    font-size: var(--font-size-sm);
}

.wallet-usage dt {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-text-muted);
    font-weight: var(--font-weight-normal);
}

.wallet-usage dt .icon { flex: none; width: 16px; height: 16px; color: var(--color-text-muted); }

.wallet-usage dd {
    margin: 0;
    text-align: right;
    font-weight: var(--font-weight-medium);
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------- จอแคบลง */

@media (max-width: 1024px) {
    .wallet-buckets { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    /* ‼️ ยอดพร้อมใช้กินเต็มแถวบนแท็บเล็ต ยังคงเป็นตัวที่เด่นที่สุดเหมือนบนเดสก์ท็อป */
    .wallet-bucket-main { grid-column: 1 / -1; }
}

@media (max-width: 600px) {
    /* ‼️ มือถือเรียง พร้อมใช้ -> ถูกจอง -> แถม -> ประวัติ ตามลำดับความสำคัญ */
    .wallet-buckets { grid-template-columns: minmax(0, 1fr); }
    .wallet-bucket-main { grid-column: auto; }

    .wallet-toolbar { flex-direction: column; align-items: stretch; }
    .wallet-range { flex-direction: column; align-items: stretch; }
    .wallet-range .field { flex: 1 1 auto; }
    .wallet-range-actions .btn { flex: 1 1 auto; justify-content: center; }
}

/* ==========================================================================
   ทีมงาน (/team) และแผงเพิ่มสมาชิก

   ‼️ ไม่มีการ์ด "คำเชิญที่รอตอบรับ" เพราะระบบไม่มีระบบคำเชิญ
      สรุปจึงมีสองใบ ไม่ใช่สาม (ดูเหตุผลเต็มที่หัวไฟล์ pages/team/index.php)
   ========================================================================== */

.team-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--space-3);
}

.team-stat {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

.team-stat-icon {
    width: var(--size-strip-icon);
    height: var(--size-strip-icon);
    border-radius: var(--radius-base);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.team-stat-label { font-size: var(--font-size-sm); color: var(--color-text-muted); }

.team-stat-value {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
}

.team-stat-value span {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-normal);
    color: var(--color-text-muted);
    margin-left: var(--space-2);
}

/* ------------------------------------------------------- แถบค้นหาและตัวกรอง */

.team-toolbar {
    display: flex;
    align-items: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.team-toolbar .field { margin: 0; min-width: 0; }
.team-toolbar .field:first-child { flex: 1 1 240px; }
.team-toolbar .field:not(:first-child) { flex: 0 1 170px; }

/* ‼️ ปุ่มต้องอยู่ระดับเดียวกับกรอบ ไม่ใช่ระดับ label */
.team-toolbar-actions { display: flex; gap: var(--space-2); }

/* --------------------------------------------------- สรุปสิทธิ์ในแผงเพิ่มสมาชิก */

.team-role-summary {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-info);
    border-radius: var(--radius-base);
    background: var(--color-info-soft);
}

.team-role-summary-title {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: var(--font-weight-medium);
    color: var(--color-info);
}

.team-role-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    list-style: none;
    margin: 0;
    padding: 0;
}

.team-role-list li { display: flex; flex-direction: column; gap: 2px; }

/* ------------------------------------------------------------- จอแคบลง */

@media (max-width: 600px) {
    .team-toolbar { flex-direction: column; align-items: stretch; }
    .team-toolbar .field,
    .team-toolbar .field:first-child,
    .team-toolbar .field:not(:first-child) { flex: 1 1 auto; }
    .team-toolbar-actions .btn { flex: 1 1 auto; justify-content: center; }
}

/* ------------------------------------------------- ปรับแผงเลื่อน (partials/drawer)

   ‼️ ขอบเขตอยู่ที่ .drawer-layer เท่านั้น ในระบบมี .drawer อีกชุดที่เปิดด้วย JavaScript
      (data-drawer) ซึ่งต้องไม่ถูกกฎชุดนี้แตะ */

.drawer-layer .drawer { width: min(460px, 100%); }

/* ‼️ เนื้อหายืดเต็มที่เหลือ ปุ่มท้ายแผงจึงติดขอบล่างเสมอแม้ฟอร์มสั้น */
.drawer-layer .drawer-body { flex: 1 1 auto; }

/* หัวแผงมีคำอธิบายใต้หัวข้อได้ จึงต้องชิดบน ไม่ใช่กึ่งกลาง */
.drawer-layer .drawer-header { align-items: flex-start; }

@media (max-width: 600px) {
    /* ‼️ มือถือใช้เต็มความกว้าง — แผงแคบบนจอแคบทำให้ฟอร์มกรอกยากโดยไม่ได้อะไรกลับมา */
    .drawer-layer .drawer { width: 100%; }
    .drawer-footer .btn { flex: 1 1 auto; justify-content: center; }
}

/* ‼️ แผงเลื่อนเป็น dialog แบบ modal จึงต้องอยู่เหนือปุ่มลอย "แจ้งปัญหา" (z-index 70)
      ของเดิม .drawer-layer อยู่ที่ 60 ปุ่มลอยจึงทับปุ่มยืนยันท้ายแผงจนกดไม่ได้
      ตั้งเท่ากับ .drawer-backdrop ของแผงอีกชุด (88) เพื่อให้ลำดับชั้นทั้งระบบเป็นชุดเดียวกัน
      ยังต่ำกว่าแถบเมนูมือถือ (95) และ skip-link (100) ซึ่งต้องอยู่เหนือทุกอย่างเสมอ */
.drawer-layer { z-index: 88; }

/* ‼️ ขั้นตอนการเติมเป็นแถวเต็มความกว้างท้ายสุด ไม่ได้อยู่ในคอลัมน์ซ้าย
      เหตุผลอยู่ที่ลำดับบนมือถือ — ถ้าอยู่ในคอลัมน์ซ้าย พอยุบเป็นคอลัมน์เดียว
      การ์ดนี้จะไปคั่นระหว่าง "เลือกจำนวน" กับ "สรุปรายการ" ทำให้ยอดที่ต้องชำระ
      ถูกดันลงไปไกลจากจุดที่ผู้ใช้เพิ่งเลือกจำนวนเสร็จ */
.topup-flow-card { grid-column: 1 / -1; }

/* ==========================================================================
   โดเมน (/domains) และแผงเชื่อมโดเมน

   ‼️ ทุกขั้นของแถบความคืบหน้าอ่านจากคอลัมน์จริง ห้ามติ๊กจากการเดา
      (เหตุผลเต็มอยู่ที่หัวไฟล์ pages/domain/index.php)
   ========================================================================== */

.domain-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--space-3);
}

.domain-stat {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

.domain-stat-icon {
    width: var(--size-strip-icon);
    height: var(--size-strip-icon);
    border-radius: var(--radius-base);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.domain-stat-label { font-size: var(--font-size-sm); color: var(--color-text-muted); }

.domain-stat-value {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
}

/* ------------------------------------------------------------- แท็บกรอง */

.domain-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    border-bottom: var(--border-width) solid var(--color-border);
}

.domain-tab {
    display: inline-flex;
    align-items: center;
    min-height: var(--height-button);
    padding: 0 var(--space-3);
    border-bottom: 2px solid transparent;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    text-decoration: none;
    margin-bottom: calc(var(--border-width) * -1);
}

.domain-tab:hover { color: var(--color-text); text-decoration: none; }

.domain-tab.is-active {
    color: var(--color-primary-strong);
    border-bottom-color: var(--color-primary);
    font-weight: var(--font-weight-medium);
}

/* ---------------------------------------------------------- การ์ดโดเมน */

.domain-item {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

.domain-item-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.domain-item-identity { min-width: 0; }

.domain-item-host {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-medium);
    overflow-wrap: anywhere;
}

.domain-item-note { font-size: var(--font-size-sm); color: var(--color-text-muted); }

.domain-item-badges {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.domain-item-line {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--color-success);
}

.domain-item-line .icon { flex: none; width: 16px; height: 16px; }

.domain-item-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.domain-item-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* ‼️ ป้ายปลอดภัยใช้สีเขียว semantic ได้ เพราะสื่อสถานะจริง ไม่ใช่การตกแต่ง */
.domain-secure {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    min-width: 0;
}

.domain-secure .icon { color: var(--color-success); flex: none; }

.domain-secure-label {
    color: var(--color-success);
    font-weight: var(--font-weight-medium);
}

/* ------------------------------------------------- สี่ขั้นของโดเมนลูกค้า */

.domain-steps {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-2);
    list-style: none;
    margin: 0;
    padding: 0;
}

.domain-step {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    position: relative;
    text-align: center;
    min-width: 0;
}

/* เส้นเชื่อมระหว่างขั้น — วาดจากขั้นที่ไม่ใช่ขั้นสุดท้าย ไม่ต้องมี element เปล่า */
.domain-step:not(:last-child)::after {
    content: "";
    position: absolute;
    top: calc(var(--space-4) / 2);
    left: calc(50% + var(--space-4));
    right: calc(-50% + var(--space-4));
    height: 2px;
    background: var(--color-border);
}

.domain-step.is-done:not(:last-child)::after { background: var(--color-success); }

.domain-step-mark {
    width: var(--space-4);
    height: var(--space-4);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    border: 2px solid var(--color-border);
    color: var(--color-text-muted);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    position: relative;
    z-index: 1;
}

.domain-step-mark .icon { width: 12px; height: 12px; }

.domain-step.is-done .domain-step-mark {
    background: var(--color-success);
    border-color: var(--color-success);
    color: var(--color-text-inverse);
}

.domain-step.is-failed .domain-step-mark {
    background: var(--color-danger);
    border-color: var(--color-danger);
    color: var(--color-text-inverse);
}

.domain-step-label { font-size: var(--font-size-xs); color: var(--color-text-muted); }

.domain-step.is-done .domain-step-label { color: var(--color-text); }

/* ------------------------------------------------ ขั้นตอนในแผงเชื่อมโดเมน */

.domain-drawer-steps {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    list-style: none;
    margin: 0;
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
}

.domain-drawer-step { display: flex; align-items: flex-start; gap: var(--space-3); }

.domain-drawer-step-mark {
    width: var(--space-4);
    height: var(--space-4);
    border-radius: var(--radius-pill);
    background: var(--color-secondary);
    color: var(--color-text-inverse);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    flex: none;
}

.domain-drawer-step-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

/* ------------------------------------------------------------- จอแคบลง */

@media (max-width: 600px) {
    /* ‼️ สี่ขั้นเรียงลงมาบนจอแคบ ป้ายชื่อขั้นจะได้ไม่ถูกบีบจนอ่านไม่ออก */
    .domain-steps { grid-template-columns: minmax(0, 1fr); }
    .domain-step { flex-direction: row; align-items: center; text-align: left; }
    .domain-step:not(:last-child)::after { display: none; }
    .domain-step-label { font-size: var(--font-size-sm); }

    .domain-item-footer { align-items: stretch; }
    .domain-item-actions .btn { flex: 1 1 auto; justify-content: center; }
}

/* ==========================================================================
   คลังรูปภาพ (/media) — แถบเครื่องมือ มุมมองรายการ และแผงอัปโหลด

   ‼️ .media-grid / .media-item / .media-thumb / .media-meta มีอยู่แล้วด้านบน
      ที่นี่เพิ่มเฉพาะของใหม่ และ "มุมมองรายการ" ที่ใช้ markup ชุดเดียวกับตาราง
   ========================================================================== */

.media-storage {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

.media-storage-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2);
}

/* ------------------------------------------------------------ แถบเครื่องมือ */

.media-toolbar {
    display: flex;
    align-items: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.media-toolbar .field { margin: 0; min-width: 0; }
.media-toolbar .field:first-of-type { flex: 1 1 240px; }
.media-toolbar .field:not(:first-of-type) { flex: 0 1 170px; }

.media-toolbar-tail {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-left: auto;
}

.media-views {
    display: inline-flex;
    padding: var(--space-1);
    gap: var(--space-1);
    background: var(--color-neutral-soft);
    border-radius: var(--radius-base);
}

.media-view {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--space-5);
    height: var(--space-5);
    border-radius: var(--radius-sm);
    color: var(--color-text-muted-on-soft);
    text-decoration: none;
}

.media-view:hover { color: var(--color-text); text-decoration: none; }

.media-view.is-active {
    background: var(--color-surface);
    color: var(--color-primary-strong);
    box-shadow: var(--shadow-sm);
}

.media-view:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* ------------------------------------------------------- มุมมองรายการ

   ‼️ ใช้ markup ชุดเดียวกับมุมมองตาราง ต่างกันแค่การจัดวาง
      ไม่มีเทมเพลตสองชุดให้เพี้ยนจากกัน */

.media-list { display: flex; flex-direction: column; gap: var(--space-2); }

.media-list .media-item { flex-direction: row; align-items: center; }

.media-list .media-thumb {
    width: 96px;
    flex: none;
    aspect-ratio: 4 / 3;
}

.media-list .media-meta { flex: 1 1 auto; min-width: 0; }

/* ‼️ ในมุมมองรายการ ฟอร์มแก้คำอธิบายวางแนวนอนเพื่อไม่ให้แถวสูงเกินจำเป็น */
.media-list .media-meta form { flex-direction: row; align-items: center; }
.media-list .media-meta form .input { flex: 1 1 auto; }
.media-list .media-meta form .btn { flex: none; width: auto; }

/* -------------------------------------------------- เมนูสามจุดบนการ์ดรูป */

.media-item { position: relative; }

.media-item-menu {
    position: absolute;
    top: var(--space-2);
    right: var(--space-2);
}

/* ‼️ พื้นทึบเล็กน้อยเพื่อให้ปุ่มอ่านออกบนรูปที่สว่างจัด */
.media-item-menu .row-menu-trigger {
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    box-shadow: var(--shadow-sm);
}

.media-list .media-item-menu { position: static; margin-inline-end: var(--space-3); }

/* --------------------------------------------- ประโยชน์ใน empty state */

.media-benefits {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-4);
    list-style: none;
    margin: 0;
    padding: 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.media-benefits li { display: inline-flex; align-items: center; gap: var(--space-2); }
.media-benefits .icon { color: var(--color-primary); }

/* ------------------------------------------------ ข้อเท็จจริงในแผงอัปโหลด */

.media-facts {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    list-style: none;
    margin: 0;
    padding: 0;
}

.media-facts li {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    background: var(--color-surface-muted);
    font-size: var(--font-size-sm);
}

.media-facts .icon { color: var(--color-text-muted); flex: none; }

/* ------------------------------------------------------------- จอแคบลง */

@media (max-width: 768px) {
    .media-toolbar { flex-direction: column; align-items: stretch; }
    .media-toolbar .field,
    .media-toolbar .field:first-of-type,
    .media-toolbar .field:not(:first-of-type) { flex: 1 1 auto; }
    .media-toolbar-tail { margin-left: 0; justify-content: space-between; }

    /* ‼️ มุมมองรายการบนจอแคบกลับไปเรียงบนล่าง รูป 96px + ฟอร์มแนวนอนแคบเกินจะพิมพ์ได้ */
    .media-list .media-item { flex-direction: column; align-items: stretch; }
    .media-list .media-thumb { width: 100%; }
    .media-list .media-meta form { flex-direction: column; align-items: stretch; }
    .media-list .media-item-menu { position: absolute; margin-inline-end: 0; }
}

/* ==========================================================================
   รายการสินค้า/บริการ (/products) และแผงจัดการหมวดหมู่

   ‼️ หน้ารายการใช้พื้นที่เต็มความกว้าง — ฟอร์มหมวดหมู่ย้ายไปอยู่ในแผงเลื่อนแล้ว
   ========================================================================== */

.product-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--space-3);
}

.product-stat {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

.product-stat-icon {
    width: var(--size-strip-icon);
    height: var(--size-strip-icon);
    border-radius: var(--radius-base);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.product-stat-label { font-size: var(--font-size-sm); color: var(--color-text-muted); }

.product-stat-value {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-tight);
}

/* ------------------------------------------------------------ แถบเครื่องมือ */

.product-toolbar {
    display: flex;
    align-items: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.product-toolbar .field { margin: 0; min-width: 0; }
.product-toolbar .field:first-of-type { flex: 1 1 220px; }
.product-toolbar .field:not(:first-of-type) { flex: 0 1 160px; }

.product-toolbar-tail {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* ‼️ ตัวสลับสองสถานะ (segmented control) — ของกลาง ใช้ได้ทุกหน้าที่ต้องเลือก 1 จาก 2-3 อย่าง
      ‼️ ทุกปุ่มต้องมี "ไอคอน + คำ" เสมอ ห้ามเหลือแต่ไอคอนเดี่ยว
         ของเดิมที่หน้าสินค้าเป็นไอคอนล้วนสองใบ วางติดกับ dropdown "เรียงลำดับ"
         และใบซ้ายใช้ไอคอนลูกศรขึ้น-ลง ผู้ใช้จึงอ่านว่าเป็น "ปุ่มกลับทิศทางการเรียง"
         ไม่ใช่ "ปุ่มเปลี่ยนมุมมอง" (เจ้าของระบบแจ้งเอง 2026-08-30) */
.segmented {
    display: inline-flex;
    padding: var(--space-1);
    gap: var(--space-1);
    background: var(--color-neutral-soft);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
}

.segmented-option {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    height: var(--height-control-sm);
    padding: 0 var(--space-3);
    border: var(--border-width) solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-text-muted-on-soft);
    font-family: inherit;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--transition-base), color var(--transition-base), border-color var(--transition-base);
}

.segmented-option .icon { width: 18px; height: 18px; flex: none; }

.segmented-option:hover { color: var(--color-text); }

/* ‼️ สถานะที่เลือกต้องต่างหลายทาง ไม่ใช่แค่สีตัวอักษร — พื้นส้มอ่อน กรอบส้ม และไอคอนส้ม
      บวกกับ aria-pressed ที่โปรแกรมอ่านหน้าจอใช้บอกสถานะ (WCAG 1.4.1 ห้ามบอกด้วยสีอย่างเดียว) */
.segmented-option.is-active {
    background: var(--color-primary-soft);
    border-color: var(--color-primary);
    color: var(--color-primary-strong);
}

.segmented-option:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* ‼️ ป้ายแนะนำเป็นดาวเดี่ยวในคอลัมน์ของตัวเอง ไม่ใช่ badge ยาวข้างชื่อสินค้า
      ทำให้อ่านทั้งคอลัมน์แล้วเห็นทันทีว่ารายการไหนถูกแนะนำบ้าง */
.product-featured { color: var(--color-primary); display: inline-flex; }

/* --------------------------------------------------------- มุมมองการ์ด
   ‼️ เป็นโครงคนละชุดกับตาราง ไม่ใช่ตารางที่ใส่คลาสเพิ่ม
      ทุกช่องบนการ์ดมาจากคอลัมน์เดียวกับที่ตารางแสดง บวกรูปปกที่ตารางไม่มีที่ให้แสดง
   ------------------------------------------------------------------------- */

.product-cards {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-3);
    list-style: none;
    margin: 0;
    padding: 0;
}

.product-card {
    display: flex;
    flex-direction: column;
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    overflow: hidden;
    transition: border-color var(--transition-base), box-shadow var(--transition-base);
}

.product-card:hover { border-color: var(--color-primary-border); box-shadow: var(--shadow-card); }

/* ‼️ อัตราส่วนคงที่ทุกใบ รูปสูงไม่เท่ากันจะทำให้ชื่อสินค้าของแต่ละใบไม่อยู่ระดับเดียวกัน
      แล้วสายตากวาดทั้งกริดไม่ได้ */
.product-card-media {
    position: relative;
    display: block;
    aspect-ratio: 4 / 3;
    background: var(--color-surface-muted);
    border-bottom: var(--border-width) solid var(--color-border);
}

.product-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ‼️ สินค้าที่ยังไม่ได้ใส่รูปได้กรอบเปล่ามาตรฐาน ไม่ใช่ <img> ที่โหลดไม่ขึ้น
      และการ์ดยังสูงเท่าใบอื่นทุกประการ */
.product-card-placeholder {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-border-strong);
}

.product-card-placeholder .icon { width: var(--space-5); height: var(--space-5); }

.product-card-featured {
    position: absolute;
    top: var(--space-2);
    left: var(--space-2);
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    height: var(--space-4);
    padding: 0 var(--space-2);
    border-radius: var(--radius-pill);
    background: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
}

.product-card-featured .icon { width: 12px; height: 12px; }

.product-card-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding: var(--space-3) var(--space-3) 0;
    flex: 1;
}

.product-card-name {
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
    /* ‼️ ชื่อสินค้ายาวได้ไม่จำกัด ตัดที่สองบรรทัดเพื่อให้ทุกใบสูงเท่ากัน */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.product-card-meta { font-size: var(--font-size-xs); color: var(--color-text-muted); }

.product-card-price { font-weight: var(--font-weight-medium); margin-top: auto; }

.product-card-was {
    display: block;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-normal);
    color: var(--color-text-muted);
    text-decoration: line-through;
}

.product-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3) var(--space-3);
}

.cell-center { text-align: center; }

/* -------------------------------------------------- รายการหมวดหมู่ในแผง */

.category-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    list-style: none;
    margin: 0;
    padding: 0;
}

.category-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-base);
    background: var(--color-surface);
}

/* ------------------------------------------------------------- จอแคบลง */

/* ‼️ กริดการ์ด: เดสก์ท็อป 4 · แล็ปท็อป 3 · แท็บเล็ต 2 · มือถือ 1 */
@media (max-width: 1200px) {
    .product-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
    .product-toolbar { flex-direction: column; align-items: stretch; }
    .product-toolbar .field,
    .product-toolbar .field:first-of-type,
    .product-toolbar .field:not(:first-of-type) { flex: 1 1 auto; }
    .product-toolbar-tail { justify-content: space-between; }

    .product-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
    .product-cards { grid-template-columns: minmax(0, 1fr); }

    /* ‼️ จอแคบ: ตัวสลับมุมมองยืดเต็มความกว้าง กดง่ายกว่าปุ่มแคบ ๆ ที่ชิดขอบ
          และยังเห็นคำกำกับครบ ไม่ต้องเดาจากไอคอน */
    .product-toolbar-tail .segmented { flex: 1 1 100%; }
    .product-toolbar-tail .segmented-option { flex: 1 1 0; justify-content: center; }
}

/* ============================================================ หน้าเพิ่ม/แก้สินค้า
   ‼️ เป็นหน้าเต็มโดยตั้งใจ ไม่ใช่แผงเลื่อน — ฟอร์มมีข้อมูล รูปภาพ และ SEO มากเกินกว่า
      จะกรอกในกล่องกว้าง 460px ได้จริง
   ------------------------------------------------------------------------- */

.product-form {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 3fr);
    gap: var(--space-4);
    align-items: start;
}

/* ‼️ แถบข้างไม่มีกฎ CSS ของตัวเอง — ตั้งใจให้เลื่อนไปพร้อมหน้าเหมือนเนื้อหาปกติ
      ของเดิม .product-form-side-inner เกาะจอ (position: sticky) แล้วจำกัดความสูงด้วย
      overflow-y: auto จึงกลายเป็น "กล่องในกล่อง" ที่มีแถบเลื่อนซ้อนอยู่ทางขวา
      ผู้ใช้เจอสองแถบเลื่อนในหน้าเดียวและไม่รู้ว่าอันไหนคุมอะไร (เจ้าของระบบแจ้งเอง 2026-08-30)
   ‼️ ปุ่มบันทึกไม่ได้อยู่ในแถบข้าง แต่อยู่ที่ .form-actionbar ซึ่งเกาะขอบล่างจออยู่แล้ว
      การเลิกเกาะจอตรงนี้จึงไม่ได้ทำให้ปุ่มที่ต้องกดหลุดจากสายตา
      ‼️ ห้ามใส่ position: sticky กลับมาโดยไม่ใส่ทางออกให้ปลายล่างของแถบข้างที่ยาวเกินจอ */

.form-slug-preview {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    word-break: break-all;
}

/* รูปหลักอยู่ซ้าย รูปเพิ่มเติมเรียงลงมาทางขวา เพราะรูปหลักคือรูปที่ลูกค้าเห็นก่อนในหน้ารายการ
   ‼️ ช่องเลือกรูปเรียงเดี่ยว ไม่ใช่สองคอลัมน์ — ตัวเลือกรูปมีทั้งชื่อรูป ปุ่มเลือก และปุ่มล้าง
      บีบให้แคบกว่านี้แล้วข้อความจะขึ้นบรรทัดทีละคำและปุ่มล้างจะล้นออกนอกกรอบ */
.product-images {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: var(--space-4);
    align-items: start;
}

.product-gallery-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-3);
}

/* สารบัญ — ลิงก์ไป id จริงในหน้า ใช้ได้แม้ปิด JavaScript */
.form-toc { display: flex; flex-direction: column; }

.form-toc a {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-2);
    border-radius: var(--radius-base);
    color: var(--color-text);
    text-decoration: none;
    font-size: var(--font-size-sm);
}

.form-toc a:hover { background: var(--color-surface-muted); }

.form-toc-dot {
    width: 6px;
    height: 6px;
    flex: 0 0 auto;
    border-radius: var(--radius-pill);
    background: var(--color-border-strong);
}

.form-toc a:hover .form-toc-dot { background: var(--color-primary); }

.form-note {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    padding: var(--space-3);
    border-radius: var(--radius-base);
    background: var(--color-surface-muted);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    line-height: var(--line-height-base);
}

.form-note svg { flex: 0 0 auto; margin-top: 2px; }

/* ‼️ แถบบันทึกเกาะขอบล่าง ฟอร์มที่ยาวกว่าจอจึงกดบันทึกได้โดยไม่ต้องเลื่อนกลับไปหาปุ่ม
      ใช้ sticky ไม่ใช่ fixed จะได้กว้างเท่าเนื้อหาเอง ไม่ต้องรู้ความกว้างของแถบเมนู */
.form-actionbar {
    position: sticky;
    bottom: 0;
    /* ‼️ ต้องอยู่เหนือปุ่มลอย "แจ้งปัญหา" (z-index 70) ไม่งั้นปุ่มนั้นจะทับปุ่มบันทึกที่มุมขวาล่าง */
    z-index: 75;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-4);
    padding: var(--space-3) var(--space-4);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-pop);
}

/* ‼️ ยกปุ่มลอยขึ้นพ้นแถบบันทึก เพื่อให้ยังกด "แจ้งปัญหา" ได้ในหน้าที่มีแถบนี้
      เบราว์เซอร์ที่ยังไม่รู้จัก :has() จะข้ามกฎนี้ไป ปุ่มบันทึกก็ยังกดได้เพราะ z-index ด้านบน */
body:has(.form-actionbar) .support-fab { bottom: calc(var(--space-6) + var(--space-5)); }

.form-actionbar-note {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.form-actionbar-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* ------------------------------------------------------------- จอแคบลง */

@media (max-width: 1024px) {
    /* ‼️ แถบข้างไหลลงมาต่อท้ายแทนที่จะซ่อน — การ์ดการแสดงผลถูกวาดชุดเดียวในหน้า
          ถ้าซ่อนด้วย display:none ช่องสถานะจะยังส่งค่าไปกับฟอร์มแต่ผู้ใช้แก้ไม่ได้ */
    .product-form { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 768px) {
    .product-images { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 600px) {
    /* จอแคบ: ข้อความเตือนขึ้นบรรทัดบน ปุ่มเรียงเต็มความกว้างข้างล่าง จะได้ไม่ถูกบีบจนกดพลาด */
    .form-actionbar { padding: var(--space-3); }
    .form-actionbar-actions { width: 100%; }
    .form-actionbar-actions .btn { flex: 1 1 auto; justify-content: center; }
}

/* ================================================= หน้าภาพรวม — สามสถานะ
   ‼️ สถานะถูกตัดสินที่ controller จากจำนวนเว็บไซต์เท่านั้น CSS ไม่ได้ตัดสินอะไรทั้งสิ้น
   ------------------------------------------------------------------------- */

/* ---------------------------------------- สถานะ 1: ยังไม่มีเว็บไซต์ */

.start-hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-5);
    align-items: center;
    padding: var(--space-6);
}

.start-hero-title {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-bold);
    margin: 0 0 var(--space-2);
}

.start-hero-text {
    color: var(--color-text-muted);
    line-height: var(--line-height-base);
    max-width: 46ch;
    margin-bottom: var(--space-4);
}

.start-hero-actions { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

/* ‼️ ภาพประกอบวาดด้วย CSS ล้วน ไม่มีไฟล์ภาพให้โหลด และไม่ได้อ้างว่าเป็นเว็บของผู้ใช้
      ทั้งบล็อกถูก aria-hidden ที่ HTML แล้ว */
.start-hero-art {
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-pop);
    overflow: hidden;
}

.start-hero-art-bar {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-3);
    background: var(--color-surface-muted);
    border-bottom: var(--border-width) solid var(--color-border);
}

.start-hero-dot { width: 8px; height: 8px; border-radius: var(--radius-pill); background: var(--color-border-strong); }

.start-hero-art-body { display: grid; grid-template-columns: auto minmax(0, 1fr); min-height: 200px; }

.start-hero-art-side {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-3);
    border-right: var(--border-width) solid var(--color-border);
    color: var(--color-text-muted);
}

.start-hero-art-canvas { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); }
.start-hero-art-line { height: 10px; border-radius: var(--radius-pill); background: var(--color-neutral-soft); width: 55%; }
.start-hero-art-line.is-wide { width: 80%; height: 14px; background: var(--color-primary-soft); }

.start-hero-art-block {
    flex: 1 1 auto;
    min-height: 96px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-base);
    background: var(--color-primary-soft);
    color: var(--color-primary-strong);
}

.start-hero-art-block .icon { width: var(--space-6); height: var(--space-6); }

/* สามขั้นของตัวช่วยสร้าง — เลขลำดับสื่อว่าต้องทำเรียงกันจริง ต่างจากรายการตรวจความพร้อม */
.start-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-4);
}

.start-step { display: flex; align-items: flex-start; gap: var(--space-3); }

.start-step-number {
    flex: 0 0 auto;
    width: var(--space-5);
    height: var(--space-5);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    background: var(--color-primary-soft);
    color: var(--color-primary-strong);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-sm);
}

.start-step-body { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.start-step-title { font-weight: var(--font-weight-medium); }
.start-step-hint { font-size: var(--font-size-sm); color: var(--color-text-muted); line-height: var(--line-height-base); }

/* ------------------------- สถานะ 2 และ 3: หนึ่งเว็บไซต์ = หนึ่งกรอบ */

.site-frame-stack { display: flex; flex-direction: column; gap: var(--space-4); }

/* ‼️ ข้อมูลเว็บกับความพร้อมอยู่ในกรอบเดียวกันเสมอ ห้ามแยกเป็นสองการ์ด
      ไม่งั้นเมื่อมีหลายเว็บจะอ่านไม่ออกว่าแถบความพร้อมอันไหนเป็นของเว็บไหน */
.site-frame {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    overflow: hidden;
}

.site-frame-main { display: grid; grid-template-columns: minmax(0, 240px) minmax(0, 1fr); }

.site-frame-media {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-surface-muted);
    color: var(--color-text-muted);
    overflow: hidden;
    min-height: 180px;
}

.site-frame-media img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.site-frame-media > .icon { width: var(--space-6); height: var(--space-6); }

.site-frame-body { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4); min-width: 0; }
.site-frame-heading { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; min-width: 0; }
.site-frame-title { font-size: var(--font-size-lg); font-weight: var(--font-weight-medium); min-width: 0; }
.site-frame-host { font-size: var(--font-size-sm); color: var(--color-text-muted); }

.site-frame-checks { list-style: none; margin: var(--space-1) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }

.site-frame-check {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    min-width: 0;
}

.site-frame-check > span { min-width: 0; overflow-wrap: anywhere; }
.site-frame-check .icon { width: var(--font-size-base); height: var(--font-size-base); flex: none; margin-top: 2px; }

/* ‼️ สีสื่อสถานะจริงเท่านั้น ห้ามเอาไปตกแต่ง (design.md ข้อ 5.3) */
.site-frame-check.is-ready .icon   { color: var(--color-success); }
.site-frame-check.is-warning .icon { color: var(--color-warning); }
.site-frame-check.is-danger .icon  { color: var(--color-danger); }
.site-frame-check.is-muted .icon   { color: var(--color-text-muted); }

.site-frame-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: auto; padding-top: var(--space-3); }

.site-frame-readiness {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4);
    border-left: var(--border-width) solid var(--color-border);
}

.site-frame-readiness-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
.site-frame-readiness-head h3 { font-size: var(--font-size-base); font-weight: var(--font-weight-medium); }
.site-frame-score { font-size: var(--font-size-sm); color: var(--color-text-muted); white-space: nowrap; }

/* ‼️ แถบมีตัวเลขกำกับเสมอ — สีอย่างเดียวไม่พอสำหรับคนที่แยกสีไม่ได้ */
.site-frame-bar {
    position: relative;
    height: var(--space-4);
    border-radius: var(--radius-pill);
    background: var(--color-neutral-soft);
    overflow: hidden;
}

.site-frame-bar-fill { position: absolute; inset: 0 auto 0 0; background: var(--color-success); }

.site-frame-bar-value {
    position: relative;
    display: block;
    text-align: center;
    line-height: var(--space-4);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
}

.site-frame-groups { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
.site-frame-group { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }

.site-frame-group-title {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-bold);
    color: var(--color-text-muted);
}

.site-frame-group-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }

.site-frame-item {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    min-width: 0;
}

.site-frame-item > a,
.site-frame-item > span:not(.site-frame-mark) { min-width: 0; overflow-wrap: anywhere; }
.site-frame-mark { flex: none; display: inline-flex; margin-top: 2px; }
.site-frame-mark .icon { width: var(--font-size-sm); height: var(--font-size-sm); }

.site-frame-item.is-ready .site-frame-mark       { color: var(--color-success); }
.site-frame-item.is-in_progress .site-frame-mark { color: var(--color-warning); }
.site-frame-item.is-needs_fix .site-frame-mark   { color: var(--color-danger); }
.site-frame-item.is-incomplete .site-frame-mark  { color: var(--color-text-muted); }

/* ‼️ "ต้องแก้ไข" ต้องบอกเป็นคำ ไม่ใช่แค่สี ไม่งั้นจะกลืนกับข้อที่แค่ยังไม่ได้ทำ */
.site-frame-flag {
    flex: none;
    font-size: var(--font-size-xs);
    color: var(--color-danger);
    background: var(--color-danger-soft);
    border-radius: var(--radius-sm);
    padding: 0 var(--space-1);
}

.site-frame-next { margin-top: auto; justify-content: center; }

.site-frame-alldone {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: auto;
    font-size: var(--font-size-sm);
    color: var(--color-success);
}

.dashboard-more { font-size: var(--font-size-sm); }
.dashboard-more a { display: inline-flex; align-items: center; gap: var(--space-1); }

/* ------------------------------------------------- กิจกรรมล่าสุด */

/* ‼️ สองกล่องนี้ต้องสูงเท่ากันเสมอ ไม่ใช่สูงตามเนื้อหาของตัวเอง
      กล่องสองใบที่วางข้างกันแล้วขอบล่างไม่ตรงกัน อ่านออกว่า "หน้าเพี้ยน" ก่อนที่จะอ่านออกว่า
      ข้างในมีข้อมูลไม่เท่ากัน (เจ้าของระบบแจ้งเอง 2026-08-30)
      จึงใช้ stretch แทน start แล้วให้เนื้อในยืดเต็มความสูงที่ได้มา */
.grid-halves { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); align-items: stretch; }

.grid-halves > .card { display: flex; flex-direction: column; }

.grid-halves > .card > .card-body-tight { flex: 1; display: flex; flex-direction: column; }

/* ‼️ รายการเริ่มจากขอบบนตามปกติ แต่สถานะ "ยังไม่มีข้อมูล" ต้องอยู่กลางพื้นที่ที่เหลือ
      ไม่ใช่เกาะขอบบนแล้วทิ้งช่องว่างยาวไว้ข้างล่าง */
.grid-halves > .card > .card-body-tight > .empty-state { margin: auto 0; }

.activity-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }

.activity-item { display: flex; align-items: flex-start; gap: var(--space-3); min-width: 0; }

.activity-icon {
    flex: 0 0 auto;
    width: var(--space-5);
    height: var(--space-5);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-base);
    background: var(--color-surface-muted);
    color: var(--color-text-muted);
}

.activity-icon .icon { width: var(--font-size-base); height: var(--font-size-base); }
.activity-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.activity-title { font-size: var(--font-size-sm); overflow-wrap: anywhere; }
.activity-meta { font-size: var(--font-size-xs); color: var(--color-text-muted); overflow-wrap: anywhere; }
.activity-time { flex: none; font-size: var(--font-size-xs); color: var(--color-text-muted); white-space: nowrap; }

/* ------------------------------------------------------------- จอแคบลง */

@media (max-width: 1200px) {
    /* ‼️ ความพร้อมไหลลงมาใต้ข้อมูลเว็บ ยังอยู่ในกรอบเดียวกันเหมือนเดิม */
    .site-frame { grid-template-columns: minmax(0, 1fr); }
    .site-frame-readiness { border-left: 0; border-top: var(--border-width) solid var(--color-border); }
}

@media (max-width: 900px) {
    .start-hero { grid-template-columns: minmax(0, 1fr); padding: var(--space-4); }
    .start-hero-art { order: -1; }
    .start-steps { grid-template-columns: minmax(0, 1fr); }
    .grid-halves { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 700px) {
    .site-frame-main { grid-template-columns: minmax(0, 1fr); }
    .site-frame-media { min-height: 160px; max-height: 200px; }
    /* จอแคบ: สามกลุ่มเรียงลงมา ไม่ใช่บีบเป็นสามคอลัมน์จนอ่านไม่ออก */
    .site-frame-groups { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
    .site-frame-actions .btn { flex: 1 1 auto; justify-content: center; }
}

/* ‼️ การ์ดตัวเลขของหน้าภาพรวมเรียงเดี่ยวบนจอที่แคบกว่า 430px
      ค่าปกติของ .kpi-grid คือสองคอลัมน์บนมือถือ ซึ่งเหมาะกับหน้ารายการที่มีตารางรออยู่ข้างล่าง
      แต่การ์ดของหน้านี้มีข้อความรองยาว ("เชื่อม Google Analytics เพื่อดูจำนวนผู้เข้าชม")
      พอถูกบีบเหลือ ~110px แล้วขึ้นบรรทัดทีละคำจนอ่านไม่ออก */
@media (max-width: 430px) {
    .kpi-grid.dashboard-kpis { grid-template-columns: minmax(0, 1fr); }
}
