@charset "UTF-8";
/* 全域設定與基礎樣式 */
:root{
  --logo-max-height: 66px;     /* 站台 logo 最大高度 */
  --logo-max-width: 160px;     /* 站台 logo 最大寬度 */
  --bg-navy-rgb: 14, 22, 42;   /* 背景主色 (RGB) */
  --bg-opacity: 0.95;          /* 背景不透明度 0~1 */
  --bg-texture-size: 2px;      /* 背景紋理尺寸 */
}

/* =============================
   Typography variables & base
   ============================= */
:root{
  --font-family-base: "Inter", "Noto Sans TC", "Microsoft JhengHei", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang TC", sans-serif;
  --font-family-headings: var(--font-family-base);
  --font-size-base:25px;          /* 文字基準大小 */
  --line-height-base: 1.55;       /* 文字行高 */
  --nav-link-size: 0.95rem;       /* 導覽連結字體大小 */
  --table-font-size: 0.95rem;     /* 表格字體大小 */
  --form-font-size: 0.95rem;      /* 表單/按鈕字體大小 */
  --panel-title-size: 1.25rem;    /* 面板標題大小 (h4) */
  --h1-size: 2rem; --h2-size: 1.75rem; --h3-size: 1.5rem; --h4-size: 1.25rem; --h5-size: 1.1rem; --h6-size: 1rem;
}
html { font-size: var(--font-size-base); }
body { font-family: var(--font-family-base); line-height: var(--line-height-base); }
.navbar .nav-link, .navbar .dropdown-menu { font-size: var(--nav-link-size); }
.table { font-size: var(--table-font-size); }
.form-control, .form-select, .btn { font-size: var(--form-font-size);}
h1 { font-size: var(--h1-size); }
h2 { font-size: var(--h2-size); }
h3 { font-size: var(--h3-size); }
h4 { font-size: var(--h4-size); }
h5 { font-size: var(--h5-size); }
h6 { font-size: var(--h6-size); }

.site-logo{
  max-height: var(--logo-max-height);
  max-width: var(--logo-max-width);
  height: auto;
  width: auto;
  display: block;
}

/* 下拉選單：避免被圖表/表格覆蓋 */
.navbar .dropdown-menu{
  font-size: var(--nav-link-size);
  z-index: 1100; /* keep dropdown above charts/tables */
}

/* Alert 與容器間距 */
.container .alert{
  margin-top: .5rem;
}

#osdChart {
  width: 100% !important;
  /* 交由 JS 設定高度；此處不限制 */
  height: auto;
  max-height: 720px !important;
}

#osdChartA {
  width: 100% !important;
  /* 交由 JS 設定高度；此處不限制 */
  height: auto;
  max-height: 720px !important;
}

#osdChartB {
  width: 100% !important;
  /* 交由 JS 設定高度；此處不限制 */
  height: auto;
  max-height: 720px !important;
}

/* ?刻撟芋撘矽??*/
body.fullscreen-active {
  margin: 0;
  padding: 0;
}
body.fullscreen-active .container-fluid {
  width: 99%;
  height: 99%;
}

/* === ?刻撟?瘨撌血蝛箇嚗??批捆皛踹祝嚗?敶梢銝餃摰對?銝蔣??navbar嚗?=== */
body.fullscreen-active .app-content,
body.fullscreen-active .app-content.container,
body.fullscreen-active .app-content.container-sm,
body.fullscreen-active .app-content.container-md,
body.fullscreen-active .app-content.container-lg,
body.fullscreen-active .app-content.container-xl,
body.fullscreen-active .app-content.container-xxl {
  max-width: 100vw !important;
  width: 99vw !important; /* ??暺??踹??脣?璇???*/
  padding-left: 8px !important;
  padding-right: 8px !important;
}

/* 霈蜓?批捆?典?Ｗ???遛擃?*/
body.fullscreen-active .app-content {
  min-height: 96vh;
}

/* ?箇?嚗Ⅱ靽??ａ?摨血?冽皛輻? */
html, body {
  height: 100%;
}
/* ?脫迫?刻撟? navbar ??container 擃漲鋡怠???*/
body.fullscreen-active nav .container-fluid {
  height: auto !important;
}

/* =============================
   Wide-mode (CSS Fullscreen Fallback)
   霈摰孵????Ｗ?銝???99% 皛輻?憿舐內
   ============================= */
