diff --git a/php/assets/app.css b/php/assets/app.css index 38674d0..c8cb82c 100644 --- a/php/assets/app.css +++ b/php/assets/app.css @@ -87,7 +87,7 @@ header h1::before { content: ""; width: 10px; height: 10px; border-radius: 50%; .ops-grid { display: grid; grid-template-columns: minmax(0,1.5fr) minmax(300px,.9fr); gap: var(--sp-4); align-items: start; margin-bottom: var(--sp-6); } .cards { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--sp-4); margin-bottom: var(--sp-4); } .cards.flush { margin-bottom: var(--sp-6); } -.sensor-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px,1fr)); gap: var(--sp-4); margin-bottom: var(--sp-6); } +.sensor-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px,1fr)); gap: var(--sp-4); margin-bottom: var(--sp-6); } .panel, .card, .chart-panel, .leak-status-card, .empty-note { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow); } .panel { padding: var(--sp-5); } @@ -569,6 +569,17 @@ tbody tr:hover td { background: var(--surface-2); } /* ── 예보 칩: 여유(safe) 상시 표시용 중립 스타일 ────────────────────────────── */ .forecast-chip.safe { background: var(--surface-2); color: var(--ink-2); } +/* ── 통합 센서 카드: 헤더(이름+유형칩) / 카드 내부 세로 리듬 정렬 ─────────────── */ +.sensor-card { display: flex; flex-direction: column; } +.sc-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); } +.sc-head strong { font-size: 1rem; font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.sc-type { flex: none; font-size: .68rem; font-weight: 800; letter-spacing: .03em; padding: 2px 8px; border-radius: var(--r-pill); background: var(--surface-2); color: var(--ink-2); border: 1px solid var(--line); } +.sc-type.metric { background: rgba(63,199,230,.13); color: var(--cold-ink); } +.sc-type.leak { background: var(--offline-bg); color: var(--offline-ink); } +.sensor-card small { display: block; margin-top: 2px; } +/* 예보줄을 카드 하단에 고정(카드 높이가 그리드 행 기준으로 늘어나도 자연스럽게) */ +.sensor-card .forecast { margin-top: auto; } + /* ── 범주형 차트 클래스 (도넛 세그먼트 stroke / 범례 스와치 background) ─────── */ .donut-ring circle.seg.cat-hot { stroke: var(--cat-hot); } .donut-ring circle.seg.cat-humid { stroke: var(--cat-humid); } @@ -582,9 +593,19 @@ tbody tr:hover td { background: var(--surface-2); } .dl i.cat-dry { background: var(--cat-dry); } .donut-note { margin-top: var(--sp-2); } -/* ── trend 탭 위젯 그리드 (기존 .overview 12열 위에서 3타일/행 균등 배치) ────── */ +/* ── trend 탭 위젯 그리드 (기존 .overview 12열 위에서 배치) ────────────────── + 1행: 경보 추이·도넛·게이지 각 span 4 (=12). 2행: 리더보드 span 12 (가로 리더보드 + — 타일 하나만 다음 행에 덩그러니 남는 것 방지). */ .trend-widgets > .ov-tile { grid-column: span 4; } -@media (max-width: 1080px) { .trend-widgets > .ov-tile { grid-column: span 6; } } +.trend-widgets > .ov-board { grid-column: span 12; } +.trend-widgets > .ov-board .board { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); } +@media (max-width: 1080px) { + .trend-widgets > .ov-tile { grid-column: span 6; } + .trend-widgets > .ov-board { grid-column: span 12; } +} +@media (max-width: 620px) { + .trend-widgets > .ov-tile, .trend-widgets > .ov-board { grid-column: span 12; } +} /* ── system 탭 패널 그리드 ──────────────────────────────────────────────────── */ .system-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: var(--sp-4); align-items: start; } diff --git a/php/tabs/live.php b/php/tabs/live.php index 81ac7ce..ac1b667 100644 --- a/php/tabs/live.php +++ b/php/tabs/live.php @@ -3,97 +3,117 @@ // 사용 변수: load_global_data() 결과(extract) — $metric_statuses, $leak_statuses, // $unrecovered_incidents, $forecasts, $sms_* , $today_* 등. if (!defined('APP_VERSION')) { exit; } // 직접 접근 차단 + +// 온습도·누수 센서를 하나의 그리드로 통합한다(센서 수가 적어도 한 행을 균등하게 +// 채우도록 — 섹션마다 카드가 1개씩 흩어지는 것 방지). sensor_id 순서, 유형은 칩으로 구분. +$sensor_cards = []; +foreach ($metric_statuses as $sid => $s) { $sensor_cards[(int)$sid] = ['type' => 'metric', 's' => $s]; } +foreach ($leak_statuses as $sid => $s) { + if (!isset($sensor_cards[(int)$sid])) { $sensor_cards[(int)$sid] = ['type' => 'leak', 's' => $s]; } +} +ksort($sensor_cards); ?>
아직 수신된 센서 데이터가 없습니다.