/* CONSTELLATION — アプリ内蔵カメラ(getUserMedia + canvasキャプチャ)。
   OSネイティブのカメラ/ビデオ/ボイスメモアプリを経由しないため、
   日本向けiPhoneで消せないシャッター音を回避できる。効果音は全て
   Web Audio合成(js/camera.js)。見た目はアプリ本体のテーマとは独立した
   常時黒背景(実機カメラのフルスクリーン体験として)。 */

#camera-overlay {
  position: fixed;
  top: 0;
  left: 0;
  /* **2026年9月修正**: 以前は`inset:0`(=100vh相当)で全画面を確保していたが、モバイルブラウザの
     アドレスバー・ボトムツールバーが表示されている状態では、100vh(古い"largest viewport"基準)は
     実際に見えている範囲より大きく、はみ出た分がブラウザUIの裏に隠れて見えなくなる。
     このオーバーレイのDOM上のサイズ(js/camera.jsのcomputeCoverCropRect()が
     getBoundingClientRect()で読む値)は隠れた分も含めた大きい方のままなので、撮影結果には
     ユーザーが実際に画面で見ていた範囲より上下に広い範囲が写り込んでしまう
     (「ブラウザヘッダ・ボトムで見切れているのに、実際の写真はそこまで写っている」という
     実機報告)。動的ビューポート単位(dvh/dvw、今の実際に見えている範囲に追従)へ切り替え、
     プレビューの見た目と撮影結果を一致させる。dvh未対応の古いブラウザ向けに、先に通常の
     vh/vwを書いておき、対応ブラウザだけ後続の宣言で上書きされるようにしている。
     **2026年9月追記**: 一時期この上をさらにJS(js/camera.jsのsyncCameraOverlayToVisualViewport()、
     現在は削除済み)からvisualViewportの値で上書きしていたが、getUserMedia使用中に端末を
     回転させるとwindow.innerWidth/visualViewportがJSからは凍結して更新されない実機不具合
     (iOS、Safari/Chrome両方で確認)が判明したため撤回した。このサイズ指定は再びCSSの
     dvh/dvwのみに委ねている(js/camera.jsのbindCameraViewportSync()参照)。 */
  width: 100vw;
  height: 100vh;
  width: 100dvw;
  height: 100dvh;
  z-index: 200;
  background: #0a0a0a;
  color: #fff;
  display: none;
  font-family: 'IBM Plex Mono', monospace;
  -webkit-user-select: none;
  user-select: none;
  /* ピンチ操作を独自のズーム(js/camera.jsのwirePinchZoom())専用にするため、
     ブラウザ標準のページ全体のピンチズーム/スクロールを無効化する
     (2026年9月、実機でピンチしたら画面ごとズームされシャッターボタンが
     見切れる不具合があったための対応)。 */
  touch-action: none;
}
#camera-overlay.open { display: block; }

#camera-close {
  position: absolute; top: calc(10px + env(safe-area-inset-top, 0px)); right: 8px; z-index: 20;
  background: rgba(0, 0, 0, 0.55); border: 1px solid rgba(255, 255, 255, 0.25); color: #fff;
  font-family: inherit; font-size: 10px; padding: 7px 10px; border-radius: 14px; cursor: pointer;
}

.cam-screen { position: absolute; inset: 0; display: none; overflow: hidden; touch-action: none; }
.cam-screen.active { display: block; }
.cam-screen video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background: #000; transform-origin: center center;
  /* 回転直後の一瞬だけjs/camera.jsのhandleCameraOrientationSettle()がopacity:0にする際、
     唐突な明滅ではなく滑らかなフェードにするため(2026年9月追加)。 */
  transition: opacity 0.15s ease-out;
}

/* ピンチズーム中(js/camera.jsのsetCamZoom())の倍率表示。ネイティブ制御(track.applyConstraints)
   ではなくCSS拡大によるデジタルズームの場合は🔍を添えて区別する。 */