body.wide-mode {
  margin: 0;
  padding: 0;
  overflow-x: hidden; /* ?脫迫?箇瘞游像?脣?璇?*/
}
/* 銝餃摰孵?憛遛撖穿?銝蔣??navbar嚗?*/
body.wide-mode .app-content,
body.wide-mode .app-content.container,
body.wide-mode .app-content.container-sm,
body.wide-mode .app-content.container-md,
body.wide-mode .app-content.container-lg,
body.wide-mode .app-content.container-xl,
body.wide-mode .app-content.container-xxl {
  max-width: 99vw !important;
  width: 98vw !important;  /* 靽? 1vw ?踹??脣??? */
  padding-left: 8px !important;
  padding-right: 8px !important;
}
/* 霈摰寥?摨行?皛輻??*/
body.wide-mode .app-content { min-height: 96vh; }
/* ?脫迫 navbar ??Wide-mode 鋡怠?蝮?*/
body.wide-mode nav .container-fluid { height: auto !important; max-width: 100% !important; }

/* =============================
   銵冽嚗”?凋????極?琿???   ?閬???<th> ?? class="th-nowrap" ??"nowrap"
   ============================= */
.table thead th.th-nowrap,
.table thead th.nowrap { white-space: nowrap; }

/* Wide-mode 銝?蝘駁 .container ?刻?撖祆???憭椰?喲?頝?*/
body.wide-mode .container.app-content { max-width: 100% !important; }

/* 擐?(銵券)?箏??株?憿舐內嚗???銵?*/
.table thead th { white-space: nowrap; }

/* =============================
   Wide Toggle (ON/OFF pill switch)
   ============================= */
.wide-toggle-container { display: inline-block; }
.wide-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 86px;         /* pill 撖砍漲 */
  height: 36px;        /* pill 擃漲 */
  border: 2px solid #222;
  border-radius: 999px;
  cursor: pointer;
  user-select: none;
  background-color: #fff;
  overflow: hidden;
}
.wide-toggle__knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: #111;
  transition: left .18s ease;
}
.wide-toggle__label {
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
  color: #111;
  padding: 0 12px;
  pointer-events: none;
  opacity: .35;
  transition: opacity .18s ease;
}
.wide-toggle__label--on { margin-left: 40px; }
.wide-toggle__label--off { margin-left: 20px; }

/* checked ?????暺?啣??銝血???ON/OFF ??雿蔭 */
#wideToggle:checked + .wide-toggle .wide-toggle__knob { left: 53px; }
#wideToggle:checked + .wide-toggle .wide-toggle__label--on { margin-left: 12px; }
#wideToggle:not(:checked) + .wide-toggle .wide-toggle__label--off { margin-left: 40px; }

/* Wide-toggle label visibility: active state brighter */
#wideToggle:checked + .wide-toggle .wide-toggle__label--on { opacity: 1; }
#wideToggle:checked + .wide-toggle .wide-toggle__label--off { opacity: .35; }
#wideToggle:not(:checked) + .wide-toggle .wide-toggle__label--off { opacity: 1; }
#wideToggle:not(:checked) + .wide-toggle .wide-toggle__label--on { opacity: .35; }

