/* ฟอนต์ Prompt เก็บไว้ในเครื่อง (assets/vendor/fonts/) ไม่พึ่งพา Google Fonts จากภายนอก
   กันปัญหาเบราว์เซอร์ของผู้ใช้บางเครื่อง/เครือข่ายบางแห่งเข้าถึง CDN ภายนอกไม่ได้ */
@font-face{
  font-family:'Prompt';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('../vendor/fonts/prompt-thai-400-normal.woff2') format('woff2');
  unicode-range:U+0E01-0E5B,U+200C-200D,U+25CC;
}
@font-face{
  font-family:'Prompt';
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url('../vendor/fonts/prompt-latin-400-normal.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

:root{
  --rc-primary:#0f4c75;
  --rc-primary-dark:#0b3a5a;
  --rc-accent:#1f8a70;
  --rc-bg:#eff3f7;
  --rc-line:#dfe6ee;
}

body{
  font-family:'Prompt',system-ui,-apple-system,"Segoe UI",sans-serif;
  font-weight:400;
  background:var(--rc-bg);
  color:#22303c;
}

h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6,.btn,.navbar-brand{font-weight:400;}

.avatar{
  width:32px;height:32px;border-radius:50%;flex:none;
  background:rgba(255,255,255,.2);
  display:inline-flex;align-items:center;justify-content:center;
}

/* ---------------- เมนูซ้าย (sidebar) ---------------- */
:root{
  --rc-sidebar-w:250px;
  --rc-sidebar-w-collapsed:68px;
}

/* ใช้ 100dvh (dynamic viewport height) แทน/เสริม 100vh เพื่อกันปัญหาความสูงหน้าจอคำนวณผิดตอนแถบเครื่องมือของ
   เบราว์เซอร์บนมือถือย่อ/ขยายระหว่างเลื่อนหน้าจอ (เบราว์เซอร์ที่ไม่รู้จัก dvh จะข้ามบรรทัดนี้ไปเฉยๆ ใช้ 100vh
   ตามเดิมไม่มีผลกระทบ) — ใช้รูปแบบเดียวกับ .login-wrap ที่มีอยู่แล้วด้านล่าง เพิ่มมาที่นี่ด้วยเพราะเป็นส่วนที่ครอบ
   ทั้งแอปหลัก (มีแถบเมนู position:sticky อยู่ด้านใน) ซึ่งพบรายงานว่าเนื้อหาถัดจากแถบ sticky หายชั่วคราวตอนเลื่อน
   หน้าจอลงเฉพาะ Chrome บน iPhone เท่านั้น */
.has-sidebar{min-height:100vh;min-height:100dvh;}

.app-sidebar{
  position:fixed;inset:0 auto 0 0;z-index:1030;
  width:var(--rc-sidebar-w);
  display:flex;flex-direction:column;
  background:linear-gradient(180deg,var(--rc-primary),var(--rc-primary-dark) 70%);
  color:rgba(255,255,255,.9);
  box-shadow:2px 0 10px rgba(15,42,66,.12);
  transition:width .18s ease, transform .2s ease;
}

.sidebar-brand{
  display:flex;align-items:center;gap:.5rem;
  padding:1rem .85rem;
  border-bottom:1px solid rgba(255,255,255,.15);
}
.brand-link{
  display:flex;align-items:center;gap:.6rem;flex:1;min-width:0;
  color:#fff;text-decoration:none;
}
.brand-logo{
  width:34px;height:34px;flex:none;border-radius:.5rem;
  background:rgba(255,255,255,.12);
  display:inline-flex;align-items:center;justify-content:center;
  font-size:1.2rem;overflow:hidden;
}
.brand-logo img{width:100%;height:100%;object-fit:cover;}
.brand-text{display:flex;flex-direction:column;min-width:0;line-height:1.25;}
.brand-title{
  font-size:.95rem;line-height:1.2;
  white-space:normal;overflow-wrap:break-word;word-break:break-word;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.brand-sub{font-size:.72rem;opacity:.7;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}

.sidebar-toggle{
  flex:none;width:28px;height:28px;border:0;border-radius:.4rem;
  background:rgba(255,255,255,.12);color:#fff;
  display:inline-flex;align-items:center;justify-content:center;
}
.sidebar-toggle:hover{background:rgba(255,255,255,.22);}

.sidebar-nav{flex:1 1 auto;overflow-y:auto;padding:.6rem .5rem;}
.sidebar-nav .nav-link{
  display:flex;align-items:center;gap:.7rem;
  padding:.55rem .7rem;margin-bottom:.15rem;border-radius:.5rem;
  color:rgba(255,255,255,.8);white-space:nowrap;overflow:hidden;
}
.sidebar-nav .nav-link i{font-size:1.05rem;flex:none;width:1.2rem;text-align:center;}
.sidebar-nav .nav-link:hover{background:rgba(255,255,255,.1);color:#fff;}
.sidebar-nav .nav-link.active{background:rgba(255,255,255,.18);color:#fff;}
.sidebar-nav .nav-label{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;}
.sidebar-nav .nav-badge{flex:none;font-weight:600;}
html.rc-sidebar-collapsed .sidebar-nav .nav-badge{display:none;}

.sidebar-nav-bottom{margin-top:.4rem;padding-top:.4rem;border-top:1px solid rgba(255,255,255,.12);}
.sidebar-nav-bottom .nav-link-logout{color:#ff8a94;}
.sidebar-nav-bottom .nav-link-logout:hover{background:rgba(255,80,90,.18);color:#ffb3ba;}

.sidebar-user{border-top:1px solid rgba(255,255,255,.15);padding:.6rem .5rem;}
.sidebar-user-link{
  display:flex;align-items:center;gap:.6rem;width:100%;
  padding:.4rem .35rem;border-radius:.5rem;text-decoration:none;color:#fff;
}
.sidebar-user-link:hover{background:rgba(255,255,255,.1);}
.sidebar-user-link::after{margin-left:auto;}

.sidebar-backdrop{
  position:fixed;inset:0;background:rgba(15,25,35,.45);z-index:1025;
  display:none;
}

.app-shell{
  margin-left:var(--rc-sidebar-w);
  min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;
  transition:margin-left .18s ease;
}
/*
 * (ย้อนกลับแล้ว) เคยลอง promote .app-content เป็น GPU layer แยก (รอบที่ 2 ของการไล่แก้ปัญหาแถบ sticky ด้านล่าง)
 * ด้วย transform:translateZ(0) แต่พบว่าทำให้ "จองห้องประชุมไม่ได้ กดจองห้องใหม่/คลิกปฏิทินค้างเป็นหน้าจอเงาดำ" —
 * สาเหตุ: การใส่ transform (แม้ค่าจะเท่ากับไม่ขยับอะไรเลยก็ตาม) ให้กับ element ใดๆ จะทำให้ element นั้นกลายเป็น
 * "containing block" ของลูกหลานที่เป็น position:fixed ทันที (พฤติกรรมมาตรฐานของ CSS) — โมดัลของ Bootstrap ทุกตัว
 * ในระบบนี้ (เช่น #bookingModal ในหน้าจองห้องประชุม) เขียนอยู่ในเนื้อหาหน้า ซึ่งอยู่ภายใน .app-content พอ .app-content
 * มี transform โมดัล (position:fixed) และฉากหลังของโมดัลเลยอ้างอิงตำแหน่งจากกรอบของ .app-content แทนที่จะเป็นวิวพอร์ต
 * ทั้งหน้าจอ ทำให้โมดัลเลื่อน/ขยายผิดตำแหน่ง (เกินขอบเขตที่มองเห็น) เหมือน "ค้าง" ขณะที่ฉากหลังสีเข้มยังคงคลุมเต็มจอ
 * ตรวจสอบแล้วด้วย Playwright: ตำแหน่งจริงของโมดัลเลื่อนเยื้องขวาเท่ากับความกว้างเมนูซ้ายพอดี และสูงเกินวิวพอร์ต จึง
 * เอา transform/will-change ออกจาก .app-content ทันที (ไม่คุ้มเสี่ยงกับปัญหาที่กระทบการใช้งานจริงแบบนี้) เหลือไว้แค่
 * ที่ .app-topbar ด้านล่างซึ่งไม่มีลูกหลานเป็น position:fixed อยู่เลย (มีแค่ปุ่ม/ข้อความ) จึงไม่มีความเสี่ยงแบบเดียวกัน
 */
.app-content{flex:1 1 auto;padding:1.5rem;}
.app-topbar{
  display:flex;align-items:center;gap:.75rem;
  padding:.65rem 1rem;background:#fff;border-bottom:1px solid var(--rc-line);
  position:sticky;top:0;z-index:1020;
  /*
   * บังคับให้แถบนี้มี compositing layer ของตัวเอง (GPU) — แก้บั๊กที่เนื้อหาส่วนที่อยู่ถัดจาก position:sticky
   * ทันที (หัวข้อหน้า + ปุ่มด้านบนของ page_title()) หายไปชั่วคราวตอนเลื่อนหน้าจอลง พบเฉพาะ Chrome บน iOS
   * (WKWebView) เท่านั้น ไม่เกิดกับ Safari บน iOS หรืออุปกรณ์อื่น เป็นบั๊กการ repaint ที่รู้จักกันดีของ
   * position:sticky บน WebKit เมื่อไม่มีการ promote เลเยอร์ ไม่กระทบการจัดวาง/พฤติกรรมใดๆ ในเบราว์เซอร์อื่น
   * (ไม่ใส่ will-change:transform ตรงนี้ตั้งใจ — WebKit รุ่นเก่าบางรุ่นมีบั๊กที่ will-change ทำให้
   * position:sticky หยุดลอยค้าง (ไม่ sticky) ไปเลย จึงใส่แค่บน .app-content ด้านบนซึ่งไม่ได้ใช้ sticky แทน)
   */
  transform:translateZ(0);
  -webkit-transform:translateZ(0);
  -webkit-backface-visibility:hidden;
}
.sidebar-toggle-mobile{
  border:0;background:transparent;font-size:1.35rem;color:var(--rc-primary);
  width:38px;height:38px;display:inline-flex;align-items:center;justify-content:center;
}
.topbar-title{font-size:1rem;color:#22303c;}

/* ย่อเมนูซ้าย (จอใหญ่) */
html.rc-sidebar-collapsed .app-sidebar{width:var(--rc-sidebar-w-collapsed);}
html.rc-sidebar-collapsed .app-shell{margin-left:var(--rc-sidebar-w-collapsed);}
html.rc-sidebar-collapsed .brand-text,
html.rc-sidebar-collapsed .nav-label{display:none;}
html.rc-sidebar-collapsed .sidebar-brand{justify-content:center;padding:.75rem .5rem;}
/* จอเล็กมาก (68px) ไม่พอวางทั้งโลโก้และปุ่มย่อ/ขยายพร้อมกัน จึงซ่อนโลโก้ไว้ เหลือปุ่มเดียวไม่ให้ซ้อนทับกัน */
html.rc-sidebar-collapsed .brand-link{display:none;}
html.rc-sidebar-collapsed .sidebar-toggle{transform:rotate(180deg);margin:0 auto;}
html.rc-sidebar-collapsed .sidebar-nav .nav-link{justify-content:center;}
html.rc-sidebar-collapsed .sidebar-user-link::after{display:none;}
html.rc-sidebar-collapsed .sidebar-user-link{justify-content:center;}

/* จอเล็ก: เมนูซ้ายซ่อนเป็นค่าเริ่มต้น เลื่อนออกมาทับเนื้อหา */
@media (max-width:991.98px){
  .app-sidebar{transform:translateX(-100%);}
  .app-shell{margin-left:0;}
  body.sidebar-mobile-show .app-sidebar{transform:translateX(0);}
  body.sidebar-mobile-show .sidebar-backdrop{display:block;}
  .sidebar-toggle{display:none;}
}
@media (min-width:992px){
  .sidebar-toggle-mobile,.app-topbar{display:none;}
}

/* การ์ด */
.card{border:1px solid var(--rc-line);border-radius:.65rem;box-shadow:0 1px 2px rgba(15,42,66,.04);}
.card-header{background:#fff;border-bottom:1px solid var(--rc-line);}

.stat-card .stat-value{font-size:1.9rem;line-height:1.2;}
.stat-card .stat-label{color:#6b7c8c;font-size:.875rem;}
.stat-card .bi{font-size:1.5rem;opacity:.35;}

.btn-primary{background:var(--rc-primary);border-color:var(--rc-primary);}
.btn-primary:hover,.btn-primary:focus{background:var(--rc-primary-dark);border-color:var(--rc-primary-dark);}
.btn-outline-primary{color:var(--rc-primary);border-color:var(--rc-primary);}
.btn-outline-primary:hover{background:var(--rc-primary);border-color:var(--rc-primary);}
a{color:var(--rc-primary);}

.table>:not(caption)>*>*{padding:.65rem .75rem;}
.table thead th{background:#f6f9fc;color:#54697d;font-size:.85rem;white-space:nowrap;}

.form-label{font-size:.925rem;color:#42566b;}
.required::after{content:" *";color:#dc3545;}

/* รายการตรวจ */
.check-row{border:1px solid var(--rc-line);border-radius:.6rem;padding:1rem;margin-bottom:.75rem;background:#fff;}
.check-row .form-check-inline{margin-right:1.25rem;}
.check-row.is-issue{border-color:#f1aeb5;background:#fff7f7;}

.photo-thumb{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:.5rem;border:1px solid var(--rc-line);}

/* ลิงก์ "รวมรูปภาพหลักฐานการตรวจ" ท้ายรายงานรายละเอียดการตรวจ (reports.php type=detail) — ทำเป็นทัมเนลจริง
   (รูปหลักฐานล่าสุดที่พบตามตัวกรองปัจจุบัน) พร้อมตัวเลขจำนวนรูปทั้งหมดมุมขวาล่าง ไปหน้าแกลเลอรี report_photos.php */
.report-photo-link{
  display:inline-flex;align-items:center;gap:.6rem;margin-top:1rem;padding:.5rem .9rem .5rem .5rem;
  border:1px solid var(--rc-line);border-radius:2rem;text-decoration:none;color:var(--rc-primary-dark,#0f4c75);
  background:#fff;transition:box-shadow .15s ease,border-color .15s ease;
}
.report-photo-link:hover{box-shadow:0 .25rem .75rem rgba(8,25,40,.12);border-color:var(--rc-primary,#0f4c75);}
.report-photo-link-thumb{position:relative;width:44px;height:44px;flex:none;}
.report-photo-link-thumb img{width:100%;height:100%;object-fit:cover;border-radius:50%;border:1px solid var(--rc-line);}
.report-photo-link-badge{
  position:absolute;right:-4px;bottom:-4px;min-width:1.2rem;height:1.2rem;padding:0 .3rem;
  border-radius:1rem;background:var(--rc-primary,#0f4c75);color:#fff;font-size:.65rem;line-height:1.2rem;
  text-align:center;border:2px solid #fff;
}

/* แถวรูปภาพหลักฐานการตรวจขนาดเล็กท้ายรายงาน "สรุปตรวจเช็คความพร้อมรายห้อง" (reports.php type=room_checklist) —
   ตามคำขอผู้ดูแลระบบ: ต่างจาก .report-photo-link ด้านบน (เป็นแค่ลิงก์ไปหน้าแกลเลอรีแยก) ตรงที่รายงานนี้ฝังรูปจริง
   ไว้ในหน้าเลย เป็นรูปเล็กๆ เรียงต่อกัน (flex-wrap ขึ้นบรรทัดใหม่เองเมื่อรูปเยอะ/จอแคบ) */
.report-photo-strip{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.75rem;}
.report-photo-strip img{flex:none;width:64px;height:64px;object-fit:cover;border-radius:.4rem;border:1px solid var(--rc-line);}

/* หัวข้อกลุ่มในรายงานแบบจัดกลุ่ม (เช่น แยกตามประเภทห้อง) */
.report-group-title{
  font-size:.95rem;padding:.5rem .1rem;margin-top:.5rem;
  border-bottom:2px solid var(--rc-primary);color:var(--rc-primary-dark);
}
.stat-card{background:#fff;}

.app-footer{border-top:1px solid var(--rc-line);background:#fff;}

/* หน้าเข้าสู่ระบบและฟอร์มสาธารณะ */
.bare-page{background:linear-gradient(160deg,#0f4c75,#123c5c 60%,#0d2f47);min-height:100vh;}
.bare-card{max-width:460px;margin:0 auto;}
.public-wrap{max-width:820px;margin:0 auto;}
/* หน้าสาธารณะบางหน้า (เช่น book.php ที่แสดงปฏิทินรายเดือน 7 คอลัมน์ + ฟอร์ม) ต้องการพื้นที่กว้างกว่าฟอร์มทั่วไป
   ใช้คู่กับ .public-wrap เสมอ (class="public-wrap public-wrap-wide") ให้ค่า max-width นี้แทนที่ค่าเดิม */
.public-wrap-wide{max-width:1100px;}
/* room_status.php ขอความกว้างเพิ่มอีกเป็นการเฉพาะ (แยกจาก .public-wrap-wide ด้านบนที่ book.php ใช้ร่วมด้วย เพื่อไม่ให้
   การขยายของหน้านี้กระทบความกว้างของ book.php โดยไม่ตั้งใจ) ใช้แทนที่ .public-wrap-wide (class="public-wrap
   public-wrap-xwide" — ไม่ต้องใส่ .public-wrap-wide ซ้ำ เพราะ .public-wrap-xwide มีความกว้างเกินอยู่แล้ว) — หมายเหตุ:
   book.php เองก็ใช้ class นี้ร่วมด้วยเช่นกัน (ไม่ใช่แค่ .public-wrap-wide ตามที่ข้อความนี้เคยระบุไว้ตอนแรก) ดังนั้น
   ถ้าจะขยายความกว้างเพิ่มให้เฉพาะหน้าใดหน้าหนึ่ง ต้องแยก class ใหม่ออกมาเหมือนที่ .public-wrap-report แยกออกไปด้านล่าง
   ห้ามแก้ตัวเลขของ .public-wrap-xwide ตรงๆ เพราะจะกระทบ book.php ไปด้วยโดยไม่ตั้งใจ */
.public-wrap-xwide{max-width:1320px;}
/* ลิงค์รายงานสาธารณะ (reports_public.php ฯลฯ) ขอความกว้างเพิ่มอีกเป็นการเฉพาะเช่นกัน (แยกจาก .public-wrap-xwide
   ด้านบนที่ room_status.php/book.php ใช้อยู่ เพื่อไม่ให้การขยายของหน้ารายงานกระทบความกว้างของ 2 หน้านั้นโดยไม่ตั้งใจ)
   ใช้แทนที่ .public-wrap-xwide (class="public-wrap public-wrap-report") ตารางรายงานมีคอลัมน์มากกว่าจึงต้องการพื้นที่
   กว้างกว่าเดิมอีก */
.public-wrap-report{max-width:1560px;}
/* room_status.php ขอขยายความกว้างปฏิทินเพิ่มอีกเป็นการเฉพาะเจาะจงยิ่งขึ้น (แยกออกจาก .public-wrap-xwide ด้านบนที่
   book.php ใช้ร่วมอยู่ด้วย เพื่อไม่ให้การขยายครั้งนี้กระทบความกว้างของ book.php โดยไม่ตั้งใจ — ดูหมายเหตุที่
   .public-wrap-xwide ด้านบน) ใช้แทนที่ .public-wrap-xwide (class="public-wrap public-wrap-xxwide" — ไม่ต้องใส่
   .public-wrap-xwide ซ้ำ เพราะ .public-wrap-xxwide มีความกว้างเกินอยู่แล้ว) */
.public-wrap-xxwide{max-width:1600px;}

/* จัดกึ่งกลางแนวตั้งสำหรับหน้าเข้าสู่ระบบ กันการ์ดชิดขอบบนจอ โดยเฉพาะมือถือ */
.login-wrap{
  min-height:100vh;min-height:100dvh;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:3rem 1rem;box-sizing:border-box;
}

/* กล่องไอคอนหน้าฟอร์มล็อกอิน (ชื่อผู้ใช้/รหัสผ่าน) */
.login-card{border:0;border-radius:1rem;box-shadow:0 1rem 2.5rem rgba(8,25,40,.18);}
.login-card .form-label{font-size:1rem;color:#22303c;font-weight:400;margin-bottom:.5rem;}
.input-group-icon .input-group-text{
  background:#f4f6f9;border-color:#dfe6ee;color:#42566b;
  min-width:3.1rem;justify-content:center;font-size:1.1rem;
}
.input-group-icon .form-control{border-color:#dfe6ee;}
.input-group-icon .form-control:focus{z-index:5;}
.input-group-icon .btn-toggle-password{
  background:#f4f6f9;border-color:#dfe6ee;color:#42566b;
}
.input-group-icon .btn-toggle-password:hover{background:#e9edf3;color:#22303c;}
.login-card .btn-primary{border-radius:.6rem;font-size:1.05rem;padding:.65rem 1rem;}

/* การ์ดเลือกระบบที่หน้า hub.php (หลัง login สำหรับเจ้าหน้าที่ที่มีสิทธิ์มากกว่า 1 ระบบ)
   ขยายให้ใหญ่ขึ้นจากเดิม (ไอคอน/หัวข้อ/ระยะห่างภายในการ์ด) ให้ดูเด่น อ่านง่ายขึ้นตามที่ผู้ดูแลระบบขอ —
   คู่กับการเปลี่ยน .public-wrap เป็น .public-wrap-wide และ p-4→p-5 ที่ hub.php เพื่อให้มีพื้นที่พอรองรับ */
.hub-card{border:0;border-radius:1.25rem;transition:transform .15s ease,box-shadow .15s ease;box-shadow:0 .5rem 1.5rem rgba(8,25,40,.1);}
.hub-card:hover{transform:translateY(-4px);box-shadow:0 1rem 2.5rem rgba(8,25,40,.18);}
.hub-card .bi{font-size:3.75rem;color:var(--rc-primary);}
.hub-card h2{font-size:1.4rem;}
.hub-card p{font-size:1rem;}

/* ตามคำขอผู้ดูแลระบบ: ตั้งค่า "จำนวนระบบต่อแถว" ที่ settings.php ไว้ 4-6 การ์ดต่อแถว (col-md-3/col-md-2) ทำให้คอลัมน์
   แคบลงมาก ขนาด/ระยะขอบด้านบนใหญ่เกินไปจนชื่อระบบภาษาไทย (ไม่มีช่องว่างแบ่งคำ) ถูกตัดขึ้นบรรทัดใหม่ถี่จนอ่านไม่ออก —
   ลดขนาดไอคอน/หัวข้อ/คำอธิบายลงเมื่อ hub.php ใส่คลาส .hub-card-compact มาด้วย (ดูเงื่อนไข $hubCompact ที่ hub.php) */
.hub-card-compact .bi{font-size:2.25rem;}
.hub-card-compact h2{font-size:1.05rem;}
.hub-card-compact p{font-size:.8rem;}

/* ตามคำขอผู้ดูแลระบบ: แถบ "ข่าวสาร"/"เอกสารดาวน์โหลด" ด้านขวาสุดของหน้า hub.php (ดูเงื่อนไข $hasSidebar ที่ hub.php) —
   .hub-layout ห่อ .public-wrap-wide เดิม (คอลัมน์การ์ดเลือกระบบ) กับ .hub-sidebar ใหม่นี้ไว้ด้วยกันแบบ flex เรียงข้างกัน
   บนจอกว้าง แล้วตกลงมาเรียงซ้อนกันเองอัตโนมัติบนจอแคบ (flex-wrap) โดยไม่ไปแก้ไขความกว้างของ .public-wrap-wide เดิมเลย
   แม้แต่น้อย (ดูคอมเมนต์ยาวที่ hub.php) */
.hub-layout{display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-start;gap:1.5rem;}
.hub-sidebar{width:340px;max-width:100%;}
.hub-sidebar-card{border:0;border-radius:1.25rem;box-shadow:0 .5rem 1.5rem rgba(8,25,40,.1);overflow:hidden;}
.hub-sidebar-scroll{max-height:320px;overflow-y:auto;}
.hub-announcement{padding:.65rem .9rem;border-bottom:1px solid var(--bs-border-color,#e9ecef);}
.hub-announcement:last-child{border-bottom:0;}
.hub-announcement-pinned{background:rgba(255,193,7,.08);}
.hub-document-item{display:flex;align-items:center;gap:.6rem;padding:.6rem .9rem;border-bottom:1px solid var(--bs-border-color,#e9ecef);text-decoration:none;color:inherit;}
.hub-document-item:last-child{border-bottom:0;}
.hub-document-item:hover{background:rgba(8,25,40,.04);}
.hub-document-item .bi:first-child{font-size:1.3rem;}

/* หัวกระดาษสำหรับพิมพ์/ส่งออก PDF เท่านั้น (ซ่อนบนหน้าจอปกติ) */
.print-header{display:none;}
.print-header .print-header-logo{width:56px;height:56px;object-fit:contain;flex:none;}
.print-header .print-header-title{font-size:1.05rem;}
.print-header .print-header-system{font-size:.85rem;font-weight:600;color:var(--rc-primary,#0d6efd);}
.print-header .print-header-org{font-size:.85rem;color:#54697d;}

@media print{
  .app-sidebar,.app-topbar,.sidebar-backdrop,.app-footer,.no-print{display:none!important;}
  .app-shell{margin-left:0!important;}
  .app-content{padding:0!important;}
  body{background:#fff;}
  /* หน้าพิมพ์/ส่งออก PDF ของรายงาน (reports.php ฯลฯ) เรียก layout_header(..., true) แบบเดียวกับหน้าสาธารณะ
     (login.php/hub.php) จึงได้ class="bare-page" ของ <body> มาด้วย ซึ่งปกติมีไว้ใส่พื้นหลังไล่สีเข้มสวยๆ ให้หน้า
     สาธารณะ — แต่ .bare-page เป็น class selector (specificity สูงกว่า) จึงชนะกฎ "body{background:#fff}" ด้านบน
     (เป็น element selector ธรรมดา) แม้อยู่ใน @media print ก็ตาม ทำให้พิมพ์/ส่งออก PDF ออกมาพื้นหลังสีน้ำเงินเข้ม
     เข้าตัวหนังสือจนอ่านไม่ออกในบางจุด ต้องเจาะจงทับ .bare-page ให้เป็นสีขาวด้วยตรงๆ ในโหมดพิมพ์ */
  .bare-page{background:#fff;}
  .card{box-shadow:none;border-color:#ccc;}
  .print-header{
    display:flex!important;align-items:center;gap:.85rem;
    border-bottom:2px solid #22303c;padding-bottom:.6rem;margin-bottom:1rem;
  }
  .print-footer{display:block!important;margin-top:1rem;padding-top:.6rem;border-top:1px solid #ccc;font-size:.8rem;color:#54697d;}
}

/* ---------------- ปฏิทินจองห้องประชุม ----------------
 * เดิมมีมุมมองรายวัน/รายสัปดาห์ (ตารางแบบคอลัมน์+ช่วงเวลา) ด้วย แต่ตัดออกแล้วเหลือเฉพาะมุมมองรายเดือน
 * (ดู booking.php) จึงเหลือไว้เฉพาะสไตล์ .cal-block/.cal-legend-dot ที่มุมมองรายเดือนยังใช้ร่วมอยู่
 */
.cal-block{
  position:absolute;left:2px;right:2px;border-radius:.35rem;padding:.15rem .4rem;
  font-size:.7rem;line-height:1.25;overflow:hidden;color:#fff;cursor:pointer;
  box-shadow:0 1px 2px rgba(0,0,0,.2);z-index:2;
}
.cal-block small{display:block;opacity:.9;font-size:.66rem;}
.cal-block.status-confirmed{background:#0d6efd;}
.cal-block.status-pending{background:#fd7e14;border:1px dashed rgba(255,255,255,.8);}
.cal-legend-dot{display:inline-block;width:.7rem;height:.7rem;border-radius:.2rem;vertical-align:middle;margin-right:.25rem;}
.cal-legend-dot.status-confirmed{background:#0d6efd;}
.cal-legend-dot.status-pending{background:#fd7e14;}

/* ---------------- ปฏิทินจองห้องประชุม: มุมมองรายเดือน ---------------- */
/* .month-wrap เดิม overflow:hidden (บังคับตัด/ไม่เลื่อน) ผู้ใช้แจ้งว่าบนมือถือปฏิทินถูกบีบจนตัวเล็กอ่านยาก
   (ดูค่าที่เคยลด font-size/height ใน @media (max-width:767.98px) ด้านล่าง — ตอนนี้เอาออกแล้ว) เปลี่ยนแนวทางเป็น
   "ไม่บีบ ให้เลื่อน/สไลด์ดูแทน": .month-weekday-row กับ .month-grid ตั้ง min-width ไว้เท่ากัน (ต้องเท่ากันเพราะเป็น
   ลูกที่เลื่อนไปด้วยกันภายใต้ .month-wrap เดียวกัน) บนจอกว้างค่า min-width นี้ไม่มีผล (grid-template-columns:
   repeat(7,1fr) ขยายเต็มความกว้างคอนเทนเนอร์อยู่แล้วซึ่งกว้างกว่า) แต่บนจอแคบกว่าค่านี้จะดันให้ .month-wrap ล้นและ
   เลื่อนแนวนอนได้ (overflow-x:auto) โดยแต่ละช่องวันยังคงขนาดเท่าจอกว้างเสมอ ไม่ถูกบีบ overflow-y:hidden ไว้เพื่อยัง
   ตัดขอบให้เข้ากับ border-radius ด้านบน/ล่างเหมือนเดิม (แกน Y ไม่มีเนื้อหาที่ควรล้นอยู่แล้ว)

   (แก้เพิ่ม) เดิมใส่ -webkit-overflow-scrolling:touch ไว้ด้วยเพื่อให้ลื่นขึ้นตอนเลื่อนแนวนอนบน iOS แต่พบว่าไปชน
   กับบั๊กเดียวกันกับที่เคยเจอที่ .app-content (ดูคำอธิบายที่ transform ด้านบนของไฟล์นี้): คุณสมบัตินี้ทำให้ WebKit/
   Safari บน iOS สร้าง compositing layer แยกให้ .month-wrap ซึ่งมีผลข้างเคียงแบบเดียวกับการใส่ transform — ทำให้
   ลูกหลานที่เป็น position:fixed (คือ .day-popup-overlay ของ room_status.php ด้านล่าง ซึ่งอยู่ภายใน .month-grid/
   .month-wrap ตามโครงสร้าง checkbox hack) ถูกยึดตำแหน่งอ้างอิงกับ .month-wrap แทนวิวพอร์ต แล้วโดน overflow-y:hidden
   ของ .month-wrap ตัดจนมองไม่เห็น (ผู้ใช้แจ้งว่า "popup หาย" ตอนเปิดในมือถือ) — เอา -webkit-overflow-scrolling:touch
   ออก (ไม่จำเป็นอีกต่อไปบน iOS รุ่นใหม่ที่ overflow-x:auto ลื่นแบบ momentum ได้เองอยู่แล้วตั้งแต่ iOS 13) เพื่อไม่ให้
   สร้าง compositing layer นี้ ป็อปอัปจึงกลับมาอ้างอิงวิวพอร์ตได้ถูกต้องเหมือนเดิม ไม่กระทบการเลื่อนแนวนอนแต่อย่างใด */
.month-wrap{
  border:1px solid #dee2e6;border-radius:.5rem;background:#fff;
  overflow-x:auto;overflow-y:hidden;
}
.month-weekday-row{display:grid;grid-template-columns:repeat(7,1fr);background:#f8f9fa;border-bottom:1px solid #dee2e6;min-width:700px;}
.month-weekday{padding:.5rem;text-align:center;font-size:.8rem;font-weight:600;color:#495057;}
.month-grid{display:grid;grid-template-columns:repeat(7,1fr);grid-auto-rows:1fr;min-width:700px;}
/* ความสูงคงที่ (ไม่ใช่ min-height) ทุกช่องวันจะได้เท่ากันหมดไม่ว่าจะมีรายการจองกี่รายการ — เดิมใช้ min-height ทำให้
   แถวที่มีวันซึ่งมีรายการจองเยอะยืดสูงกว่าแถวอื่น ดูไม่เป็นตาราง เพราะฝั่ง PHP จำกัดจำนวนที่แสดงต่อวันไว้แล้วสูงสุด
   3 รายการ (ดู $maxShow ที่ booking.php/room_status.php) ที่เกินจะยุบเป็น "+N เพิ่มเติม" อยู่แล้ว ความสูงคงที่นี้จึง
   พอสำหรับ เลขวันที่ 1 บรรทัด + รายการ 3 แถว + บรรทัด "+N เพิ่มเติม" เสมอ ใส่ overflow:hidden กันไว้เผื่อกรณีขอบๆ */
.month-day{
  height:6.6rem;overflow:hidden;position:relative;
  border-right:1px solid #f1f3f5;border-top:1px solid #f1f3f5;
  padding:.3rem;cursor:pointer;box-sizing:border-box;
}
.month-day:nth-child(7n){border-right:none;}
.month-day:hover{background:rgba(13,110,253,.06);}
.month-day.cal-today{background:#fffceb;}
.month-day.cal-today:hover{background:#fff8d6;}
.month-day-out{background:#fafbfc;color:#adb5bd;}
.month-day-out .month-day-num{color:#adb5bd;}
.month-day-num{font-size:.78rem;font-weight:600;margin-bottom:.2rem;}
/*
 * ปฏิทินเลือกวันจองของ book.php (ลิงก์สาธารณะ) — เดิมใช้ <a> เป็นแท็กของแต่ละช่องวันเพื่อคลิกแล้วนำทางได้ทันที
 * โดยไม่ต้องพึ่ง JavaScript แต่ตอนนี้เปลี่ยนมาใช้ <div> + JS (คลิกแล้วอ่านค่าจาก data-href แล้วค่อยสั่ง
 * location.href เอง) เหมือน room_status.php/booking.php แล้ว เพื่อรองรับฟีเจอร์ใหม่ที่ต้องแยกแยะจังหวะคลิก:
 * คลิกโดนรายการจอง/ปุ่ม "+N เพิ่มเติม" (ตอนดู "ทุกห้อง") ต้องเปิดโมดัลดูรายละเอียดแทนการเปลี่ยนวันที่ และคลิกวันที่
 * ยื่นคำขอไม่ได้ต้องมี popup alert เตือนก่อนนำทาง ซึ่งทำไม่ได้ถ้ายังใช้ <a href> ธรรมดา (ดู book.php ท้ายไฟล์)
 */
/* วันที่ยื่นคำขอจองสาธารณะไม่ได้ (เสาร์-อาทิตย์/วันหยุด/ล่วงหน้าไม่พอ) — ยังคลิกดูได้ตามปกติ (จะเห็นเหตุผลที่แถบแจ้งเตือน
   ด้านล่างปฏิทินหลังคลิก) แค่แต้มสีเตือนไว้ล่วงหน้าไม่ให้เข้าใจผิดว่าเลือกได้เหมือนวันทำการปกติ */
.month-day-restricted{background:#fff5f5;}
.month-day-restricted .month-day-num{color:#c92a2a;}
.month-day-restricted-swatch{display:inline-block;width:.7rem;height:.7rem;border-radius:.2rem;vertical-align:middle;margin-right:.25rem;background:#fff5f5;border:1px solid #ffc9c9;}
/* วันที่เลือกอยู่ตอนนี้ (ค่าที่จะถูกใช้จริงตอนส่งฟอร์มด้านล่างปฏิทิน) เน้นด้วยกรอบสีฟ้าให้ชัดเจนแยกจาก "วันนี้" (cal-today) */
.month-day-selected{outline:2px solid #0d6efd;outline-offset:-2px;}
/* วันที่ไม่มีรายการจองเลย ไม่ต้องมี label/popup ครอบ (ดู room_status.php) จึงไม่ควรมีเมาส์ชี้แบบคลิกได้ */
.month-day-empty{cursor:default;}
.month-day-empty:hover{background:none;}
.month-day-empty.cal-today:hover{background:#fffceb;}
/*
 * พื้นหลังของรายการจอง = สีประจำห้องนั้นๆ โดยตรง (กำหนดด้วย inline style ที่ตัวรายการเลย ดู room_color ที่
 * booking.php/room_status.php) ทำให้มองออกว่าเป็นห้องไหนได้ทันทีจากสีพื้นหลัง โดยเฉพาะตอนดูรวม "ทุกห้อง" ในวันเดียว
 * ที่มีหลายห้องปนกัน — เดิมใช้สีพื้นหลังแทนสถานะ (ยืนยัน/รออนุมัติ) แล้วมีแถบสีประจำห้องบางๆ แปะข้างซ้ายแทน แต่สลับ
 * มาให้สีพื้นหลังเป็นสีห้องแทน ส่วนสถานะ "รออนุมัติ" ยังคงแยกแยะได้ด้วยกรอบเส้นประเหมือนเดิม (.status-pending)
 * ห้องที่ยังไม่ได้ตั้งสีไว้ (หรือระบบยังไม่มีคอลัมน์ rooms.color) จะไม่มี inline style จึงใช้สีสถานะเดิมเป็นค่าสำรอง
 * (.status-confirmed/.status-pending ด้านบน)
 */
.cal-block.cal-block-month{
  position:static;margin:0 0 2px;overflow:hidden;font-size:.68rem;box-shadow:none;
  padding:.15rem .4rem;
}
.cal-block.cal-block-month .cal-block-text{
  display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;
}
/* booking.php (เจ้าหน้าที่ มี JS) — ปุ่ม "+N เพิ่มเติม" เปิดโมดัล Bootstrap แสดงรายการทั้งหมดของวันนั้น */
.month-day-more{
  display:block;width:100%;text-align:left;font-size:.68rem;color:#495057;text-decoration:none;margin-top:.1rem;
  background:none;border:0;padding:0;font-family:inherit;cursor:pointer;
}
.month-day-more:hover{text-decoration:underline;}
/* ป้ายบอกใบ้ "+N เพิ่มเติม" ของ room_status.php — ไม่ใช่ปุ่ม/ลิงก์แยก แค่ข้อความอยู่ในช่องวันเดียวกัน เพราะทั้งช่อง
   วันเป็น label เปิดป็อปอัปได้อยู่แล้ว (ดูด้านล่าง) ไม่ต้องคลิกเจาะจงตรงข้อความนี้ก็เปิดได้เหมือนกัน */
.month-day-more-hint{font-size:.68rem;color:#495057;margin-top:.1rem;}

/*
 * room_status.php (หน้าสาธารณะ ไม่มี JavaScript เลยสักบรรทัด) ใช้เทคนิค "checkbox hack" แทนการเปิด modal ด้วย JS:
 * ทั้งช่องวันที่มีรายการจองอย่างน้อย 1 รายการจะเป็น <label for="เช็คบ็อกซ์ที่ซ่อนไว้ของวันนั้น"> คลิกตรงไหนของช่อง
 * ก็ได้ (ไม่ใช่แค่ "+N เพิ่มเติม") เพื่อกาเครื่องหมาย ทำให้ป็อปอัปแสดงรายการทั้งหมดของวันนั้นลอยขึ้นกลางจอ พร้อมพื้น
 * หลังสีเข้มคลุมทั้งหน้า ปิดได้ด้วยคลิกพื้นหลังหรือปุ่ม × (ทั้งคู่เป็น label ผูกกับเช็คบ็อกซ์เดียวกัน คลิกซ้ำ = ถอด
 * เครื่องหมาย = ปิด) เช็คบ็อกซ์และกล่องป็อปอัปตั้ง position:absolute/fixed (หรือ display:none ตอนปิด) เสมอ จึงไม่ถูก
 * นับเป็นช่องในตาราง .month-grid (CSS Grid ไม่นับ item ที่ absolute/fixed/none เป็นส่วนหนึ่งของกริด) ไม่กระทบผัง 7
 * คอลัมน์เดิม — วันที่ไม่มีรายการจองยังคงเป็น <div> ธรรมดาไม่มี label ครอบ (ดู room_status.php)
 *
 * สำคัญ: ใช้ตัวเชื่อม "+" (immediate sibling ตัวถัดไปตัวเดียว) ไม่ใช่ "~" (general sibling ทุกตัวที่ตามมา) — เพราะ
 * checkbox ของทุกวันเป็น sibling แบนราบเดียวกันหมดภายใต้ .month-grid ถ้าใช้ "~" พอวันไหนวันหนึ่งถูกกาเครื่องหมาย จะ
 * ทำให้ป็อปอัปของ "ทุกวันถัดไป" ในเดือนเดียวกันเปิดขึ้นมาพร้อมกันหมดโดยไม่ได้ตั้งใจ (เจอบั๊กนี้ตอนทดสอบจริง) จึงต้อง
 * วางกล่องป็อปอัป (.day-popup-overlay) ไว้เป็น sibling ที่อยู่ "ติดกันทันที" หลัง checkbox ของวันนั้นเท่านั้น (ก่อน
 * label ของช่องวัน) ให้ "+" จับคู่ได้เฉพาะป็อปอัปของ checkbox ตัวที่ถูกกาเครื่องหมายจริงๆ ตัวเดียว
 */
.day-popup-toggle{position:absolute;opacity:0;width:0;height:0;pointer-events:none;}
.day-popup-overlay{display:none;}
.day-popup-toggle:checked + .day-popup-overlay{
  display:flex;position:fixed;inset:0;z-index:1050;align-items:flex-start;justify-content:center;
  padding:8vh 1rem 1rem;
}
.day-popup-backdrop{position:absolute;inset:0;background:rgba(0,0,0,.55);cursor:pointer;}
.day-popup-panel{
  position:relative;width:100%;max-width:420px;max-height:80vh;overflow-y:auto;
  background:#fff;border-radius:.6rem;box-shadow:0 12px 32px rgba(0,0,0,.3);padding:1rem;cursor:default;
}
.day-popup-header{
  display:flex;align-items:center;justify-content:space-between;gap:.5rem;margin-bottom:.6rem;
  padding-bottom:.5rem;border-bottom:1px solid #e9ecef;
}
.day-popup-header strong{font-size:.95rem;color:#212529;}
.day-popup-close{cursor:pointer;font-size:1.3rem;line-height:1;color:#868e96;padding:0 .3rem;}
.day-popup-close:hover{color:#495057;}
.day-popup-list{list-style:none;margin:0;padding:0;}
.day-popup-list li{
  display:flex;align-items:flex-start;gap:.5rem;padding:.5rem 0;font-size:.82rem;color:#212529;
  border-bottom:1px solid #f1f3f5;
}
.day-popup-list li:last-child{border-bottom:none;}
.day-popup-list .cal-legend-dot{margin-top:.25rem;flex:0 0 auto;}
@media (max-width:767.98px){
  /* เดิมลดขนาดตัวอักษร/ความสูงของช่องปฏิทิน (.month-weekday/.month-day/.month-day-num/.cal-block-month) ที่นี่
     เพื่อให้ 7 คอลัมน์พอดีความกว้างจอมือถือ แต่ผู้ใช้แจ้งว่าตัวเล็กจนอ่านยาก จึงเอากฎบีบขนาดออก แล้วให้ปฏิทินคง
     ขนาดเท่าจอกว้างเสมอ เลื่อนดูแนวนอนแทน (ดู .month-wrap/.month-weekday-row/.month-grid ด้านบน) เหลือไว้เฉพาะ
     ส่วนของป็อปอัป "+N เพิ่มเติม" ที่ยังต้องปรับสำหรับจอมือถือ (ไม่เกี่ยวกับการบีบขนาดตาราง) */
  .day-popup-toggle:checked ~ .day-popup-overlay{padding:5vh .75rem .75rem;}
  .day-popup-panel{max-height:88vh;}
}
/*
 * ช่องกรอกเวลาแบบ 24 ชั่วโมง (แทนที่ <input type="time"> เดิมทุกจุด — ดูคำอธิบายเหตุผลที่ assets/js/app.js)
 * ใช้เลขแบบความกว้างเท่ากัน (tabular-nums) ให้ตัวเลขเรียงชิดกันอ่านง่ายเหมือนนาฬิกาดิจิทัล ไม่ใช่ฟอนต์สัดส่วนปกติ
 */
.time24-input{font-variant-numeric:tabular-nums;letter-spacing:.03em;}

/*
 * ช่องกรอกวันที่สำหรับ "+ เพิ่มวันที่" (book.php / booking.php) — ผู้ใช้แจ้งว่าช่องเดิมเล็กเกินไป อ่านตัวเลขวันที่ยาก
 * ขยายให้ใหญ่ขึ้นชัดเจน (ตัวหนา ตัวใหญ่ขึ้น เว้นระยะภายในมากขึ้น) และกว้างพอที่จะไม่บีบตัวเลขปี พ.ศ./ค.ศ. ให้ดูอึดอัด
 */
.date-add-input{
  font-size:1.15rem;
  font-weight:400;
  padding:.55rem .75rem;
  min-width:180px;
  max-width:230px;
  font-variant-numeric:tabular-nums;
}
@media (max-width:575.98px){
  .date-add-input{min-width:0;max-width:100%;width:100%;}
}

/*
 * "ชิป" แสดงวันที่ที่เลือกไว้แล้ว (เหนือช่อง "+ เพิ่มวันที่" — book.php / booking.php) — เดิมใช้คลาส badge ของ
 * Bootstrap ซึ่งตัวอักษรเล็กมาก (~0.75em) ผู้ใช้แจ้งว่ามองยาก จึงแทนที่ด้วยคลาสนี้ (ตัวใหญ่ขึ้นชัดเจน ไม่ใช่ badge เล็กๆ
 * อีกต่อไป) และแสดงวันที่เป็นรูปแบบไทยอ่านง่าย (เช่น "14 ก.ย. 2569") แทนรูปแบบ ISO ดิบ (เช่น "2026-09-14") ที่ตีความยาก
 */
.date-chip{
  display:inline-flex;align-items:center;gap:.5rem;
  font-size:1.05rem;font-weight:400;
  padding:.5rem .85rem;
  border-radius:.5rem;
  background:#fff;border:1.5px solid #adb5bd;color:#212529;
}
.date-chip .btn-close{font-size:.85rem;}
@media (max-width:575.98px){
  .date-chip{font-size:.95rem;padding:.45rem .7rem;}
}

/*
 * ตัวเลขหน้า (pagination) ท้ายตารางรายการ (inspections.php / maintenance.php / rooms.php / usage_log.php) — ค่า
 * เริ่มต้นของ Bootstrap คือ display:flex แถวเดียวไม่มีการตัดขึ้นบรรทัดใหม่ ถ้ามีจำนวนหน้าเยอะ (ผลการค้นหา/รายการเยอะ)
 * รายการเลขหน้าจะ "ยาวเกินความกว้างจอ" โดยเฉพาะบนมือถือ ทำให้ล้นออกนอกกรอบการ์ด/นอกจอแทนที่จะตัดขึ้นบรรทัดใหม่
 * แก้ด้วยการอนุญาตให้ตัดขึ้นบรรทัดใหม่ได้ (flex-wrap) พร้อมเว้นระยะห่างระหว่างบรรทัดเล็กน้อย — ใช้ได้ทุกขนาดจอ
 * (ไม่ใช่แค่มือถือ) เพราะไม่มีผลเสียตอนที่ตัวเลขพอดีอยู่แล้วในบรรทัดเดียว
 */
.pagination{flex-wrap:wrap;row-gap:.35rem;}
