/* PPK Medical - reset, buttons, cards, and components reused across multiple apps */

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--card-bg);
  color: var(--ink-900);
  font-family: 'Prompt', 'Inter', system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* กันไว้อีกชั้น เผื่อ element ไหนในอนาคตดันความกว้างเกินจอ จะโดนตัดแทนที่จะทำให้ทั้งหน้า scroll แนวนอนได้ */
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }
h1, h2, h3, p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

.card {
  background: var(--card-bg);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.08);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px 18px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.85rem;
  white-space: nowrap;
}

.btn-alert-cta { background: var(--accent-green); color: #fff; }
.btn-export { background: var(--accent-green); color: #fff; }

.dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; }
.dot-good { background: var(--status-good); }
.dot-bad { background: var(--status-critical); }
.dot-blue { background: var(--gender-male); }
.dot-green { background: var(--gender-female); }

/* ---------- SOS/fall/vital modal (priority alert queue) ---------- */
/* กลางจอ ไม่ใช่แถบบนสุดแบบเดิม (.alert-banner) — โชว์แค่ตัวหน้าคิวตัวเดียวเสมอ (ดู
   core/services.py::build_alert_modal) แสดง/ซ่อนล้วนขับเคลื่อนจาก server (ไม่มี client toggle) จึง
   ไม่ต้องพึ่ง JS — z-index สูงกว่า drawer-backdrop (30) เพราะต้องอยู่บนสุดของหน้าเสมอ */

.sos-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(10, 24, 48, 0.6);
  /* ฉากหลังทั้งจอกะพริบแดงสลับกับพื้นเข้ม — เห็นได้จากมุมตาแม้ไม่ได้มองที่ popup (ผู้ใช้บอกว่ากะพริบยัง
     น้อยไป) รอบ 0.9 วินาที (~1.1 Hz) ต่ำกว่าเกณฑ์ 3 Hz ที่เสี่ยงต่อผู้ไวต่อแสงกะพริบ */
  animation: sos-backdrop-flash 0.9s ease-in-out infinite;
}

@keyframes sos-backdrop-flash {
  0%, 100% { background: rgba(10, 24, 48, 0.6); }
  50% { background: rgba(220, 38, 38, 0.62); }
}

/* triage-popup แทน .sos-modal เดิม (กล่องแดงเล็ก ชื่อ+ปุ่มรับทราบ) — ตอนนี้ต้องพอมีที่แสดงข้อมูลคัด
   แยกครบ (โรคประจำตัว/สัญญาณชีพ/ที่ตั้ง/เบอร์ติดต่อ + 4 ปุ่ม action) จึงแยกหัว (สีแดง เร่งด่วน) กับตัว
   เนื้อหา (พื้นขาว อ่านง่าย) แทนที่จะให้ทั้งกล่องเป็นพื้นแดงตัวหนังสือขาวเหมือนเดิม ซึ่งอ่านข้อมูลเยอะๆ
   ไม่ไหว — max-height + overflow-y เพราะเนื้อหาอาจสูงกว่าจอ (โดยเฉพาะจอเตี้ยอย่างแท็บเล็ตแนวนอน) */
.triage-popup {
  width: 100%;
  max-width: 640px;
  max-height: 92vh;
  overflow-y: auto;
  background: var(--card-bg);
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
  animation: sos-modal-pulse 0.9s ease-in-out infinite;
}

/* กระพริบให้รู้สึกเร่งด่วนจริง — เคยไม่กระพริบแล้วดูเหมือนไม่สำคัญพอ (ผู้ใช้ยืนยันแล้ว) แล้วเคยกะพริบเบา
   เกินไปอีก (ผู้ใช้บอกอีกรอบ) จึงขยายวงแสงรอบกล่องและเพิ่มความสว่างของสีแดงให้เห็นชัดขึ้น */
@keyframes sos-modal-pulse {
  0%, 100% {
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35), 0 0 0 0 rgba(239, 68, 68, 1),
      0 0 24px 6px rgba(239, 68, 68, 0.9);
  }
  50% {
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35), 0 0 0 34px rgba(239, 68, 68, 0),
      0 0 80px 30px rgba(239, 68, 68, 0);
  }
}

/* ผู้ใช้ที่ตั้งค่า "ลดการเคลื่อนไหว" ในระบบปฏิบัติการ ไม่ต้องเจอฉากหลังทั้งจอกะพริบ — ยังคงวงแสงรอบกล่อง
   และหัวสีแดงกะพริบไว้ (ยังเห็นชัดว่าเป็นเหตุฉุกเฉิน) แต่ไม่กะพริบทั้งหน้าจอ */
@media (prefers-reduced-motion: reduce) {
  .sos-modal-backdrop { animation: none; }
}