/* ?冽楛?脣?閬賢?銝?皜?航? */
.navbar-dark .wide-toggle { border-color: #bbb; }
.navbar-dark .wide-toggle__knob { background: #ddd; }
.navbar-dark .wide-toggle__label { color: #ddd; }


/* =============================
   Body ?嚗?? + ?航矽??摨?   ============================= */
body {
  background-color: rgba(var(--bg-navy-rgb), var(--bg-opacity));
  background-image:
    radial-gradient(rgba(255,255,255,.06) 1px, transparent 1px),
    radial-gradient(rgba(0,0,0,.05) 1px, transparent 1px);
  background-size: var(--bg-texture-size) var(--bg-texture-size);
}

/* =============================
   Surface Panels (?啁? + ?? + ?啣蔣)
   ============================= */
:root {
  --panel-bg-rgb: 255, 255, 255; /* ?啁摨 */
  --panel-opacity: 0.9;          /* ??摨?(0~1) */
  --panel-radius: 12px;          /* ?? */
  --panel-shadow: 0 6px 18px rgba(0,0,0,.12); /* ?啣蔣 */
}

.app-content > div {
  background-color: rgba(var(--panel-bg-rgb), var(--panel-opacity));
  border-radius: var(--panel-radius);
  box-shadow: var(--panel-shadow);
  padding: 1rem;
  margin-bottom: 1.5rem !important;
}
.app-content > div > h4 {
  text-align: center;
  margin-bottom: 2rem;
  font-weight: 600;
}

/* Reusable panel title (use when element-specific styles aren? applied by selector) */
.panel-title {
  text-align: center;
  margin: 0 0 1rem !important; /* leave space under the title */
  font-weight: 600;
  font-size: var(--panel-title-size);
}

/* =============================
   Navbar (transparent gray, adjustable)
   ============================= */
:root{
  --navbar-bg: rgba(33, 37, 41, 0.65); /* adjustable transparent gray */
  --navbar-height: 64px;               /* adjust if your navbar is taller */
  --navbar-border: rgba(255,255,255,.08);
  --navbar-blur: 6px;                  /* backdrop blur radius */
}
.app-navbar{
  background-color: var(--navbar-bg) !important;
  -webkit-backdrop-filter: blur(var(--navbar-blur));
  backdrop-filter: blur(var(--navbar-blur));
  border-bottom: 1px solid var(--navbar-border);
  z-index: 1100; /* keep above content */
}
.app-navbar .nav-link {
  white-space: nowrap;
}
/* offset page content for fixed-top navbar */
/* At top: offset content by navbar height; after scrolling: overlay on content */
body:not(.has-scrolled) { padding-top: var(--navbar-height); }
body.has-scrolled { padding-top: 0; }

/* 憒?銝?閬????啣蔣嚗?? .no-surface */
.app-content > div.no-surface {
  background: transparent;
  box-shadow: none;
  border-radius: 0;
  padding: 0;
}


/* === PCS ??璅?? === */
:root{
  --device-photo-width: 120px;                 /* 隤踵??撖砍漲 */
  --device-photo-radius: 12px;                  /* ???? */
  --device-photo-shadow: 0 8px 20px rgba(0,0,0,.18); /* ?啣蔣 */
}
.panel-with-photo{ display:flex; gap:12px; align-items:flex-start; }
.panel-with-photo .device-photo{
  flex: 0 0 auto;
  width: var(--device-photo-width);
  height: auto;
  border-radius: var(--device-photo-radius);
  box-shadow: var(--device-photo-shadow);
  display:block;
}

/* Reusable surface panel for nested layouts */
.surface-panel{
  background-color: rgba(var(--panel-bg-rgb), var(--panel-opacity));
  border-radius: var(--panel-radius);
  box-shadow: var(--panel-shadow);
  padding: 1rem;
}

/* === PCS ??瘥??????=== */
:root{
  --device-photo-object-fit: cover;  /* cover | contain | fill | scale-down | none */
}
.device-photo-box{ width:100%; aspect-ratio: var(--device-photo-aspect); }
.device-photo-box .device-photo{
  width:100%; height:100%; object-fit: var(--device-photo-object-fit);url(http://127.0.0.1:1000/static/img/pcs.png)
}

/* 銵冽?舀偌撟單??摰孵嚗???粹??*/
.table-scroll{ overflow-x:auto; width:100%; }

/* =============================
   EMS Schedule: centered h4 and calendar cells
   ============================= */
/* Center h4.panel-title when inside flex toolbars */
.d-flex .panel-title { flex: 1 1 auto; text-align: center; margin: 0; }

:root { --calendar-cell-height: clamp(120px, 18vh, 200px); }
#calendar .day-cell {
  height: var(--calendar-cell-height);
  display: flex;
  flex-direction: column;
  cursor: pointer;
}
#calendar .day-cell .day-number { font-weight: 700; margin-bottom: 4px; }
#calendar .day-cell .day-content {
  font-size: .7em;
  white-space: pre-wrap;
  overflow: auto; /* scroll when content exceeds height */
}

/* EMS Schedule toolbar (top controls) center layout */
.app-content > .d-flex.align-items-center.mb-3 {
  justify-content: center;
  flex-wrap: wrap;
  gap: .5rem .5rem;
}
.app-content > .d-flex.align-items-center.mb-3 > h4 {
  width: 100%;
  text-align: center;
  margin: 0 0 .5rem;
}

/* iPad / tablet landscape: prevent navbar text wrapping into vertical columns */
@media (min-width: 992px) and (max-width: 1366px) {
  .app-navbar .container-fluid {
    gap: .5rem;
    align-items: center;
  }

  .app-navbar .navbar-brand {
    margin-right: .5rem;
    flex: 0 0 auto;
  }

  .app-navbar .site-logo {
    max-height: 52px;
    max-width: 132px;
  }

  .app-navbar .navbar-collapse {
    display: flex !important;
    align-items: center;
    flex-wrap: wrap;
    min-width: 0;
    gap: .5rem;
  }

  .app-navbar .navbar-collapse > .navbar-nav.me-auto {
    flex: 1 1 auto;
    min-width: 0;
    flex-wrap: wrap;
    row-gap: .1rem;
  }

  .app-navbar .navbar-collapse > .navbar-nav.me-auto .nav-link {
    font-size: .82rem;
    padding-left: .4rem;
    padding-right: .4rem;
  }

  .app-navbar .navbar-collapse > .navbar-nav.ms-auto {
    flex: 1 1 100%;
    justify-content: flex-end;
    margin-left: 0 !important;
    gap: .15rem;
    align-items: center;
  }

  .app-navbar .navbar-collapse > .navbar-nav.ms-auto .nav-link {
    font-size: .82rem;
    padding-left: .35rem;
    padding-right: .35rem;
  }

  .app-navbar .wide-toggle-container {
    transform: scale(.9);
    transform-origin: center right;
  }
}


/* === 瘚桀閰單??Ｘ嚗pple 憸冽嚗?=== */
.sheet-overlay{ position:fixed; inset:0; display:none; z-index:2000; }
.sheet-overlay.active{ display:block; }
.sheet-overlay .sheet-backdrop{ position:absolute; inset:0; background:rgba(0,0,0,.55); }
.sheet-overlay .sheet-content{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  background:#fff; color:#111; border-radius:12px; box-shadow:0 18px 48px rgba(0,0,0,.25);
  /* Adjustable via CSS variables */
  --sheet-width: 96vw;
  --sheet-max-width: min(2400px,96vw);
  --sheet-max-height: 86vh;
  max-width: var(--sheet-max-width);
  width: var(--sheet-width);
  max-height: var(--sheet-max-height);
  overflow:auto; padding:16px;
}
.sheet-overlay .sheet-close{ position:absolute; top:8px; right:12px; border:0; background:transparent; font-size:28px; line-height:1; opacity:.7; }
.sheet-overlay .sheet-close:hover{ opacity:1; }

/* 霈底??蝒葉?”?澆撠撟璈怠??脣? */
.sheet-overlay .table-scroll{ overflow:auto; width:100%; }

/* ===============
   EMS Schedule overlay sizing + sticky table header
   You can tweak these variables to change the overlay size and the editable table area
   =============== */
#overlayDay .sheet-content{
  /* Per-page overrides (optional) */
  --overlay-day-width: var(--sheet-width);
  --overlay-day-max-width: var(--sheet-max-width);
  --overlay-day-max-height: var(--sheet-max-height);
  --overlay-day-table-max-h: 48vh; /* default table viewport height */
  --overlay-day-chart-h: 180px;    /* chart height above the table */
  width: var(--overlay-day-width);
  max-width: var(--overlay-day-max-width);
  max-height: var(--overlay-day-max-height);
}

/* Match resource-default pattern: wrapper controls scroll; thead sticks to wrapper */
#dayTableWrap{ max-height: var(--overlay-day-table-max-h); overflow: auto; }
#dayTable{ border-collapse: separate; }
#dayTableWrap thead th{ position: sticky; top: 0; z-index: 2; background: #fff; box-shadow: 0 1px 0 rgba(0,0,0,.06); }

/* Overlay day chart height control */
#overlayDay #dayChart{ height: var(--overlay-day-chart-h); width: 100%; }

/* ???航矽?渡???憿舐內瘥??‵?芋撘?*/
:root{ --device-photo-aspect: 3/4; /* 靘?16/9??/3??/1??/4 */ }

/* =============================
   Resource Default: sticky header/first-col for 24h table
   ============================= */
#rdTableWrap{ max-height: 60vh; overflow: auto; }
#defaultTable{ border-collapse: separate; }
#rdTableWrap thead th{ position: sticky; top: 0; z-index: 2; background: #fff; box-shadow: 0 1px 0 rgba(0,0,0,.06); }
#rdTableWrap tbody th{ position: sticky; left: 0; z-index: 1; background: #fff; box-shadow: 1px 0 0 rgba(0,0,0,.06); }
#rdTableWrap thead th:first-child{ left: 0; z-index: 3; }

/* Keep Bootstrap modals above the fixed navbar */
.modal { z-index: 2000; }
.modal-backdrop { z-index: 1990; }

/* =============================
   Account Management: keep 4 action buttons on one line
   ============================= */
#accountTable td:last-child {
  white-space: nowrap;      /* prevent wrapping to second line */
}
#accountTable td:last-child .btn {
  margin-right: .35rem;     /* small gap between buttons */
}
#accountTable td:last-child .btn:last-child { margin-right: 0; }
#accountTable td:last-child form { display: inline; }