.cam-zoom-badge {
  position: absolute; top: calc(14px + env(safe-area-inset-top, 0px)); left: 50%; transform: translateX(-50%);
  z-index: 6; background: rgba(0, 0, 0, 0.55); border: 1px solid rgba(255, 255, 255, 0.25);
  color: #fff; font-family: inherit; font-size: 11px; padding: 4px 10px; border-radius: 12px;
  pointer-events: none;
}

/* 画面上部はブラウザ/OSのカメラ使用中インジケーターと重なるため、ヒントはボトム側に置く */
.cam-hint {
  position: absolute; bottom: calc(78px + env(safe-area-inset-bottom, 0px)); left: 0; right: 0; z-index: 5; text-align: center;
  font-family: inherit; font-size: 9px; letter-spacing: 0.08em; color: rgba(255, 255, 255, 0.6);
  padding: 0 16px; pointer-events: none;
}

/* ---------- 傾きガイド(トンボ) ---------- */
.cam-tilt-layer { position: absolute; inset: 34px; pointer-events: none; z-index: 4; visibility: hidden; }
.cam-tilt-layer.enabled { visibility: visible; }
.cam-tick { position: absolute; width: 24px; height: 24px; transition: transform 0.08s linear, opacity 0.2s; }
.cam-tick svg { width: 100%; height: 100%; }
.cam-tick path { stroke: #fff; stroke-width: 2; fill: none; stroke-linecap: round; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5)); }
.cam-tilt-layer.aligned .cam-tick path { stroke: #8fe08f; }
.cam-t-tl { top: 0; left: 0; }
.cam-t-tr { top: 0; right: 0; }
.cam-t-bl { bottom: 0; left: 0; }
.cam-t-br { bottom: 0; right: 0; }
.cam-align-pulse {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.85); z-index: 4;
  font-family: inherit; font-size: 9.5px; letter-spacing: 0.1em; color: #8fe08f; opacity: 0;
  transition: opacity 0.2s, transform 0.2s; pointer-events: none;
}
.cam-align-pulse.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }

/* ---------- 手描きフォーカス(タップでピント) ---------- */
.cam-focus-layer { position: absolute; inset: 0; pointer-events: none; z-index: 4; }
.cam-focus-group { position: absolute; }
.cam-focus-rect { position: absolute; width: 96px; height: 96px; left: -48px; top: -48px; }
.cam-focus-rect path { fill: none; stroke: #fff; stroke-width: 1.6; stroke-linecap: round; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5)); }
.cam-sun { position: absolute; left: 56px; top: -14px; width: 26px; height: 26px; }
.cam-sun circle, .cam-sun line { stroke: #ffe27a; stroke-width: 1.6; fill: none; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5)); }

/* ---------- 写真:シャッター ---------- */
.cam-shutter-btn {
  position: absolute; bottom: calc(26px + env(safe-area-inset-bottom, 0px)); left: 50%; transform: translateX(-50%);
  z-index: 8; width: 64px; height: 64px; border-radius: 50%; background: #fff;
  border: 3px solid rgba(255, 255, 255, 0.4); cursor: pointer; padding: 0;
}
.cam-shutter-btn:disabled { opacity: 0.5; cursor: default; }

/* ---------- テクスト:キャプション読み取り ---------- */
.cam-cap-btn {
  position: absolute; bottom: calc(26px + env(safe-area-inset-bottom, 0px)); left: 50%; transform: translateX(-50%);
  z-index: 8; font-family: inherit; font-size: 10px; color: #000; background: #fff; border: none;
  border-radius: 20px; padding: 11px 22px; cursor: pointer;
}
.cam-cap-btn:disabled { opacity: 0.5; cursor: default; }

/* ---------- テクスト:撮影後、範囲を選んでからOCRする ----------
   撮影直後は静止フレーム(cam-freeze-wrap、実体のcanvasはJSが差し込む)を表示し、
   その上でドラッグして選択した範囲だけを切り出してGeminiへ送る。選択しなければ
   全体を送る(従来通りの挙動)。 */
.cam-freeze-wrap { position: absolute; inset: 0; z-index: 3; display: none; background: #000; }
.cam-freeze-wrap.show { display: block; }
.cam-freeze-wrap canvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }

.cam-select-layer { position: absolute; inset: 0; z-index: 6; touch-action: none; display: none; }
.cam-select-layer.show { display: block; }
.cam-select-rect {
  position: absolute;
  border: 1.5px dashed #fff;
  background: rgba(255, 255, 255, 0.1);
  /* 選択範囲の外側だけを暗くする簡易マスク(要素1つで済ませるためbox-shadowを流用) */
  box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.5);
}

.cam-select-actions {
  position: absolute; bottom: calc(26px + env(safe-area-inset-bottom, 0px)); left: 0; right: 0; z-index: 8;
  display: none; justify-content: center; gap: 10px; padding: 0 16px;
}
.cam-select-actions.show { display: flex; }
.cam-select-btn {
  font-family: inherit; font-size: 10px; border-radius: 20px; padding: 11px 18px; cursor: pointer;
}
.cam-select-retake { background: rgba(255, 255, 255, 0.12); color: #fff; border: 1px solid rgba(255, 255, 255, 0.32); }
.cam-select-run { background: #fff; color: #000; border: none; }
.cam-select-btn:disabled { opacity: 0.5; cursor: default; }

/* ---------- 動画 ---------- */
.cam-video-timer {
  position: absolute; top: 14px; left: 50%; transform: translateX(-50%); z-index: 6;
  font-family: inherit; font-size: 12px; color: #fff; background: rgba(0, 0, 0, 0.4);
  padding: 4px 10px; border-radius: 10px; display: flex; align-items: center; gap: 6px;
}
.cam-rec-dot { width: 7px; height: 7px; border-radius: 50%; background: #e04b3f; animation: cam-blink 1.1s step-end infinite; }
@keyframes cam-blink { 50% { opacity: 0.2; } }
.cam-video-rec-btn {
  position: absolute; bottom: calc(26px + env(safe-area-inset-bottom, 0px)); left: 50%; transform: translateX(-50%);
  z-index: 8; width: 64px; height: 64px; border-radius: 50%; background: none; border: 3px solid #fff; cursor: pointer; padding: 0;
}
.cam-video-rec-btn::after { content: ''; display: block; margin: auto; width: 26px; height: 26px; border-radius: 6px; background: #e04b3f; transition: 0.15s; }
.cam-video-rec-btn.recording::after { border-radius: 3px; width: 20px; height: 20px; }

/* ---------- 音声 ---------- */
.cam-audio-scene { position: absolute; inset: 0; background: #111; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 26px; }
.cam-wave-wrap { width: 220px; height: 64px; }
.cam-wave-wrap svg { width: 100%; height: 100%; overflow: visible; }
.cam-wave-wrap path { fill: none; stroke: #fff; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; opacity: 0.9; }
.cam-audio-timer { font-family: inherit; font-size: 13px; color: rgba(255, 255, 255, 0.7); letter-spacing: 0.05em; }
.cam-audio-btn { background: none; border: none; cursor: pointer; width: 76px; height: 76px; padding: 0; }
.cam-audio-btn svg { width: 100%; height: 100%; }
.cam-audio-btn path { stroke: #fff; stroke-width: 2; fill: none; stroke-linecap: round; }
.cam-audio-label { font-family: inherit; font-size: 9px; color: rgba(255, 255, 255, 0.5); letter-spacing: 0.1em; }

/* ---------- エラー表示 ---------- */
#camera-error {
  position: absolute; left: 16px; right: 16px; bottom: calc(96px + env(safe-area-inset-bottom, 0px)); z-index: 15;
  background: rgba(224, 75, 63, 0.15); border: 1px solid rgba(224, 75, 63, 0.5); color: #ffb4ac;
  font-family: inherit; font-size: 11px; padding: 10px 12px; border-radius: 6px; text-align: center;
}