.triage-popup-head {
  display: flex;
  align-items: center;
  gap: 12px;
  background: linear-gradient(120deg, #991b1b, var(--status-critical));
  color: #fff;
  border-radius: 16px 16px 0 0;
  padding: 16px 20px;
  position: sticky;
  top: 0;
  animation: sos-head-flash 0.9s ease-in-out infinite;
}

/* หัวแดงสว่างสลับเข้ม จังหวะเดียวกับฉากหลังและวงแสงรอบกล่อง */
@keyframes sos-head-flash {
  0%, 100% { filter: brightness(0.9); }
  50% { filter: brightness(1.6) saturate(1.3); }
}

.triage-popup-icon {
  font-size: 1.8rem;
  line-height: 1;
  flex: none;
  animation: sos-modal-icon-blink 0.9s ease-in-out infinite;
}

@keyframes sos-modal-icon-blink {
  0%, 100% { opacity: 1; transform: scale(1.15) rotate(-10deg); }
  50% { opacity: 0.15; transform: scale(0.9) rotate(10deg); }
}

.triage-popup-head-text { flex: 1; min-width: 0; }
.triage-popup-title { font-weight: 700; font-size: 1rem; line-height: 1.35; }
.triage-popup-sub-link { color: #fecaca; font-size: 0.75rem; text-decoration: none; }
.triage-popup-sub-link:hover { text-decoration: underline; }

.triage-popup-timer {
  flex: none;
  text-align: center;
  background: rgba(0, 0, 0, 0.25);
  border-radius: 10px;
  padding: 5px 12px;
}
.triage-popup-timer-label { display: block; font-size: 0.62rem; opacity: 0.85; }
.triage-popup-timer-value { display: block; font-size: 1.1rem; font-weight: 700; font-variant-numeric: tabular-nums; }

.triage-popup-body {
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.triage-popup-identity { display: flex; align-items: center; gap: 12px; }
.triage-popup-meta { display: block; font-size: 0.72rem; font-weight: 400; color: var(--ink-600); margin-top: 2px; }

.triage-popup-block-label { font-size: 0.72rem; font-weight: 600; color: var(--ink-600); margin-bottom: 6px; }

.med-chips, .contact-chips { display: flex; flex-wrap: wrap; gap: 6px; }

.med-chip {
  background: #fff7e6;
  border: 1px solid #ffe082;
  color: #7a5800;
  font-size: 0.72rem;
  font-weight: 500;
  border-radius: 12px;
  padding: 3px 11px;
}
.med-chip-caution {
  background: #fde8e8;
  border-color: #ffcdd2;
  color: var(--status-critical);
  font-weight: 600;
}

.contact-chip {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--surface);
  border-radius: 10px;
  padding: 6px 12px;
  font-size: 0.72rem;
  color: var(--ink-600);
}
.contact-chip b { color: var(--ink-900); font-size: 0.8rem; }

.triage-popup-location { font-size: 0.8rem; color: var(--ink-900); }

.triage-popup-actions {
  border-top: 1px solid var(--border);
  padding: 12px 20px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* วางปุ่มเรียงคอลัมน์เดียวก่อนบนจอแคบ (ปุ่มมีข้อความยาวอย่าง "เปิดเคสส่งกู้ชีพ" เบียดกันไม่พอถ้าวางคู่
   บนมือถือ) แล้วค่อยขยับเป็น 2 ต่อแถวตั้งแต่ 480px ขึ้นไป */
.triage-popup-row { display: flex; flex-direction: column; gap: 8px; }
.triage-popup-row form { display: flex; }
.triage-popup-row form .btn { width: 100%; }

@media (min-width: 480px) {
  .triage-popup-row { flex-direction: row; }
  .triage-popup-row form { flex: 1; }
  .triage-popup-row > .btn { flex: 1; }
}

/* เฉพาะเคสล้มที่ปลดล็อกปุ่มเพราะหมดเวลารอวัดค่า ไม่ใช่วัดได้ครบจริง (ดู
   core/services.py::build_alert_modal, "vitals_stale") */
.triage-popup-waiting-note {
  margin-top: 4px;
  font-size: 0.78rem;
  color: var(--status-warning);
  text-align: center;
}

.btn-alert-ack { background: var(--status-info); color: #fff; }
.btn-alert-call { background: #fff; color: var(--accent-green); border: 1.5px solid var(--accent-green); }
.btn-alert-cancel { background: #fff; color: var(--ink-600); border: 1.5px solid var(--border); }
.btn-alert-dispatch { background: var(--status-critical); color: #fff; }
.btn-alert-close { background: var(--accent-green); color: #fff; }

/* ---------- แบนเนอร์ลิงก์ใบงานฉุกเฉิน (patient_detail.html หลังส่งกู้ชีพ) ---------- */
/* ยังไม่มี LINE Official Account จริง (ดู alerts/services.py::queue_dispatch_notification) —
   แบนเนอร์นี้คือจุดที่เจ้าหน้าที่คัดลอกลิงก์ไปส่งเอง วันที่มี LINE API แล้วจะมีปุ่ม "ส่งอัตโนมัติ"
   มาแทนที่ตรงนี้จุดเดียว ไม่ต้องแก้ที่อื่น */
.dispatch-banner {
  border: 2px solid var(--status-info);
  background: #eff6ff;
}
.dispatch-banner-title { font-weight: 700; font-size: 0.9rem; margin-bottom: 4px; }
.dispatch-banner-note {
  font-size: 0.75rem;
  color: var(--ink-600);
  background: #fff7e6;
  border: 1px solid #ffe082;
  border-radius: 8px;
  padding: 6px 10px;
  margin-bottom: 10px;
}
.dispatch-banner-field { margin-bottom: 8px; }
.dispatch-banner-label { display: block; font-size: 0.68rem; color: var(--ink-600); margin-bottom: 3px; }
.dispatch-banner-link-input {
  width: 100%;
  font-family: inherit;
  font-size: 0.78rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 10px;
  background: #fff;
  color: var(--ink-900);
}
.dispatch-banner-message {
  white-space: pre-wrap;
  font-size: 0.78rem;
  color: var(--ink-900);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
}

/* ---------- "งานที่ยังไม่จบ" dropdown (checkbox hack แบบเดียวกับ drawer — ไม่มี JS) ---------- */
/* .open-cases-toggle ต้องอยู่นอก .shell เป็น sibling ของมัน (เหมือน .drawer-toggle) ให้ตัวเลือก
   ":checked ~ .shell ..." เอื้อมเข้าไปหา .open-cases-dropdown ที่ซ้อนอยู่ข้างในได้ */
.open-cases-toggle { position: absolute; opacity: 0; pointer-events: none; }

.open-cases-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 35;
  background: transparent;
}

.open-cases-toggle:checked ~ .open-cases-backdrop { display: block; }

.open-cases-widget { position: relative; }

.open-cases-dropdown {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 10px;
  width: min(360px, 90vw);
  max-height: min(70vh, 480px);
  overflow-y: auto;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 12px 32px rgba(16, 24, 40, 0.16);
  z-index: 45;
  padding: 14px;
}

.open-cases-toggle:checked ~ .shell .open-cases-dropdown { display: block; }

.open-cases-dropdown-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  margin-bottom: 10px;
}

.open-cases-dropdown-count {
  background: var(--status-critical);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  min-width: 20px;
  height: 20px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 6px;
}

.open-cases-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border-radius: 10px;
  color: inherit;
  text-decoration: none;
}
.open-cases-item:hover { background: var(--surface); }

.open-cases-item-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.open-cases-item-name { font-weight: 600; font-size: 0.88rem; }
.open-cases-item-sub { font-size: 0.76rem; color: var(--ink-600); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.open-cases-empty { color: var(--ink-600); font-size: 0.85rem; padding: 8px; }

.open-cases-viewall {
  display: block;
  text-align: center;
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-weight: 700;
  color: var(--status-info);
}

/* ---------- popup สถานะรายเคส (กดจากรายการ "งานที่ยังไม่จบ") ---------- */
/* ทรง/สไตล์เดียวกับ .triage-popup (popup แจ้งเตือน SOS/ล้ม) ตามที่ผู้ใช้ยืนยัน แต่ไม่กระพริบ (ไม่ใช่
   เหตุฉุกเฉิน แค่เช็คสถานะ) checkbox-hack แยกต่างหากต่อ 1 เคส (id ผูกกับ case.id) ซ้อนอยู่ใน
   .case-status-trigger เดียวกันทั้ง 3 ส่วน (checkbox/backdrop/modal) เป็น general sibling กัน ทำให้
   ใช้ selector เดียวกันซ้ำได้ทุกเคสโดยไม่ต้องเขียน CSS แยกทีละ id — ต่างจาก .open-cases-toggle ที่ต้อง
   เอื้อมออกไปนอก .shell (ตัวนี้ไม่ต้อง เพราะ backdrop/modal ซ้อนอยู่ในบล็อกเดียวกับ checkbox อยู่แล้ว) */
.case-status-toggle { position: absolute; opacity: 0; pointer-events: none; }

.case-status-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 46;
  background: rgba(10, 24, 48, 0.5);
}

.case-status-toggle:checked ~ .case-status-backdrop { display: block; }

.case-status-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 47;
  align-items: center;
  justify-content: center;
  padding: 16px;
  pointer-events: none;
}

.case-status-toggle:checked ~ .case-status-modal { display: flex; }

.case-status-modal-inner {
  position: relative;
  width: 100%;
  max-width: 480px;
  max-height: 92vh;
  overflow-y: auto;
  background: var(--card-bg);
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
  padding: 20px;
  pointer-events: auto;
}

.case-status-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--surface);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-weight: 700;
}

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--navy-700);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
}