/* =============================
   Notify page table: widen cols and prevent wrapping
   Targets the table that contains tbody#tbody (unique to notify.html)
   ============================= */
table:has(> #tbody) thead th { white-space: nowrap; }
/* Column widths: 1=狀態, 2=場域名稱, 3=項目內容, 4=訊息內容, 5=發佈時間 */
table:has(> #tbody) thead th:nth-child(3) { min-width: 180px; }
table:has(> #tbody) thead th:nth-child(4) { min-width: 520px; }
table:has(> #tbody) tbody td { white-space: nowrap; }
table:has(> #tbody) tbody td:nth-child(3) { min-width: 180px; }
table:has(> #tbody) tbody td:nth-child(4) { min-width: 520px; }

/* =============================
   AC Meter: trend toolbar single-line layout
   Allows quick tweaks via CSS variables below.
   ============================= */
:root{
  --meter-toolbar-gap: 12px;           /* gap between blocks */
  --meter-device-w: 400px;             /* width of device picker */
  --meter-fields-w: 400px;             /* width of field picker */
  --meter-mode-w: 360px;               /* width of mode select */
  --meter-time-w: 360px;               /* width of date/time input area */
  --meter-custom-w: 460px;             /* width of custom range area */
  --meter-draw-w: 200px;               /* width of draw button block */
  --meter-export-w: 200px;             /* width of CSV button block */
  --meter-picker-h: 180px;             /* max-height for checkbox lists */
}

/* Make the chart form a horizontal toolbar */
#chartForm{ display:flex !important; flex-wrap: nowrap !important; gap: var(--meter-toolbar-gap); align-items: flex-start; overflow-x: auto; }
#chartForm > div{ flex: 0 0 auto; }
/* 1) Device picker */
#chartForm > div:nth-child(1){ width: var(--meter-device-w); }
#chartForm > div:nth-child(1) .form-check{ margin-bottom: .25rem; }
#chartForm > div:nth-child(1) > div{ max-height: var(--meter-picker-h); overflow:auto; }
/* 2) Field picker */
#chartForm > div:nth-child(2){ width: var(--meter-fields-w); }
#chartForm > div:nth-child(2) > div{ max-height: var(--meter-picker-h); overflow:auto; }
/* 3) Mode */
#chartForm > div:nth-child(3){ width: var(--meter-mode-w); }
/* 4) Date container */
#chartForm #dateContainer{ width: var(--meter-time-w); }
/* 5) Custom range */
#chartForm #customRange{ width: var(--meter-custom-w); }
/* 6) Draw button */
#chartForm > div:nth-child(6){ width: var(--meter-draw-w); align-self: end; }
/* 7) CSV button */
#chartForm > div:nth-child(7){ width: var(--meter-export-w); align-self: end; }

/* =============================
   Footer Script Branding (cursive)
   Adjustable sizes/colors/fonts via CSS variables
   ============================= */
:root{
  /* Shared fallback cursive list */
  --footer-script-font: 'Brush Script MT', 'Segoe Script', 'Snell Roundhand', 'Lucida Handwriting', cursive;
  /* Per-part font families (override any of these to change individually) */
  --footer-from-font: 'Lucida Handwriting';
  --footer-ally-font: 'Brush Script MT';
  --footer-ems-font:  'Lucida Handwriting';
  /* Sizes */
  --footer-from-size: 22px;
  --footer-ally-size: 48px;
  --footer-ems-size: 20px;
  /* Colors */
  --footer-from-color: #ffffff;
  --footer-ally-color: #FF5809;   /* brand accent */
  --footer-ems-color: #ffffff;
}
.site-footer{ text-align: center; background: transparent; }
.footer-brand{
  display: inline-flex;
  flex-direction: row;           /* keep in one line */
  align-items: baseline;
  gap: .5rem;                    /* space between words */
  line-height: 1.05;
  white-space: nowrap;           /* prevent wrapping */
}
.footer-brand > span{ display: inline-block; }
.footer-from{ font-family: var(--footer-from-font); font-size: var(--footer-from-size); color: var(--footer-from-color); }
.footer-ally{ font-family: var(--footer-ally-font); font-size: var(--footer-ally-size); color: var(--footer-ally-color); }
.footer-ems{  font-family: var(--footer-ems-font);  font-size: var(--footer-ems-size);  color: var(--footer-ems-color); }
