/* =========================================================
   custom.css — ส่วนที่เพิ่มจากธีม admin-template
   โหลดท้ายสุดเสมอ (header.php) จึงเขียนทับธีมได้

   กฎเดียวกับธีม: ห้ามฝังสีตายตัว ใช้ var(--*) เท่านั้น
   ไม่งั้นสไตล์ 16 ชุดและโหมดมืดจะไม่ตามไปด้วย
   ========================================================= */

@layer components {

  /* ---------- ไอคอนเมนู (Font Awesome จากฐานข้อมูล) ----------
     ธีมออกแบบมาให้เมนูใช้ <svg> ขนาด 16px
     ไอคอนเมนูของระบบเก็บเป็นคลาส FA ใน DB จึงต้องจัดขนาดให้เท่ากัน
     ไม่งั้นข้อความเมนูจะไม่ตรงแนวกัน */
  .nav-ico {
    width: 16px;
    height: 16px;
    flex: none;
    display: inline-grid;
    place-items: center;
    font-size: 14px;
    line-height: 1;
  }

  /* ---------- เมนูย่อยแบบลอย (ตอนย่อเมนู) ----------
     shell.js ใส่คลาสนี้แล้ววางตำแหน่งด้วย Admin.place */
  .nav-sub.is-flyout {
    position: fixed;
    z-index: var(--z-dropdown);
    min-width: 190px;
    margin: 0;
    padding: var(--space-1);
    border: 1px solid var(--border);
    border-left: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--card);
    box-shadow: var(--shadow-lg);
  }

  /* ---------- รูปโปรไฟล์ใน .avatar ----------
     ธีมออกแบบ .avatar ไว้ใส่ตัวอักษรย่อเท่านั้น (display:grid + place-items:center)
     ระบบนี้มีรูปโปรไฟล์จริงด้วย ถ้าไม่บังคับขนาด <img> จะดันกรอบจนเสียทรง */
  .avatar > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
    display: block;
  }

  /* ---------- โลโก้องค์กรใน .avatar ----------
     ตราสัญลักษณ์มีกรอบลวดลายของมันเองอยู่แล้ว ถ้าครอบพื้นสีหลักทับจะกลายเป็นกรอบซ้อนกรอบ
     จึงถอดพื้นหลังออกและใช้ contain เพื่อไม่ให้ตราโดนครอบตัด (เหมือนหน้าเข้าสู่ระบบ)
     ถ้ารูปโหลดไม่ขึ้น shell.js จะถอดคลาสนี้ทิ้ง พื้นสีของตัวอักษรย่อจึงกลับมา */
  .avatar.avatar-logo {
    background: transparent;
  }

  .avatar.avatar-logo > img {
    object-fit: contain;
  }

  /* ---------- เมนูที่ต้องกางขึ้นบน ----------
     ใช้กับเมนูผู้ใช้ท้าย sidebar ซึ่งชิดขอบล่างจอ ถ้ากางลงจะตกขอบ */
  .menu.menu-up {
    top: auto;
    bottom: calc(100% + 6px);
    left: 0;
    right: auto;
  }

  /* ---------- เมนูที่ลอยออกมา (หนีกรอบที่ overflow ตัด) ----------
     .sidebar เป็น overflow:hidden และ .table-wrap เป็น overflow-x:auto
     shell.js จึงเปลี่ยนเมนูข้างในเป็น position:fixed แล้ววางตำแหน่งเอง
     ต้องล้าง bottom ของ .menu-up ด้วย ไม่งั้นจะตีกับ top ที่ JS คำนวณ */
  .menu.is-flyout {
    position: fixed;
    z-index: var(--z-dropdown);
    bottom: auto;
    min-width: 200px;
  }

  /* ตอนเมนูย่อ ตัวหนังสือหายไป เหลือแต่รูป จึงจัดให้อยู่กลางพอดี */
  .app.is-collapsed .sidebar-footer .switcher,
  .app.menu-iconly .sidebar-footer .switcher {
    gap: 0;
  }

  /* ---------- ความสูงของพื้นที่เนื้อหา ----------
     ธีมต้นฉบับไม่มี footer ในหน้า จึงเว้น padding ล่าง 64px ไว้เฉย ๆ
     ระบบนี้มี footer ต่อท้าย .content ถ้าปล่อยไว้แบบเดิม หน้าที่เนื้อหาสั้น
     footer จะลอยขึ้นมาติดเนื้อหากลางจอ แทนที่จะอยู่ก้นจอ

     แก้ด้วยการทำ .content เป็น flex column แล้วดัน footer ลงล่างด้วย margin-top:auto
     (ใช้ min-height ไม่ได้ เพราะ .content เป็นตัว scroll เอง — .app สูง 100vh
     และ .main เป็น flex column อยู่แล้ว ความสูงจึงพอดีจออัตโนมัติ)

     ส่วนระยะกันชนเหนือ footer ใช้ row-gap ของ flex container
     เดิมใช้ .content > *:nth-last-child(2) { margin-bottom } ซึ่งพังเมื่อ view
     ปิดท้ายด้วย script เพราะตัวนับไปตกที่แท็กที่มองไม่เห็น การ์ดใบสุดท้าย
     จึงไม่ได้ระยะแล้วชนเส้นคั่น footer — row-gap ไม่ขึ้นกับลำดับลูกจึงไม่มีปัญหานี้ */
  .content {
    display: flex;
    flex-direction: column;
    row-gap: var(--space-6);
    padding-bottom: var(--space-5);
  }

  /* เนื้อหาไม่ควรถูกยืด/บีบตามความสูงที่เหลือ ให้สูงตามของจริง */
  .content > * {
    flex: none;
  }

  /* .page-head มี margin-bottom ของธีมอยู่แล้ว ถ้าปล่อยไว้จะซ้อนกับ row-gap */
  .content > .page-head {
    margin-bottom: 0;
  }

  /* ---------- หัวหน้าจอบนจอแคบ ----------
     ธีมจัด .page-head เป็น flex แถวเดียวไม่มี wrap และปุ่มมี white-space:nowrap
     ปุ่มจึงไม่ยอมย่อ กล่องชื่อเรื่องเลยโดนบีบจนชื่อขึ้นบรรทัดละคำ
     (วัดที่ 375px : กล่องชื่อเหลือ 145px จาก 343px) และถ้าปุ่มมีไอคอนด้วย
     แถวปุ่มจะล้นขอบขวาออกไปอีก

     แก้ที่ต้นเหตุคือให้ห่อบรรทัดได้ ชื่อเรื่องกินเต็มแถว ปุ่มลงแถวถัดไป
     flex-basis 320px = ความกว้างที่ชื่อเรื่องยังอ่านเป็นประโยคได้
     แคบกว่านี้ค่อยห่อ กว้างกว่านี้ปุ่มยังอยู่แถวเดียวกับชื่อเหมือนเดิม */
  .page-head {
    flex-wrap: wrap;
  }

  .page-head > :first-child {
    flex: 1 1 320px;
    min-width: 0;
  }

  /* ชื่อยาว ๆ ที่ไม่มีช่องว่างให้ตัด (รหัสนักศึกษา ชื่อสาขา) ต้องตัดกลางคำได้
     ไม่งั้นคำเดียวก็ดันกล่องจนหน้าเลื่อนแนวนอน */
  .page-head h1,
  .page-head p {
    overflow-wrap: anywhere;
  }

  @media (max-width: 640px) {
    /* .push ตั้ง margin-left:auto ไว้ พอห่อบรรทัดแล้วปุ่มจะไปกองชิดขวา
       ลอย ๆ คนละแนวกับชื่อเรื่อง จอแคบให้กลับมาชิดซ้ายตรงแนวเดียวกัน */
    .page-head > .push {
      margin-left: 0;
      width: 100%;
      /* ป้ายปุ่มยาว ๆ ที่เรียงสองใบไม่พอ ให้ตกลงบรรทัดถัดไปเต็มความกว้าง
         ห้ามใช้ min-width:0 บีบแทน เพราะ .btn เป็น white-space:nowrap
         ตัวอักษรจะทะลุออกนอกกรอบปุ่ม */
      flex-wrap: wrap;
    }

    /* ปุ่มแบ่งความกว้างกันเองเต็มแถว ไม่ล้นขอบ และนิ้วกดง่ายกว่าปุ่มเล็ก ๆ */
    .page-head > .push > .btn {
      flex: 1 1 auto;
    }
  }

  /* แท็กที่ไม่แสดงผลไม่ควรกินพื้นที่ ไม่งั้น row-gap จะเว้นช่องให้ด้วย */
  .content > script,
  .content > style,
  .content > template,
  .content > link {
    display: none;
  }

  /* ---------- footer ----------
     สามส่วนซ้อนกันเป็นชั้น ไม่ใช่แถวเดียวยาว ๆ
       1. ข้อความกำกับที่มาของข้อมูล (เฉพาะจอแคบ ดูหัวข้อถัดไป)
       2. แถวลิขสิทธิ์ + ช่องทางติดต่อ + เลขเวอร์ชัน

     เดิมเป็น flex แถวเดียว justify-content:space-between มีแค่ลิขสิทธิ์กับเวอร์ชัน
     บนจอกว้างจึงเหลือช่องว่างกลางเกือบทั้งแถว และพอจอแคบสองก้อนก็แย่งบรรทัดกัน
     เปลี่ยนเป็นคอลัมน์ แล้วให้แถวข้างในจัดตัวเอง */
  .app-footer {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    /* auto = ดันลงก้นจอเมื่อเนื้อหาสั้น ตอนเนื้อหายาวจะยุบเป็น 0
       ระยะเหนือเส้นคั่นมาจาก row-gap ของ .content แล้ว */
    margin-top: auto;
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
    font-size: var(--text-sm);
    color: var(--muted-fg);
  }

  /* จอกว้าง = ลิขสิทธิ์ชิดซ้าย ติดต่อชิดขวา
     จอแคบ = ตกบรรทัด แล้วชิดซ้ายทั้งคู่ (space-between จัดทีละบรรทัด
     บรรทัดที่มีก้อนเดียวจึงไปกองซ้าย ไม่ลอยไปขวาแบบที่ flex-end จะทำ) */
  .app-footer-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
  }

  .app-footer-links {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-3);
  }

  /* ลิงก์ติดต่อกลมกลืนกับข้อความรอบ ๆ ตอนปกติ แล้วค่อยเข้มขึ้นตอนชี้
     footer ไม่ใช่ที่ที่ควรมีสีลิงก์สดใสมาแย่งสายตาจากเนื้อหาหน้า */
  .app-footer-links a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: inherit;
    text-decoration: none;
    transition: color var(--dur-fast) var(--ease-out);
  }

  .app-footer-links a:hover { color: var(--fg); }

  .app-footer-links a > i {
    font-size: 12px;
    opacity: .7;
  }

  /* จุดคั่นระหว่างเมล/โทร — ต้องจางกว่าตัวอักษร ไม่งั้นเด่นกว่าสิ่งที่มันคั่น */
  .app-footer-sep { opacity: .45; }

  /* เลขเวอร์ชันเป็นข้อมูลของระบบ ไม่ใช่ช่องทางติดต่อ ใส่กรอบให้อ่านแยกออก
     จากลิงก์ที่อยู่ติดกัน โดยไม่ต้องเพิ่มจุดคั่นอีกอัน */
  .app-footer-ver {
    padding: 1px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    font-size: var(--text-xs);
    line-height: 1.6;
  }

  /* ตอนพิมพ์ ไม่ต้องดัน footer ลงก้นหน้า ให้ไหลต่อจากเนื้อหาตามปกติ */
  @media print {
    .content {
      display: block;
    }

    .app-footer {
      margin-top: var(--space-6);
    }
  }

  /* ---------- ข้อความกำกับที่มาของข้อมูล ----------
     ระบบอ่านข้อมูลจากฐานทะเบียนกลางอย่างเดียว จึงต้องบอกผู้ปกครองทุกหน้าว่า
     ตัวเลขที่เห็นเป็นข้อมูลเบื้องต้น ไม่ใช่ฉบับที่ใช้อ้างอิง

     มีสองร่างที่สลับกันตามความกว้างจอ ไม่ใช่แสดงพร้อมกัน
       จอกว้าง  -> แถบบน  ฉบับย่อ + ฉบับเต็มใน tooltip
       จอแคบ    -> ท้ายหน้า ฉบับเต็ม (แถบบนไม่มีที่พอ และ tooltip กดบนจอสัมผัสไม่ติด)

     ทั้งคู่ใช้สีจางระดับเดียวกับ .muted โดยตั้งใจ — เป็นข้อความที่ค้างอยู่ทุกหน้า
     ถ้าทำให้เด่นเท่ากล่องเตือนจริง ผู้ใช้จะชินแล้วเลิกอ่านทั้งสองแบบ */

  /* แถบบนสูงคงที่ (--topbar-h) ข้อความจึงห้ามขึ้นบรรทัดที่สอง */
  .topbar-note {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    max-width: 340px;
    font-size: var(--text-sm);
    color: var(--muted-fg);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: help;
  }

  .topbar-note > i {
    flex: none;
    opacity: .7;
  }

  /* ปริยายซ่อน — จอกว้างใช้ร่างที่แถบบนแทน
     ไม่ต้องมี flex-basis แล้ว เพราะ .app-footer เป็น column อยู่แล้ว
     ตัวมันจึงได้บรรทัดของตัวเองเหนือแถวลิขสิทธิ์อัตโนมัติ */
  .app-footer-note {
    display: none;
    align-items: flex-start;
    gap: var(--space-2);
    margin: 0;
    line-height: 1.5;
  }

  /* ไอคอนต้องไม่ยุบเมื่อข้อความขึ้นบรรทัดที่สอง และให้จางกว่าตัวอักษรอีกขั้น */
  .app-footer-note > i {
    flex: none;
    margin-top: 2px;
    opacity: .7;
  }

  /* สลับร่างที่จุดเดียว จึงเหลือร่างที่แสดงอยู่หนึ่งร่างเสมอ ไม่มีช่วงที่หายไปทั้งคู่
     1100px = จุดเดียวกับที่ธีมเริ่มยุบ breadcrumb ซึ่งเป็นจุดที่แถบบนเริ่มเบียด */
  @media (max-width: 1100px) {
    .topbar-note { display: none; }
    .app-footer-note { display: flex; }
  }

  /* ---------- ปุ่มลอยเปิดแผงตั้งค่าธีม ---------- */
  .theme-fab {
    position: fixed;
    right: var(--space-5);
    bottom: var(--space-5);
    z-index: var(--z-dropdown);
    width: 44px;
    height: 44px;
    border-radius: var(--radius-full);
    box-shadow: var(--shadow-lg);
  }

  @media print {
    .theme-fab {
      display: none !important;
    }
  }

  /* ---------- โมดัลขนาดใหญ่ ----------
     dialog.dialog ของธีมกว้าง 460px ซึ่งพอสำหรับกล่องยืนยัน
     แต่ฟอร์ม CRUD ของระบบนี้มีหลายคอลัมน์ จึงต้องกว้างกว่า */
  dialog.dialog.dialog-lg {
    width: min(860px, calc(100vw - 40px));
    padding: 0;
  }

  dialog.dialog.dialog-lg .modal-header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-bottom: 1px solid var(--border);
  }

  dialog.dialog.dialog-lg .modal-header h1,
  dialog.dialog.dialog-lg .modal-header h2,
  dialog.dialog.dialog-lg .modal-header h3 {
    flex: 1;
    min-width: 0;
    font-size: var(--text-md);
    font-weight: 600;
  }

  dialog.dialog.dialog-lg .modal-body {
    padding: var(--space-5);
    max-height: calc(100vh - 230px);
    overflow-y: auto;
  }

  dialog.dialog.dialog-lg .modal-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);
    border-top: 1px solid var(--border);
    background: var(--muted);
  }

  /* ปุ่มปิดมุมขวาบนของโมดัล */
  .btn-close {
    width: 30px;
    height: 30px;
    flex: none;
    display: inline-grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--muted-fg);
    cursor: pointer;
    font-size: 18px;
    line-height: 1;
  }

  .btn-close::before {
    content: "\00d7";
  }

  .btn-close:hover {
    background: var(--hover);
    color: var(--fg);
  }

  /* ---------- โมดัลกำหนดสิทธิ์การเข้าถึงเมนู ----------
     แถบเครื่องมือกับตัวนับตรึงไว้บนสุด ไม่เลื่อนหายไปกับรายการที่ยาว */
  .perm-toolbar {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    padding: var(--space-3) var(--space-5);
    border-bottom: 1px solid var(--border);
  }

  .perm-summary {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-5);
    border-bottom: 1px solid var(--border);
    background: var(--muted);
  }

  /* ---- กลุ่มเมนู ---- */
  .perm-group {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--card);
    overflow: hidden;
  }

  .perm-group[hidden] {
    display: none;
  }

  .perm-group-head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 10px var(--space-4);
    border-bottom: 1px solid var(--border);
    background: var(--muted);
  }

  /* เลือกไม่ครบกลุ่ม -> ขีดสีไว้ให้เห็นว่ายังมีที่ยังไม่ได้เลือก */
  .perm-group.is-partial .perm-group-head {
    box-shadow: inset 3px 0 0 var(--primary);
  }

  .perm-group-body {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 2px;
    padding: var(--space-2);
  }

  /* ---- เมนูแต่ละรายการ : ทั้งแถวกดได้ ไม่ใช่แค่กล่องติ๊ก ---- */
  .perm-item {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    cursor: pointer;
  }

  .perm-item[hidden] {
    display: none;
  }

  .perm-item:hover {
    background: var(--hover);
  }

  .perm-item input {
    width: 15px;
    height: 15px;
    flex: none;
    accent-color: var(--primary);
    cursor: pointer;
  }

  .perm-item span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* เมนูที่เลือกไว้ให้เด่นกว่าเมนูที่ยังไม่เลือก */
  .perm-item:has(input:checked) {
    background: color-mix(in srgb, var(--primary) 10%, transparent);
    color: var(--primary-text);
    font-weight: 500;
  }

  .perm-item input:focus-visible {
    outline: 2px solid var(--ring);
    outline-offset: 2px;
  }



  /* ---------- โมดัลกำหนดสิทธิ์ทำรายการ ----------
     ใช้ .perm-group-head ร่วมกับโมดัลสิทธิ์เมนู แต่ที่นี่แต่ละแถวคือสิทธิ์
     หนึ่งตัว ไม่ใช่หัวกลุ่ม จึงเน้นสีแถวที่เปิดอยู่ด้วย --primary
     แบบเดียวกับ .perm-item:has(input:checked) ให้กวาดตาแล้วเห็นทันที
     ว่าบทบาทนี้เปิดสิทธิ์อะไรไว้บ้าง */
  .perm-group-head:has(.action-checkbox:checked) {
    background: color-mix(in srgb, var(--primary) 10%, transparent);
    color: var(--primary-text);
  }

  /* คำอธิบายใต้ชื่อสิทธิ์ปกติเป็นสีจาง พอแถวถูกเปิดให้เข้มขึ้นตามหัวข้อ
     ไม่งั้นจะอ่านยากบนพื้นที่เข้มขึ้น */
  .perm-group-head:has(.action-checkbox:checked) .text-xs.muted {
    color: inherit;
    opacity: .75;
  }

  /* แถวที่ถูกล็อกเพราะปิดสิทธิ์อ่าน — ทำจางทั้งแถวผ่าน css
     ไม่ต้องให้ js ไปยุ่งกับ style ทีละตัว */
  .perm-group-head.is-locked {
    opacity: .55;
  }

  /* ป้าย "สิทธิ์ฐาน" ของแถวอ่าน — ใช้สีหลักของธีมให้ต่างจาก badge-outline
     ทั่วไป เพราะมันบอกว่าแถวนี้คุมแถวอื่นทั้งหมดอยู่ ไม่ใช่ป้ายบอกสถานะเฉย ๆ */
  .perm-base-badge {
    background: color-mix(in srgb, var(--primary) 12%, transparent);
    border-color: color-mix(in srgb, var(--primary) 35%, transparent);
    color: var(--primary-text);
    font-weight: 500;
  }

  /* ---------- ป้ายสิทธิ์ทำรายการในตารางบทบาท ----------
     ย่อชื่อสิทธิ์เหลืออักษรอังกฤษตัวเดียว (R C U D E I) เพื่อให้เห็นสิทธิ์ครบทุกตัว
     ในคอลัมน์เดียวโดยไม่ต้องเปิดโมดัล ตัวที่ปิดอยู่ยังแสดงแต่จางลง
     ให้เทียบกันได้ว่าบทบาทไหนขาดสิทธิ์อะไร */
  .perm-chips {
    display: inline-flex;
    gap: 3px;
  }

  .perm-chip {
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--muted);
    color: var(--muted-fg);
    /* อักษรละตินตัวเดียว ใช้ฟอนต์ระบบและจัดระยะตัวอักษรให้กว้างเท่ากันทุกชิป
       ไม่งั้น R กับ I จะกินที่ไม่เท่ากันจนขอบชิปดูไม่ตรงแนว */
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    cursor: default;
  }

  .perm-chip.is-on {
    border-color: transparent;
    background: var(--primary);
    color: var(--primary-fg);
  }

  /* ---------- สถานะกำลังโหลด ---------- */
  .loading-block {
    display: grid;
    place-items: center;
    gap: var(--space-3);
    min-height: 30vh;
    color: var(--muted-fg);
    font-size: var(--text-sm);
  }

  .spinner {
    width: 26px;
    height: 26px;
    border: 2px solid var(--border);
    border-top-color: var(--primary);
    border-radius: 50%;
    animation: spin .7s linear infinite;
  }

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

  /* ---------- ดอกจันช่องบังคับกรอก ---------- */
  .req {
    color: var(--danger-fg);
  }

  /* ---------- Parsley (ตรวจฟอร์ม) ----------
     ปลั๊กอินเดิมยังใช้อยู่ จึงจับสีให้ตรงกับธีม */
  .parsley-errors-list {
    margin: 5px 0 0;
    padding: 0;
    list-style: none;
    font-size: var(--text-sm);
    color: var(--danger-fg);
  }

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

  /* ---------- โมดัลกำหนดขอบเขตข้อมูล (กลุ่มสิทธิ์) ----------
     ใช้ .perm-toolbar / .perm-summary ร่วมกับโมดัลสิทธิ์เมนู
     ส่วนที่เพิ่มคือแท็บ ต้นไม้ 3 ชั้น และชิปเขตพื้นที่

     ตั้งชื่อขึ้นต้นด้วย scope- ทั้งหมด ไม่ใช้ perm-item ซ้ำ
     เพราะคลาสนั้นถูกโมดัลสิทธิ์เมนูใช้อยู่แล้วคนละความหมาย */

  /* ---- แท็บสลับหมวด ---- */
  .scope-tabs {
    display: flex;
    gap: var(--space-1);
    flex: none;
  }

  .scope-tab {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--bg);
    color: var(--muted-fg);
    font-family: inherit;
    font-size: var(--text-sm);
    font-weight: 500;
    cursor: pointer;
  }

  .scope-tab:hover {
    background: var(--hover);
    color: var(--fg);
  }

  .scope-tab.is-active {
    border-color: var(--primary);
    background: color-mix(in srgb, var(--primary) 10%, transparent);
    color: var(--primary-text);
  }

  /* ---- ต้นไม้หน่วยงาน ---- */
  .scope-tree {
    display: flex;
    flex-direction: column;
    gap: 2px;
  }

  .scope-node[hidden] {
    display: none;
  }

  .scope-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 6px var(--space-2);
    border-radius: var(--radius-sm);
    min-width: 0;
  }

  .scope-row:hover {
    background: var(--hover);
  }

  /* ชั้นลึกเยื้องเข้าไป ให้เห็นลำดับชั้นโดยไม่ต้องมีเส้น */
  .scope-node-2 {
    margin-left: var(--space-5);
  }

  .scope-node-3 {
    margin-left: var(--space-5);
  }

  /* กิ่งที่เลือกลูกไม่ครบ ทำหัวกิ่งให้เด่นไว้ */
  .scope-node.is-partial > .scope-row > .scope-check > .scope-name {
    color: var(--primary-text);
  }

  /* ---- ปุ่มกาง/ยุบ ---- */
  .scope-caret {
    width: 18px;
    height: 18px;
    flex: none;
    display: inline-grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--muted-fg);
    cursor: pointer;
  }

  .scope-caret::before {
    content: "";
    width: 0;
    height: 0;
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    transition: transform .15s ease;
  }

  .scope-caret.is-open::before {
    transform: rotate(90deg);
  }

  .scope-caret:hover {
    background: var(--hover);
    color: var(--fg);
  }

  /* ที่ว่างแทนปุ่ม เพื่อให้ชื่อของทุกชั้นตรงแนวกัน */
  .scope-caret.is-empty {
    cursor: default;
    background: none;
  }

  .scope-caret.is-empty::before {
    border: 0;
  }

  /* ---- กล่องติ๊กพร้อมชื่อ ---- */
  .scope-check {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: 1;
    min-width: 0;
    cursor: pointer;
  }

  .scope-check input {
    width: 15px;
    height: 15px;
    flex: none;
    accent-color: var(--primary);
    cursor: pointer;
  }

  .scope-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--text-sm);
  }

  .scope-check input:checked + .scope-name {
    color: var(--primary-text);
    font-weight: 500;
  }

  .scope-node-count {
    flex: none;
  }

  /* ---- เขตพื้นที่: ชิปเรียงเป็นตาราง ---- */
  .scope-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: var(--space-2);
  }

  .scope-chip {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 10px var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    cursor: pointer;
  }

  .scope-chip[hidden] {
    display: none;
  }

  .scope-chip:hover {
    background: var(--hover);
  }

  .scope-chip input {
    width: 15px;
    height: 15px;
    flex: none;
    accent-color: var(--primary);
    cursor: pointer;
  }

  /* ตัวเลือก "ไม่กำหนดกลุ่ม" อยู่เต็มแถวเหนือรายการกลุ่ม
     ใช้เส้นประให้ต่างจากกลุ่มจริงที่เลือกได้ */
  .scope-chip-none {
    border-style: dashed;
  }

  .scope-chip:has(input:checked) {
    border-color: var(--primary);
    background: color-mix(in srgb, var(--primary) 10%, transparent);
    color: var(--primary-text);
    font-weight: 500;
  }

  /* ---- ป้ายสรุปขอบเขตในตาราง ---- */
  .scope-badges {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
  }

  .scope-badges .badge {
    gap: 4px;
  }

  /* ---- จอแคบ ---- */
  @media (max-width: 640px) {
    .scope-node-2,
    .scope-node-3 {
      margin-left: var(--space-3);
    }

    .scope-node-count {
      display: none;
    }
  }

}

/* ---------- SweetAlert2 ----------
   ปลั๊กอินฉีด CSS ของตัวเองมาทีหลัง จึงต้องอยู่นอก @layer
   (สไตล์นอก layer ชนะสไตล์ใน layer เสมอ) */
.swal2-popup {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--card);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--text-base);
}

.swal2-title,
.swal2-html-container {
  color: var(--fg);
}

.swal2-html-container {
  font-size: var(--text-base);
}

.swal2-actions .swal2-styled {
  border-radius: var(--radius-sm);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: 500;
  box-shadow: none;
}

.swal2-actions .swal2-confirm {
  background: var(--primary) !important;
  color: var(--primary-fg) !important;
}

.swal2-actions .swal2-cancel {
  border: 1px solid var(--input) !important;
  background: var(--bg) !important;
  color: var(--fg) !important;
}

.swal2-container.swal2-backdrop-show {
  background: var(--overlay);
}