/* ---------- content ---------- */

/*
  .content เป็น grid item ของ .shell — ถ้าไม่ set min-width:0 ความกว้าง "1fr" ของ grid track
  จะยอมโดนดันกว้างเกินจอได้ถ้าเนื้อหาข้างในมี min-content ใหญ่ (เช่น tile-row ที่มี 3 การ์ดขั้นต่ำ
  120px ต่อใบ) auto-fit/1fr ที่ตั้งใจให้ reflow ตามพื้นที่จริงจะไม่ทำงานถ้า min-width chain ขาดตอน
*/
.groups-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.groups-head h2 { font-size: 1.1rem; font-weight: 700; }

.link-muted { font-size: 0.78rem; color: var(--status-info); font-weight: 600; }

.section-title { font-size: 0.85rem; font-weight: 700; margin-bottom: 12px; }

.risk-bg-high { background: rgba(239, 68, 68, 0.1); }
.risk-bg-medium { background: rgba(234, 179, 8, 0.1); }
.risk-bg-low { background: rgba(34, 197, 94, 0.08); }
.risk-bg-offline { background: rgba(107, 114, 128, 0.08); }
.patient-name { font-size: 0.95rem; font-weight: 700; white-space: normal; overflow-wrap: break-word; }
.patient-row-stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  min-width: 0;
}
@media (min-width: 1024px) {
  .patient-row-stats {
    flex: 1;
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
}

.stat-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface);
  border-radius: 12px;
  padding: 8px 12px;
  min-width: 0;
}

