/* 서비스 웹의 화면별 조각. 토큰·기본 요소·공통 컴포넌트는 theme.css 에 있다.
   페이지는 theme.css → style.css 순서로 불러온다. */

/* --- 카메라 목록: 카드 그리드 ---------------------------------------- */
.grid {
  display: grid; gap: var(--gap); margin: 0; padding: 0; list-style: none;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.cam-card {
  overflow: hidden; cursor: pointer;
  background-color: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  transition: transform .12s ease, box-shadow .12s ease;
}
.cam-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.cam-card:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* 썸네일 자리 — 아직 실제 화면 캡처가 없어 그라디언트 + 카메라 아이콘으로 채운다.
   나중에 스냅샷이 생기면 이 영역에 <img> 만 얹으면 된다. */
.cam-thumb {
  /* 카메라 원본이 4:3 이다(EN675 2592x1944, SD 640x480) — 칸도 4:3 이면 위아래가 덜 잘린다.
     이름·버튼 사이 여백을 줄여 그만큼을 사진에 준다 */
  position: relative; aspect-ratio: 4 / 3;
  display: flex; align-items: center; justify-content: center;
  background-image: linear-gradient(135deg, #12417c 0%, #0d6efd 55%, #4dabf7 100%);
  color: #fff;
}
/* 카메라 아이콘은 CSS 배경(인라인 SVG 데이터 URI)으로 넣는다 —
   JS 에서 innerHTML 을 쓰지 않기 위해서다(XSS 규칙을 예외 없이 지킨다). */
.cam-thumb::after {
  content: ""; width: 46px; height: 46px; opacity: .55;
  background-repeat: no-repeat; background-position: center; background-size: contain;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' \
viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='1.5'%3E%3Cpath d='M3 8.5 16 4l1.8 \
5.2L4.8 13.7z'/%3E%3Ccircle cx='7.5' cy='10.2' r='1.6'/%3E%3Cpath d='M11 14l-1.2 5h3.4l1-4'/%3E%3C/svg%3E");
}
/* 스냅샷이 있으면 사진이 자리를 덮는다. 원본은 4:3 이라 16:9 칸에 맞춰 잘라 보여준다 */
.cam-thumb { overflow: hidden; }
.cam-thumb img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  /* 새 사진이 옛 사진 위로 서서히 덮인다 (cameras.html swapThumb) */
  opacity: 1; transition: opacity .45s ease;
}
.cam-thumb img.fading-in { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .cam-thumb img { transition: none; }
}
.cam-thumb.has-image::after { display: none; }
.cam-thumb .snap-age {
  position: absolute; left: 10px; bottom: 8px;
  padding: 2px 8px; border-radius: 999px; font-size: .72rem;
  background: rgba(0, 0, 0, .55); color: #fff;
}
.cam-thumb .badge {
  position: absolute; top: 10px; right: 10px;
  background-color: rgba(255, 255, 255, .92); border-color: transparent;
}
.cam-body { padding: 10px 14px 12px; }
.cam-name { font-weight: 600; word-break: break-all; text-align: center; }
/* 카드 버튼은 폭과 관계없이 **한 줄, 가운데**. 세 버튼을 합쳐도 약 200px 라 320px 폰에서도 들어간다 */
.cam-actions {
  display: flex; gap: 6px; margin-top: 6px;
  flex-wrap: nowrap; justify-content: center;
}
.cam-actions button {
  min-height: 34px; padding: 5px 10px; font-size: .8rem; font-weight: 500;
  white-space: nowrap;                 /* "연결 설정" 이 두 줄로 꺾이지 않게 */
}
/* 카드 아이콘 버튼은 앱바(44px)보다 한 단계 작게. 세 개라도 약 130px 라 어느 폭이든 한 줄이다 */
.cam-actions button.icon-btn { width: 40px; height: 40px; min-height: 40px; padding: 0; }
.cam-actions button.icon-btn svg { width: 19px; height: 19px; }

/* --- 영상 보기 -------------------------------------------------------- */
/* 플레이어 크기는 **스트림 원본**이 정한다. WebRTC 는 카메라가 인코딩한 픽셀만 보내므로,
   CSS 로 그보다 크게 늘려도 선명해지지 않고 흐려지기만 한다. 그래서 재생이 시작되면
   view.html 이 실제 해상도를 읽어 아래 두 변수를 채운다(실측 근거는 README 30).
     --player-w     : 원본 가로 픽셀(상한 1600) — 이보다 넓히지 않는다
     --player-ratio : 원본 비율 — 카메라마다 16:9 도 있고 4:3 도 있다
   값이 오기 전에는 16:9 로 자리를 잡아 두어 레이아웃이 튀지 않게 한다. */
.player {
  width: 100%; max-width: var(--player-w, 1280px); margin-inline: auto;
  background-color: #000; border-radius: var(--radius); overflow: hidden;
  box-shadow: var(--shadow);
}
video {
  display: block; width: 100%;
  aspect-ratio: var(--player-ratio, 16 / 9);
  max-height: 78svh;                 /* 세로로도 화면을 넘지 않게 */
  object-fit: contain;               /* 비율이 달라도 잘리거나 찌그러지지 않는다 */
  background-color: #000;
}

/* 폰: 좌우 끝까지 쓴다. 375px 는 어떤 스트림보다도 작아 여백을 둘 이유가 없다 */
@media (max-width: 640px) {
  .player { margin-inline: -16px; width: calc(100% + 32px); max-width: none; border-radius: 0; }
}
/* 가로로 돌렸을 때: 크게 보려는 것이므로 높이를 화면에 맞추되 컨트롤이 잘리지 않게 */
@media (orientation: landscape) and (max-height: 560px) {
  video { max-height: 100svh; }
}
.video-state { min-height: 1.5em; margin: 10px 2px var(--gap); font-size: .86rem; color: var(--muted); }
.video-state.error { color: var(--danger); }

.quality-row {
  display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap;
  margin-top: 2px;
}
/* 세그먼트 토글 — 두 칸이 한 덩어리로 보이고, 고른 쪽이 색으로 확실히 드러나게.
   글자만 있으면 "누를 수 있는 것"으로 안 읽힌다. */
.quality {
  display: inline-flex; padding: 3px; gap: 2px;
  border: 1px solid var(--line); border-radius: 999px;
  background-color: color-mix(in srgb, var(--ink) 6%, var(--card));
}
.quality button {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 38px; padding: 6px 18px; border: 0; border-radius: 999px;
  font-size: .9rem; font-weight: 700; letter-spacing: .02em;
  color: var(--muted); background: none;
}
/* 화질을 가리키는 막대 두 개 — SD 는 한 칸, HD 는 두 칸이 차 보이게 */
.quality button::before {
  content: ""; width: 14px; height: 10px; border-radius: 2px;
  background-image: linear-gradient(to right, currentColor 5px, transparent 5px 9px,
                                     currentColor 9px);
  opacity: .45;
}
.quality button#q-sd::before {
  background-image: linear-gradient(to right, currentColor 5px, transparent 5px);
}
.quality button:hover { color: var(--brand); }
.quality button[aria-pressed="true"] {
  background-color: var(--brand); color: #fff;
  box-shadow: 0 1px 4px rgba(5, 60, 73, .25);
}
.quality button[aria-pressed="true"]::before { opacity: 1; }
.quality button[disabled] { opacity: .4; }
.quality button:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* --- 연결 설정 화면 (17절) -------------------------------------------- */
.card + .card { margin-top: var(--gap); }
.card > h2 { margin: 0 0 6px; font-size: 1.05rem; }
section.card { padding: 16px; }
.kv { margin: var(--gap) 0 0; }
.kv dt { margin-bottom: 3px; font-size: .8rem; color: var(--muted); }
.kv dd { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 var(--gap); }
.kv-value { flex: 1 1 100%; word-break: break-all; }
.kv-value.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .9rem; }
.kv-actions { display: flex; gap: 8px; }
/* 대조용 값 — 서비스명·PIN 을 한 줄에 나란히. 복사 버튼 없이 읽기만 하는 자리다. */
.facts {
  display: flex; flex-wrap: wrap; gap: 10px 22px;
  margin-top: 4px; padding-top: 12px; border-top: 1px dashed var(--line);
}
.facts[hidden] { display: none; }
.fact { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.fact-key { font-size: .8rem; color: var(--muted); white-space: nowrap; }
.fact-value { font-size: .92rem; font-weight: 600; word-break: break-all; }

/* 주의 문구 — 네모칸 없이 앞에 ⚠ 만 강조색으로. \FE0E 는 폰에서 이모지 그림 대신 글자 모양으로 */
.note {
  display: flex; align-items: baseline; gap: 6px;
  margin: var(--gap) 0; font-size: .85rem; color: var(--muted);
}
.note::before { content: "\26A0\FE0E"; color: var(--warn); font-weight: 700; flex: 0 0 auto; }
.note[hidden] { display: none; }

p.sub { margin: 0 0 18px; color: var(--muted); font-size: .9rem; }
h2 { font-size: 1.1rem; margin: 0 0 4px; }


/* --- 카메라 설정 화면 (settings.html, README 35) ---------------------- */
/* 섹션 = 카드 하나. 새 기능이 붙어도 같은 모양으로 쌓이게 간격만 정해 둔다 */
.setting-card { padding: 18px; margin-bottom: var(--gap); }
.setting-card h2 { margin: 0 0 6px; }
.setting-subhead { margin: 16px 0 8px; font-size: .92rem; }
.setting-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 0; border-top: 1px solid var(--line);
}
.setting-label { flex: 0 0 84px; font-size: .88rem; font-weight: 600; }
.setting-control { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.setting-control button[aria-pressed="true"] { border-color: var(--brand); color: var(--brand); font-weight: 600; }
/* 전송 주기 — 최대 3600(4자리)에 맞춘 폭: 숫자 4칸(4ch) + 좌우 여백·테두리 (입력도 4자리로 제한, panel-settings.js) */
.setting-input {
  width: calc(4ch + 20px); min-height: 38px; padding: 6px 8px;
  text-align: right; font-variant-numeric: tabular-nums;
}
.setting-unit { font-size: .88rem; color: var(--muted); }
/* 적용 버튼 옆 입력 범위, 줄 오른쪽 끝의 마지막 지시 시각 — 둘 다 작은 회색 글씨 */
.setting-range { font-size: .78rem; color: var(--muted); white-space: nowrap; }
.setting-meta {
  margin-left: auto; font-size: .78rem; color: var(--muted);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.setting-meta[hidden] { display: none; }
.preview {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 4 / 3; overflow: hidden;
  max-width: 420px;                    /* PC 에서 본문 폭(720px)만큼 커지지 않게 */
  margin-inline: auto;                 /* 폭이 남으면(PC·넓은 팝업) 가운데에 */
  background-color: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.preview img { width: 100%; height: 100%; object-fit: cover; }
.preview .hint { margin: 0; }

/* 카드 제목 가운데 — 내 정보·카메라 추가 (팝업 제목과 맞춘다) */
.card.center-title > h2 { text-align: center; }
.card.center-title > h2 + .facts { margin-top: 10px; }
/* 제목 아래 안내 한 줄(카메라 추가) — 페이지·팝업 모두 가운데 */
p.sub.center-sub { text-align: center; }

/* --- 이미지 저장(스냅샷 아카이브, README 38) -------------------------------- */
.setting-select { min-height: 38px; padding: 6px 10px; }
.setting-value { font-size: .88rem; font-variant-numeric: tabular-nums; }
.setting-row[hidden], .setting-actions[hidden] { display: none; }   /* display:flex 가 hidden 을 이기지 않게 */
.setting-empty { margin: 4px 0 0; font-size: .9rem; color: var(--muted); }
/* 끄기·용량 줄이기를 섹션 안에서 되묻는 줄 */
.setting-confirm {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin: 0 0 8px; padding: 8px 10px; border-radius: var(--radius-sm);
  background-color: color-mix(in srgb, var(--warn) 12%, var(--card)); font-size: .88rem;
}
.setting-confirm[hidden] { display: none; }
.setting-confirm > span { margin-right: auto; }
.setting-actions { display: flex; justify-content: flex-end; padding-top: 12px; border-top: 1px solid var(--line); }
.setting-actions button.primary { width: auto; }

/* 뷰어 (archive.html) */
.archive-empty { padding: 20px; text-align: center; max-width: 720px; margin-inline: auto; }   /* 넓은 main.watch 에서도 예전 폭 */
.archive-empty p { margin: 0 0 14px; }
.archive-empty button.primary { width: auto; }
/* 화면은 실시간 영상 보기의 .player 를 그대로 쓴다(폭·폰 좌우 끝까지·그림자). 이미지는 video 와 같은 규칙:
   원본 비율(--player-ratio), 높이는 화면의 78% 까지, 잘리거나 찌그러지지 않게 contain.
   --player-w·--player-ratio 는 archive.html 의 fit() 이 첫 장의 해상도로 넣는다 */
.archive-frame {
  display: flex; align-items: center; justify-content: center; width: 100%;
  aspect-ratio: var(--player-ratio, 16 / 9); max-height: 78svh; background-color: #000;
}
.archive-frame img { display: block; width: 100%; height: 100%; object-fit: contain; }
.archive-frame .hint { color: #cbd5e1; margin: 0; }
@media (orientation: landscape) and (max-height: 560px) {
  .archive-frame { max-height: 100svh; }
}
/* 조작 줄 — 플레이어와 같은 폭으로 그 아래에 */
.archive-panel { max-width: var(--player-w, 1280px); margin: 12px auto 0; }
.archive-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.archive-bar .setting-select { width: auto; }
.archive-bar { flex-wrap: wrap; }                     /* 폰: 날짜·시간·시각·장수가 좁으면 두 줄로 */
.archive-time { font-size: 1.05rem; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--on-backdrop); }
.archive-count { margin-left: auto; font-size: .85rem; color: var(--on-backdrop-muted); font-variant-numeric: tabular-nums; }
.archive-slider { width: 100%; margin: 4px 0 0; accent-color: var(--brand); }
/* 바 양 끝의 시각 — 지금 범위(하루 전체 / 고른 한 시간)의 처음과 끝 */
.archive-range {
  display: flex; justify-content: space-between; margin: 2px 2px 12px;
  font-size: .78rem; color: var(--on-backdrop-muted); font-variant-numeric: tabular-nums;
}
.archive-controls { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; }
.archive-controls > button.primary { width: auto; min-width: 88px; }
.quality.speed button { padding: 6px 14px; }
.quality.speed button::before { display: none; }       /* SD/HD 막대 아이콘은 화질 버튼 전용 */