.stat-chip-abnormal {
  background: rgba(220, 38, 38, 0.08);
  box-shadow: inset 0 0 0 1px rgba(220, 38, 38, 0.3);
}

.stat-chip-icon { font-size: 1.05rem; flex: none; line-height: 1; }
.stat-chip-text { display: flex; flex-direction: column; min-width: 0; }
.stat-chip-value { font-size: 0.85rem; font-weight: 700; color: var(--ink-900); line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stat-chip-label { font-size: 0.63rem; color: var(--ink-600); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.filter-input,
.filter-select {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 12px;
  min-height: 42px;
  height: 42px;
  font-size: 0.88rem;
  line-height: 1.5;
  font-family: inherit;
  color: #0f172a;
  background: #ffffff;
  box-sizing: border-box;
}

.filter-select { flex: 0 0 auto; }
.avatar-lg { width: 52px; height: 52px; font-size: 1.05rem; }
.avatar-sm { width: 28px; height: 28px; font-size: 0.7rem; flex: none; }
.patient-row-stats-standalone { grid-template-columns: repeat(2, 1fr); }
.report-chart { margin-top: 16px; min-width: 0; }
.report-chart svg { width: 100%; height: auto; display: block; }

.report-chart-with-axis { display: flex; align-items: stretch; gap: 6px; }
.chart-y-axis-labels {
  flex: none;
  display: flex;
  flex-direction: column-reverse;
  justify-content: space-between;
  padding: 1px 0;
  font-size: 0.62rem;
  color: var(--ink-400);
  text-align: right;
}
.report-chart-body { flex: 1; min-width: 0; }

.report-chart-axis {
  display: flex;
  justify-content: space-between;
  margin-top: 6px;
  font-size: 0.65rem;
  color: var(--ink-400);
}
.report-chart-axis span { flex: 1; text-align: center; }

.chart-gridline { stroke: rgba(17, 24, 39, 0.08); stroke-width: 1; }

.btn-block {
  display: block;
  text-align: center;
  margin-top: auto;
  padding: 10px 0;
  border-radius: 999px;
  background: #14b8a6;
  color: #ffffff;
  font-weight: 700;
  font-size: 0.85rem;
  text-decoration: none;
}
.btn-block:hover { background: #0d9488; }

.akr-page { min-width: 0; }

.akr-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

.akr-header-title { display: flex; align-items: center; gap: 12px; min-width: 0; }

.akr-header-icon {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  color: #fff;
}

.akr-header-title h2 { font-size: 1.15rem; font-weight: 700; }
.akr-header-en { font-weight: 400; color: var(--ink-400); font-size: 0.85rem; }

.akr-range-form { display: flex; align-items: center; gap: 8px; margin: 0; }

.akr-btn-download {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid #bfdbfe;
  background: #dbeafe;
  color: #1d4ed8;
  font-size: 0.82rem;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
}
.akr-btn-download:hover { background: #bfdbfe; }

.akr-inline-icon { flex: none; vertical-align: -0.2em; }

.akr-table-wrap {
  overflow-x: auto;
  background: var(--dash-navy);
  border-radius: 14px;
  padding: 6px;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.08);
}

.akr-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; color: var(--ink-900); }
.akr-table th {
  text-align: left;
  padding: 10px 12px;
  color: var(--ink-600);
  font-weight: 600;
  white-space: nowrap;
  border-bottom: 1px solid var(--border);
}
.akr-table td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.akr-table a { color: var(--status-info); font-weight: 600; }
.akr-elapsed-warning { color: var(--status-critical); font-weight: 700; }

.akr-empty {
  background: var(--dash-navy);
  border-radius: 14px;
  padding: 28px 20px;
  text-align: center;
  color: var(--ink-600);
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.08);
}
.akr-empty-note { margin-top: 8px; font-size: 0.8rem; color: var(--ink-400); }

.hr-level-pill {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 700;
  white-space: nowrap;
}
.hr-level-high { background: rgba(239, 68, 68, 0.15); color: #b91c1c; }
.hr-level-medium { background: rgba(234, 179, 8, 0.18); color: #92400e; }
.hr-level-low { background: rgba(34, 197, 94, 0.15); color: #15803d; }
/* ถอดนาฬิกา/ขาดการติดต่อ — เทา ตั้งใจแยกจาก 3 สีข้างบน (ดู --status-offline ใน :root) */
.hr-level-offline { background: rgba(107, 114, 128, 0.15); color: #374151; }
/* กำลังดำเนินการ (ทีมกู้ชีพระบุตัวตนแล้ว) — คนละความหมายกับระดับความเสี่ยง 3 สีข้างบน จึงตั้งชื่อแยก
   ไม่ใช้ hr-level-medium (เหลือง สื่อ "ความเสี่ยง" ไม่ใช่ "กำลังทำงานอยู่") */
.hr-level-active { background: rgba(37, 99, 235, 0.15); color: #1d4ed8; }

.akr-table a.hr-detail-btn {
  background: rgba(56, 189, 248, 0.12);
  border: 1px solid rgba(56, 189, 248, 0.5);
  color: #38bdf8;
  padding: 7px 18px;
  font-size: 0.78rem;
  font-weight: 700;
}

.akr-table a.hr-detail-btn:hover { background: rgba(56, 189, 248, 0.22); }

/* ---------- หน้ายืนยันยกเลิกเคส (cancel_case_confirm.html) + หน้ายืนยันบันทึกความเสี่ยง
   (risk_note_confirm.html) ใช้โครงการ์ดยืนยันร่วมกัน ---------- */
.cancel-confirm-card { max-width: 480px; padding: 20px; display: flex; flex-direction: column; gap: 12px; }
.cancel-confirm-summary { font-size: 0.85rem; font-weight: 600; color: var(--status-critical); }
.cancel-confirm-warning {
  font-size: 0.78rem;
  color: var(--ink-600);
  background: #fff7e6;
  border: 1px solid #ffe082;
  border-radius: 8px;
  padding: 8px 10px;
}
.cancel-confirm-error {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--status-critical);
  background: #fde8e8;
  border: 1px solid #ffcdd2;
  border-radius: 8px;
  padding: 8px 10px;
}
.cancel-confirm-form { display: flex; flex-direction: column; gap: 6px; }
.cancel-confirm-label { font-size: 0.75rem; font-weight: 600; color: var(--ink-600); }
.cancel-confirm-reason {
  font-family: inherit;
  font-size: 0.85rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  resize: vertical;
}
/* วางคอลัมน์เดียวก่อนบนจอแคบ (ปุ่มข้อความยาวอย่าง "ยกเลิกเคส (False Alarm)" เบียดกันไม่พอถ้าวางคู่บน
   มือถือ) แล้วค่อยขยับเป็น 2 ต่อแถวตั้งแต่ 480px ขึ้นไป — แพทเทิร์นเดียวกับ .triage-popup-row */
.cancel-confirm-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 6px; }
@media (min-width: 480px) {
  .cancel-confirm-actions { flex-direction: row; }
}
.cancel-confirm-actions .btn { flex: 1; }

/* ---------- พิมพ์ / Export Report (ปุ่ม "Export Report" เรียก window.print() ตรงๆ ไม่มี
   PDF library ฝั่งเซิร์ฟเวอร์ ใช้ browser save-as-PDF แทน ไม่ต้องเพิ่ม dependency ใหม่) ---------- */

/* ขนาดกระดาษของรายงานที่พิมพ์/เซฟเป็น PDF ทั้งหมด (ยืนยันจากผู้ใช้ให้เป็น A4 เต็มหน้า) — โปรเจกต์นี้ไม่เคย
   ประกาศ @page มาก่อน เดิมปล่อยให้ default ของ browser/OS ตัดสินขนาดกระดาษเอง — margin แคบกว่าปกติเล็กน้อย
   (10mm แทน 14mm ทั่วไป) ให้มีพื้นที่เนื้อหาเหลือเผื่อไว้มากขึ้น เพราะบั๊กจริงที่ผู้ใช้เจอ: เบราว์เซอร์บาง
   ตัวแทรกหัว/ท้ายกระดาษของตัวเอง (URL, วันที่, เลขหน้า) ทับพื้นที่ margin นี้อีกชั้นถ้าผู้ใช้เปิดตัวเลือก
   "Headers and footers" ตอนพิมพ์ ซึ่งเป็นการตั้งค่าฝั่งเบราว์เซอร์ที่ CSS สั่งปิดไม่ได้ตรงๆ */
@page {
  size: A4;
  margin: 10mm;
}

@media print {
  .sidebar,
  .drawer-toggle,
  .drawer-backdrop,
  .hamburger-btn,
  .sos-modal-backdrop,
  .topbar-actions,
  .btn-export,
  .filter-bar,
  .link-muted,
  .akr-footer,
  .akr-range-form {
    display: none !important;
  }

  /* รายงานพิมพ์ต้องมีครบทุกคอลัมน์ (ยืนยันจากผู้ใช้ ไม่ตัดค่าใดออก) จึงลดขนาดตัวอักษร/ระยะห่างของตาราง
     รายงานความเสี่ยงและให้ป้ายในตารางขึ้นบรรทัดใหม่ได้ เพื่อให้ 8 คอลัมน์พอดีหน้ากระดาษแทนการซ่อนคอลัมน์ */
  .high-risk-report .akr-table { font-size: 0.7rem; }
  .high-risk-report .akr-table th,
  .high-risk-report .akr-table td { padding: 6px 3px; }
  .high-risk-report .akr-table .hr-level-pill,
  .high-risk-report .akr-table .risk-sla-pill { white-space: normal; text-align: center; padding: 3px 8px; }

  body { background: #fff; overflow-x: visible; }
  .shell { display: block; min-height: 0; }
  .content { padding: 0; }
  .content-row { display: block; }
  .group-grid { display: block; }
  .group-card { break-inside: avoid; margin-bottom: 16px; }
  .side-panel { margin-top: 16px; }
  .akr-table tr { break-inside: avoid; }

  /* browser ปิดพื้นหลัง/ไล่สีตอนพิมพ์เป็นค่าเริ่มต้น เพื่อประหยัดหมึก แต่หัวการ์ดกลุ่มโรค/การ์ดสรุปตัวเลข/
     ป้ายระดับความเสี่ยง/แท่งกราฟแนวโน้มของหน้ารายงาน (trend_report/high_risk_report และหน้าสรุป) ใช้สี
     เป็นตัวบอกความหมาย (ระดับวิกฤต/เฝ้าระวัง/ปกติ/ถอดนาฬิกา, ชนิดเหตุการณ์ในกราฟ) ต้องบังคับให้พิมพ์
     ออกมาจริงไม่งั้นจะอ่านความหมายไม่ออก — ใช้ * แทนไล่รายชื่อ class ทีละตัว (บั๊กจริงที่เจอ: รายชื่อเดิม
     ครอบแค่ .akr-stat-card/.hr-level-pill/.risk-sla-pill/.trend-insight-card เอง ไม่ครอบ
     .akr-stat-icon/.legend-dot-*/.bar (fill สี SVG ของแท่งกราฟ) เลยออกมาขาวดำ และพลาดง่ายทุกครั้งที่
     เพิ่ม element สีใหม่ เช่น .hr-level-offline — บังคับทั้งหน้าไปเลยตัดปัญหานี้ทั้งหมด) */
  * {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* บั๊กจริงที่เจอ (ยืนยันจากผู้ใช้): แม้ตั้ง print-color-adjust: exact ทั้งหน้าแล้ว เครื่องพิมพ์/ตัวแสดง
     ตัวอย่างก่อนพิมพ์ของบางเบราว์เซอร์ยังคงไม่แสดงพื้นหลังโปร่งแสง (rgba กับ alpha < 1) ของป้ายวงรีให้
     เต็มเหมือนบนจอ — เหลือแต่สีตัวอักษรเข้ม (เช่น #92400e ของ .hr-level-medium/.risk-sla-watch) ลอยอยู่
     บนพื้นขาวเปล่าๆ โดยไม่มีพื้นหลังเหลืองอ่อนช่วยให้ตีความสีถูก ทำให้ "เฝ้าระวัง" ดูเหมือนสีแดง/น้ำตาล
     ไม่ใช่เหลืองเหมือนตอนดูบนจอ ทั้งที่เป็นค่าสี/ระดับเดียวกันทุกประการ — บังคับพื้นหลังทึบกว่าเดิมเฉพาะ
     ตอนพิมพ์ (ไม่กระทบตอนดูบนจอปกติ) กันปัญหานี้แทนที่จะพึ่ง print-color-adjust อย่างเดียว */
  .hr-level-pill,
  .risk-sla-pill {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    border: 1px solid currentColor;
  }
  .hr-level-high,
  .risk-sla-sla_breach,
  .risk-sla-urgent { background: #fee2e2 !important; }
  .hr-level-medium,
  .risk-sla-reassess_due,
  .risk-sla-watch { background: #fef3c7 !important; }
  .hr-level-low,
  .risk-sla-ok,
  .risk-sla-normal { background: #dcfce7 !important; }
  .hr-level-offline { background: #e5e7eb !important; }
  .hr-level-active { background: #dbeafe !important; }

  /* หน้าผู้ป่วย: ดาวโหลดรายงาน — ชื่อผู้ป่วยซ้ำ 2 จุดบนจอ (topbar + การ์ดโปรไฟล์) เหลือจุดเดียวตอนพิมพ์
     (ยืนยันจากผู้ใช้ — เหลือจุดที่ติดกับป้าย NEWS2) และซ่อนปุ่ม/ตัวกรองที่ใช้ไม่ได้บนหน้ากระดาษ */
  .patient-detail-shell .topbar-brand h1 { display: none !important; }
  .vital-history-actions { display: none !important; }

  /* ข้อมูลโรคประจำตัว/แพ้ยา/ผู้ติดต่อฉุกเฉิน — โชว์เฉพาะตอนพิมพ์เท่านั้น (ยืนยันจากผู้ใช้ ไม่ต้องการให้
     รกหน้าจอปกติ) ปกติซ่อนด้วย .patient-print-extra-info { display:none } นอก @media print (ดูจุด
     ประกาศ base ด้านล่างนอกบล็อกนี้) */
  .patient-print-extra-info { display: block !important; }

  /* แต่ละค่า (ความดัน/หัวใจ/SpO2/อุณหภูมิ/RR) ขึ้นคนละหน้า A4 เต็มหน้าแยกกัน (ยืนยันจากผู้ใช้ จากตัวอย่าง
     รายงานทางการที่ส่งมา) แทนที่จะไหลต่อกันในหน้าเดียวแบบเดิม — break-after:page บังคับให้การ์ดถัดไปขึ้น
     หน้าใหม่เสมอ (ยกเว้นใบสุดท้ายกันเหลือหน้าเปล่าท้ายรายงาน) การ์ดนอกสุดเป็นแค่กรอบหน้ากระดาษ (ไม่มีกรอบ/
     สีของตัวเอง) ส่วนกรอบเข้ม 3 กล่องที่เห็น (กราฟ+ตาราง / วิเคราะห์ / สรุปข้อแนะนำ) มาจาก
     .vital-chart-card-history/.vital-analysis-main/.vital-analysis-conclusion ด้านล่างแทน (ยืนยันจาก
     ผู้ใช้ให้ตรงกับภาพอ้างอิง — 3 กล่องแยกกันชัดเจน ไม่ใช่กรอบใหญ่กรอบเดียวครอบทั้งหมด) */
  .vital-chart-card {
    break-inside: avoid;
    page-break-inside: avoid;
    break-after: page;
    page-break-after: always;
    margin-bottom: 0;
    min-height: calc(297mm - 20mm);
    box-sizing: border-box;
    font-size: 0.86rem;
  }
  .vital-chart-grid > .vital-chart-card:last-child {
    break-after: auto;
    page-break-after: auto;
  }

  /* เรียงแนวตั้งเดียวแบบภาพอ้างอิง (กราฟ+ตารางเต็มความกว้างก่อน วิเคราะห์อยู่ล่างสุด) — ยืนยันจากผู้ใช้
     บั๊กจริงที่เจอรอบก่อน (กราฟ/วิเคราะห์หลุดไปคนละหน้า) เกิดเพราะกล่องภาพรวมแนวโน้ม/ระดับความเสี่ยงยังถูก
     บังคับเรียงแนวตั้งซ้อนกันเองด้วย (breakpoint 2 คอลัมน์เดิมยึดความกว้างจอ ซึ่งหน้ากระดาษไม่มีวันกว้างถึง)
     รวมความสูงบานเกินหนึ่งหน้า — บังคับกล่องนั้นเป็น 2 คอลัมน์ตรงๆ เฉพาะตอนพิมพ์ด้านล่าง — บั๊กจริงรอบสอง
     ที่ผู้ใช้เจอ (จากไฟล์ PDF จริง ไม่ใช่แค่ตัวอย่างพรีวิว): บางค่า (เช่น SpO2 ที่มีตารางประวัติเต็ม 5 แถว)
     ยังเกินพอดีจนกล่องสรุปข้อแนะนำหลุดไปอีกหน้าอยู่ดี ทั้งที่ตัวอย่างที่ทดสอบไว้พอดีหนึ่งหน้า — เว้น margin
     หน้ากระดาษ/ระยะห่างระหว่างกล่อง/ขนาดตัวอักษรให้แคบลงอีกชั้นทั่วทั้งการ์ด (ดู @page ด้านบนด้วย) เผื่อ
     พื้นที่ว่างมากขึ้นกันปัญหานี้เกิดซ้ำกับค่าอื่นที่มีข้อความยาวกว่านี้ */
  .vital-chart-card-body { flex-direction: column !important; gap: 10px; }

  /* กล่องเข้ม 3 กล่องของรายงาน (กราฟ+ตาราง / วิเคราะห์ / สรุปข้อแนะนำ) แต่ละกล่องมีกรอบและมุมโค้งเป็นของ
     ตัวเอง แยกจากกันชัดเจน (ยืนยันจากผู้ใช้จากภาพอ้างอิง) แทนกรอบใหญ่กรอบเดียวครอบทั้งการ์ดแบบเดิม */
  .vital-chart-card-history,
  .vital-analysis-main,
  .vital-analysis-conclusion {
    break-inside: avoid;
    page-break-inside: avoid;
    box-sizing: border-box;
    border: 2px solid var(--navy-700);
    border-radius: 10px;
    overflow: hidden;
  }
  .vital-chart-card-history { padding: 0 0 10px; }
  .vital-chart-mini-table-wrap { max-height: none; overflow: visible; padding: 0 14px; }
  .vital-chart-mini-table { font-size: 0.76rem; }
  .vital-chart-mini-table th,
  .vital-chart-mini-table td { padding: 5px 10px; }
  .vital-chart-mini-table th { background: var(--navy-700); color: #fff; }

  /* หัวกล่องกราฟกลายเป็นแถบหัวเรื่องรายงานสีเข้ม-ตัวอักษรขาวชนขอบกล่อง (ยืนยันจากผู้ใช้ ให้หน้าตาเป็น
     รายงานทางการ) แทนหัวข้อธรรมดาบนจอ ป้ายค่าปัจจุบันเปลี่ยนเป็นพื้นขาว-กรอบเข้มให้ตัดกับแถบหัวเรื่องสีเข้ม
     (แทนสีตามชนิดค่าที่ใช้บนจอปกติ ซึ่งจะกลืนกับแถบเข้มจนอ่านยาก) */
  .vital-chart-card-head {
    background: var(--navy-700);
    color: #fff;
    padding: 8px 14px;
    margin: 0 0 10px;
  }
  .vital-chart-card-head .vital-chart-title { font-size: 1.15rem; color: #fff; }
  .vital-chart-card-head .vital-chart-badge,
  .vital-chart-card-head .vital-chart-badge-bp,
  .vital-chart-card-head .vital-chart-badge-hr,
  .vital-chart-card-head .vital-chart-badge-spo2,
  .vital-chart-card-head .vital-chart-badge-temp,
  .vital-chart-card-head .vital-chart-badge-rr {
    background: #fff !important;
    color: var(--navy-700) !important;
    border: 2px solid var(--navy-700);
    font-size: 0.9rem;
  }
  .vital-chart-legend { padding: 0 14px; }
  .vital-chart { padding: 0 14px; }
  .vital-chart .report-chart-body { width: 100%; margin: 0; }
  /* ลดความสูงกราฟลงจากค่าธรรมชาติ (~228px ตามสัดส่วน viewBox 460x160 เมื่อเต็มความกว้างคอลัมน์) เผื่อพื้นที่
     ให้ตาราง+กล่องวิเคราะห์ด้านล่างมากขึ้น (svg มี preserveAspectRatio="none" อยู่แล้ว ย่อความสูงตรงๆ ได้
     โดยไม่บิดเบี้ยวข้อมูล แค่กราฟแบนลงเล็กน้อย) */
  .vital-chart .report-chart-body svg { height: 150px; }
  .vital-chart-line { stroke-width: 2.5; }

  /* กล่องวิเคราะห์ (ภาพรวมแนวโน้ม+ระดับความเสี่ยง) มีหัวเรื่องแถบเข้มแบบเดียวกับกล่องกราฟ บังคับ 2 คอลัมน์
     เสมอตอนพิมพ์ (ไม่รอ breakpoint 1180px ของหน้าจอ ซึ่งหน้ากระดาษไม่มีวันกว้างถึง) มีเส้นแบ่งกลางแทนกรอบ
     แยกกล่องย่อย (ยืนยันจากผู้ใช้จากภาพอ้างอิง) */
  .vital-analysis { border: none; background: none; padding: 0; height: auto; }
  .vital-analysis-main { padding: 0 0 10px; margin-bottom: 10px; }
  .vital-analysis-title {
    background: var(--navy-700);
    color: #fff;
    font-size: 1rem;
    text-align: center;
    padding: 8px 14px;
    margin: 0 0 10px;
  }
  .vital-analysis-title-en { color: #dbeafe; }
  .vital-analysis-box-title { font-size: 0.78rem; margin: 0 0 6px; }
  .vital-analysis-list { font-size: 0.74rem; gap: 3px; }
  .vital-risk-label { font-size: 0.78rem; }
  .vital-risk-description { font-size: 0.72rem; }
  .vital-analysis-grid { flex-direction: row !important; padding: 0 14px; }
  .vital-analysis-grid .vital-analysis-box {
    flex: 1;
    min-width: 0;
    border: none;
    background: none;
    padding: 0 14px;
  }
  .vital-analysis-grid .vital-analysis-box:first-child {
    padding-left: 0;
    border-right: 1px solid var(--border);
  }
  .vital-analysis-grid .vital-analysis-box:last-child { padding-right: 0; }

  /* กล่องสรุปข้อแนะนำ — หัวเรื่องอยู่บนพื้นขาวขีดเส้นใต้เข้ม (ไม่ใช่แถบทึบแบบ 2 กล่องบน) ตามภาพอ้างอิง — บั๊ก
     จริงที่ผู้ใช้เจอ (จากไฟล์ PDF จริง): กล่องนี้ดูเหมือนไม่มีขอบบน/ติดกับกล่องข้างบนเกินไป root cause คือ
     .vital-analysis-conclusion ในโหมดจอปกติ (patients.css) มี border-top: 1px dashed อยู่ก่อนแล้ว ซึ่งโหลด
     "หลัง" shared.css เสมอ (patient_detail.html ใส่ patients.css ผ่าน extra_css ท้าย <head>) — พอ specificity
     เท่ากัน (คลาสเดียวเหมือนกันทั้งคู่) กฎที่โหลดทีหลังชนะ ทำให้ border-top จอปกติ (เส้นประบางสีเทา) ทับกฎ
     border ก้อนเข้มด้านบนเฉพาะด้านบนด้านเดียว (ด้านซ้าย/ขวา/ล่างไม่ชน เพราะกฎจอปกติไม่ได้แตะ) — ระบุ
     border-top ให้ตรงๆ ที่นี่กันชนซ้ำ */
  .vital-analysis-conclusion { margin-top: 0; padding: 10px 14px; border-top: 2px solid var(--navy-700); }
  .vital-analysis-summary,
  .vital-analysis-recommendation,
  .vital-analysis-checkup { font-size: 0.76rem; margin: 0 0 4px; }
  .vital-analysis-note { font-size: 0.68rem; margin: 6px 0 0; }
  .vital-analysis-conclusion .vital-analysis-box-title {
    text-align: center;
    font-size: 1rem;
    padding-bottom: 8px;
    margin: 0 0 12px;
    border-bottom: 2px solid var(--navy-700);
  }

  .health-summary-tile { break-inside: avoid; page-break-inside: avoid; }

  /* จุดที่ควรสังเกต + หมายเหตุท้ายหน้า — ย้ายมาอยู่ต่อท้ายสรุป/เคสฉุกเฉินในหน้าแรกแล้ว (ยืนยันจากผู้ใช้ ไม่
     ต้องการให้แยกไปเป็นหน้าเดี่ยวๆ) ลดขนาดตัวอักษร/ระยะห่างลงอีกชั้นเฉพาะตอนพิมพ์ เผื่อพื้นที่ว่างให้พอสำหรับ
     เคสที่มีค่าเข้าเกณฑ์เฝ้าระวังพร้อมกันหลายค่า (สูงสุด 5 ค่า ไม่ใช่แค่ 1-2 ค่าที่ทดสอบไว้) */
  .health-summary-watchbox { break-inside: avoid; page-break-inside: avoid; font-size: 0.76rem; padding: 10px 12px; margin-top: 10px; }
  .health-summary-watchbox-list { gap: 4px; }
  .health-summary-disclaimer { font-size: 0.66rem; padding-top: 8px; margin-top: 10px; }
}
