:root {
  color-scheme: light dark; --bg:#07111b; --surface:#0d1b29; --surface-2:#142536; --text:#f4f8fb;
  --muted:#aebfcd; --line:#30475b; --accent:#70d2ff; --accent-text:#061019;
  --video:#ff6577; --image:#ffd166; --page:#bac5cf; --windy:#5cc8ff; --shadow:0 16px 50px #0008;
  /* 地図の上に浮くもの（ズーム・凡例・現在地・どこかの窓）の角丸と面の色。ばらばらだと寄せ集めに見える。 */
  --radius-control:12px; --control-surface:rgba(15,23,32,.9);
  /* 上部バーの下端。lib/ui.js が ResizeObserver で実測して上書きする（ここは測る前の目安）。 */
  --topbar-h:132px;
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Noto Sans JP", sans-serif;
}
@media (prefers-color-scheme:light) { :root:not([data-theme]) { --bg:#eef4f7;--surface:#fff;--surface-2:#e5eef3;--text:#10202c;--muted:#526675;--line:#a8bbc8;--accent:#006da0;--accent-text:#fff;--video:#b81736;--image:#b45309;--page:#4d5d68;--windy:#006da0;--shadow:0 16px 45px #1734492b;--control-surface:#fff; } }
:root[data-theme="light"] { --bg:#eef4f7;--surface:#fff;--surface-2:#e5eef3;--text:#10202c;--muted:#526675;--line:#a8bbc8;--accent:#006da0;--accent-text:#fff;--video:#b81736;--image:#b45309;--page:#4d5d68;--windy:#006da0;--shadow:0 16px 45px #1734492b;--control-surface:#fff; }
* { box-sizing:border-box; }
/* hidden 属性を表示のスイッチとして使うので、後ろに書いた display 指定（チップの flex など）に負けないようにする。 */
[hidden] { display:none!important; }
/* 地図アプリなので画面に収める。出典・共有はパネルの中身の末尾にあり、そこがスクロールする。 */
html,body { margin:0; min-width:320px; height:100%; background:var(--bg); color:var(--text); }
body { font-size:16px; line-height:1.55; overflow:hidden; --panel-w:400px; }
/* 詳細（とくにYouTube）はパネルの幅が足りないので、開いている間だけ広げる。 */
body.has-detail { --panel-w:min(560px,calc(100vw - 24px)); }
button,input { font:inherit; }
button,a { -webkit-tap-highlight-color:transparent; }
button { color:inherit; cursor:pointer; }
a { color:var(--accent); }
svg { fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.sr-only { position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0; }
.skip-link { position:fixed;left:12px;top:-60px;z-index:100;padding:10px 16px;background:var(--surface);color:var(--text);border:2px solid var(--accent); }
.skip-link:focus { top:12px; }
:focus-visible { outline:3px solid var(--accent); outline-offset:2px; }
/* パネルを開くと見出しへフォーカスを移す（読み上げの位置を合わせるため）。既定の枠が出ると
   見出しが入力欄に見えてしまうので、キーボードで辿り着いたときだけ枠を出す。 */
#panel-title:focus:not(:focus-visible) { outline:none; }
#panel-title:focus-visible { outline:2px solid var(--accent);outline-offset:4px;border-radius:6px; }
.app-shell { position:relative; height:100svh; overflow:hidden; }
.topbar { position:absolute; z-index:30; top:12px; left:12px; right:12px; display:grid; grid-template-columns:auto minmax(210px,440px) auto; align-items:center; gap:10px; padding:10px; border:1px solid var(--line); border-radius:18px; background:color-mix(in srgb,var(--surface) 94%,transparent); box-shadow:var(--shadow); backdrop-filter:blur(14px); }
.brand { display:flex; align-items:center; gap:10px; min-width:190px; }
.brand h1 { font-size:1.15rem; letter-spacing:.08em; margin:0; line-height:1.25; }
.brand p { color:var(--muted); font-size:.82rem; margin:1px 0 0; white-space:nowrap; }
.brand-orbit { width:32px;height:32px;border:2px solid var(--accent);border-radius:50%;position:relative;flex:none; }
.brand-orbit::before,.brand-orbit::after { content:"";position:absolute;inset:5px -2px;border-top:1px solid var(--image);border-bottom:1px solid var(--image);border-radius:50%; }
.brand-orbit::after { inset:-2px 10px; }
.search-area { position:relative; }
.search-box { min-height:44px; display:flex; align-items:center; gap:8px; border:1px solid var(--line); border-radius:12px; background:var(--bg); padding:0 12px; }
.search-box svg { width:20px; flex:none; }
.search-box input { width:100%; min-width:0; border:0; outline:0; color:var(--text); background:transparent; }
.search-box input::placeholder { color:var(--muted); }
.search-results { --search-row:62px; position:absolute; top:50px; width:100%; max-height:min(calc(100vh - 120px),calc(var(--search-row) * 5.5 + 40px)); overflow:auto; scrollbar-gutter:stable; padding:6px; background:var(--surface); border:1px solid var(--line); border-radius:12px; box-shadow:var(--shadow); }
/* 続きがあるときだけ下端をぼかす。1〜2件しか無いのに最後の行が薄いと、読めない字に見える。 */
.search-results.has-more { -webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 24px),transparent);mask-image:linear-gradient(to bottom,#000 calc(100% - 24px),transparent); }
/* 候補は「名前 → 当たった項目 → 種別」の3点で読めるようにする。名前で当たっていない候補が
   理由なく並ぶと、検索が壊れているように見えた。 */
.search-results button { display:grid;grid-template-columns:1fr auto;align-items:center;gap:2px 10px;width:100%;height:var(--search-row);padding:7px 10px;text-align:left;border:0;border-radius:8px;background:transparent; }
.search-results button:hover,.search-results button[aria-selected="true"] { background:var(--surface-2); }
.search-count { margin:2px 4px 6px;color:var(--muted);font-size:.82rem;line-height:1.6; }
.search-option-text { display:grid;gap:1px;min-width:0; }
.search-option-text strong,.search-option-text small { overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
.search-option-text small { color:var(--muted);font-size:.82rem;line-height:1.6; }
.search-results mark { background:transparent;color:var(--accent);font-weight:600; }
.icon-button,.filters button,.secondary-button,.close-button { min-width:44px;min-height:44px;border:1px solid var(--line);border-radius:12px;background:var(--surface-2); }
.icon-button { display:flex;align-items:center;gap:7px;padding:0 11px; }
/* auto トラックは余った幅を吸うので、そのままだと検索欄と同じ幅まで伸びる。内容の幅に留める。 */
#theme-toggle { justify-self:end;width:max-content; }
.icon-button svg { width:20px; }
.filters { grid-column:1 / -1; display:flex; gap:7px; flex-wrap:wrap; }
.filters button { display:flex;align-items:center;gap:6px;padding:0 12px; }
.kind-dot { flex:none;width:11px;height:11px;border-radius:50%;background:currentColor;box-shadow:0 0 0 1px rgb(0 0 0 / .35); }
.kind-dot.video { color:var(--video); }.kind-dot.image { color:var(--image); }.kind-dot.page { color:var(--page); }.kind-dot.windy { color:var(--windy); }
.filters button[aria-pressed="true"] { background:color-mix(in srgb,var(--accent) 18%,transparent);border-color:var(--accent);font-weight:600; }
/* OFF は面を抜いて文字を弱める。取り消し線も残す（色だけで状態を伝えない）。 */
.filters button[aria-pressed="false"] { background:transparent;color:var(--muted);text-decoration:line-through; }
.filters button[aria-pressed="false"] .kind-dot { opacity:.3; }
.map-stage,#map { position:absolute;inset:0; }
/* パネル(z:25)より下・地図の浮きもの(z:20)より上。地図を覆うが出典は透けて残る（ODbLの表示条件）。 */
.map-scrim { position:absolute;inset:0;z-index:24;width:100%;border:0;background:rgb(0 0 0 / .45); }
/* 「現在地」が属性表示の上に乗ると出典が読めなくなる。ズーム＋／−と属性表示の上へ逃がす。 */
.map-actions { position:absolute;z-index:20;right:16px;bottom:112px;display:flex;flex-direction:column;align-items:flex-end;gap:8px; }
.primary-button,.secondary-button { display:flex;align-items:center;justify-content:center;gap:8px;min-height:48px;padding:0 16px;border-radius:var(--radius-control);font-weight:700;box-shadow:0 8px 24px #0005; }
/* 主ボタンだけは地図の上で唯一の色付き。面の色をそろえる対象は、その周りの中立なもの（凡例・現在地・ズーム）。 */
.primary-button { border:1px solid color-mix(in srgb,var(--accent) 70%,white);background:var(--accent);color:var(--accent-text); }
.secondary-button { background:var(--control-surface); }
.primary-button svg,.secondary-button svg { width:21px;height:21px; }
/* 凡例は右下だとズーム＋／−に重なって押せなくなる。左下・属性表示の上へ（パネルの右隣から始める）。
   幅はズームボタンの手前で止める。詳細を開くとパネルが広がって地図側の余地が無くなるので、そのときは出さない
   （見ている種別のバッジは詳細の中にある）。 */
.legend { position:absolute;z-index:20;left:calc(var(--panel-w) + 24px);bottom:40px;display:flex;flex-wrap:wrap;gap:6px 12px;max-width:calc(100vw - var(--panel-w) - 90px);padding:7px 11px;border:1px solid var(--line);border-radius:var(--radius-control);background:var(--control-surface);font-size:.82rem;line-height:1.6; }
body.has-detail .legend { display:none; }
.legend span,.list-legend span { display:flex;align-items:center;gap:4px; }
/* 薄い色の丸（ライトの黄など）が背景に溶けないよう、細い輪郭を足す。 */
.legend i,.list-legend i { flex:none;width:11px;height:11px;border-radius:50%;background:currentColor;box-shadow:0 0 0 1px rgb(0 0 0 / .35); }
.legend .video,.list-legend .video{color:var(--video)}.legend .image,.list-legend .image{color:var(--image)}.legend .page,.list-legend .page{color:var(--page)}.legend .windy,.list-legend .windy{color:var(--windy)}
/* 貼り付けた見出しの下を中身が通るので、パネルの面は透かさない（透けると文字が重なって読めない）。 */
.panel { position:absolute;z-index:25;top:calc(var(--topbar-h) + 12px);left:12px;bottom:12px;width:var(--panel-w);border:1px solid var(--line);border-radius:18px;background:var(--surface);box-shadow:var(--shadow);overflow:hidden; }
.sheet-handle { display:none; }
/* 上の余白は見出しの帯（.panel-head）が持つ。スクロール領域に余白を持たせると、
   貼り付いた帯が余白のぶんだけ下へずれて、次の行に重なる。 */
.panel-content { --pad-x:18px;--pad-t:18px;height:100%;overflow:auto;padding:0 var(--pad-x) 18px;scrollbar-color:var(--line) transparent; }
/* 下端のフェードは「まだ続きがある」ときだけ。読み切った状態で出典や共有ボタンが薄いまま残らないようにする。 */
.panel-content.has-more-below { -webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 46px),rgb(0 0 0 / .35) calc(100% - 16px),transparent);mask-image:linear-gradient(to bottom,#000 calc(100% - 46px),rgb(0 0 0 / .35) calc(100% - 16px),transparent); }
/* スクロールすると見出しと×が消えて、どのカメラを見ているのか・どう閉じるのかが分からなくなっていた。
   パネルの内側の余白ぶんだけ外へ広げて、幅いっぱいの帯として貼り付ける。 */
.panel-head { position:sticky;top:0;z-index:2;display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin:0 calc(var(--pad-x) * -1);padding:var(--pad-t) var(--pad-x) 8px;background:var(--surface); }
.panel-head::after { content:"";position:absolute;left:0;right:0;top:100%;height:14px;background:linear-gradient(var(--surface),transparent);opacity:0;pointer-events:none;transition:opacity .15s; }
.panel-content.has-more-above .panel-head::after { opacity:1; }
.eyebrow { margin:0 0 2px;color:var(--accent);font-size:.68rem;font-weight:800;letter-spacing:.18em; }
.panel h2 { margin:0;font-size:1.28rem;line-height:1.35; }
.close-button { flex:none;font-size:1.65rem;line-height:1; }
.panel-subtitle,.list-legend { display:none; }
.panel-counts { display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:2px 12px;margin:6px 0 12px; }
/* 詳細では中身が空になる（一覧のメタもチップの件数も出さない）ので、余白だけを残さない。 */
.panel.is-detail .panel-counts { margin:0; }
.panel-count,.camera-count { margin:0;color:var(--muted);font-size:.82rem; }
.camera-list { display:grid;gap:8px; }
.camera-row { min-height:58px;width:100%;display:grid;grid-template-columns:1fr auto;gap:4px 10px;padding:9px 11px;text-align:left;border:1px solid var(--line);border-radius:12px;background:var(--surface-2); }
.camera-row:hover { border-color:var(--accent); }.camera-row strong { overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }.camera-row small { color:var(--muted);font-size:.82rem;line-height:1.6; }.camera-row .badge { grid-column:2;grid-row:1/3;align-self:center; }
.badge { display:inline-flex;align-items:center;gap:5px;width:max-content;padding:3px 8px;border:1px solid currentColor;border-radius:999px;font-size:.72rem;font-weight:700; }
.badge::before { content:"";width:7px;height:7px;border-radius:50%;background:currentColor; }.badge.video{color:var(--video)}.badge.image{color:var(--image)}.badge.page{color:var(--page)}.badge.windy{color:var(--windy)}
.skeleton { height:62px;border-radius:12px;background:linear-gradient(100deg,var(--surface-2) 30%,color-mix(in srgb,var(--surface-2) 65%,white) 48%,var(--surface-2) 66%);background-size:250% 100%;animation:shimmer 1.2s infinite; }
@keyframes shimmer { to { background-position-x:-250%; } }
.empty,.error { padding:24px 14px;text-align:center;color:var(--muted);border:1px dashed var(--line);border-radius:12px; }
.error { color:var(--video); }
.privacy-note { margin:14px 0 8px;padding:9px 11px;border-left:3px solid var(--image);background:var(--surface-2);font-size:.82rem;line-height:1.6; }
.viewer { width:100%;margin:0 0 16px; }
.viewer-frame { width:100%;position:relative;overflow:hidden;border-radius:12px;background:#000; }
.viewer-frame iframe,.viewer-frame video,.viewer-frame img { display:block;width:100%;border:0;object-fit:contain;background:#000; }
/* 幅をパネルより広げると overflow で右が切れる（YouTubeの「プレーヤーを遮らない」に触れる）。常に幅いっぱい。 */
.viewer-frame iframe,.viewer-frame video { aspect-ratio:16/9;min-height:200px; }
.viewer-frame img { max-height:55vh; }
/* 読めなかったときに黒い箱を残さない。面の色に戻して、文言と提供元ボタンだけを見せる。 */
.viewer-frame.is-fallback { background:var(--surface-2); }
.viewer-note,.fetched { margin:6px 0;color:var(--muted);font-size:.82rem;line-height:1.6; }.viewer-tools { display:flex;align-items:center;justify-content:space-between;gap:10px; }.viewer-tools button { min-height:44px;padding:0 14px;border:1px solid var(--line);border-radius:10px;background:var(--surface-2); }
.viewer-fallback { padding:24px 14px;text-align:center;background:var(--surface-2);border-radius:12px; }
.sheet-expand { display:none; }
.large-link { min-height:48px;display:inline-flex;align-items:center;justify-content:center;margin-top:8px;padding:0 16px;border-radius:12px;background:var(--accent);color:var(--accent-text);font-weight:800;text-decoration:none; }
.details { display:grid;grid-template-columns:7.3em 1fr;margin:0; }.details dt,.details dd { padding:8px 0;border-bottom:1px solid var(--line); }.details dt { color:var(--muted); }.details dd { margin:0;overflow-wrap:anywhere; }
.direction-arrow { display:inline-block;width:18px;height:18px;margin-right:5px;vertical-align:-4px;transform:rotate(var(--direction)); }
.external-links { display:grid;gap:8px;margin:16px 0; }.external-links a { min-height:44px;display:flex;align-items:center;padding:0 12px;border:1px solid var(--line);border-radius:10px;text-decoration:none; }
.source-note,.windy-credit { font-size:.82rem;line-height:1.6;color:var(--muted); }.windy-credit a { color:inherit; }
.toast { position:absolute;z-index:40;left:50%;bottom:80px;transform:translateX(-50%);max-width:min(90vw,420px);padding:12px 16px;border-radius:10px;background:var(--surface);border:1px solid var(--video);box-shadow:var(--shadow); }
.map-unavailable { position:absolute;inset:40% 20px auto;text-align:center;padding:15px;background:var(--surface); }
.maplibregl-ctrl-attrib { display:block!important;font-size:10px!important; }
/* 属性表示はパネルの右隣に逃がす（左下のままだとパネルの下敷きになって読めない）。
   幅もズームボタンの手前で止め、狭いときは折り返させる（重ねて隠さない＝ODbLの表示条件）。 */
.maplibregl-ctrl-bottom-left { left:calc(var(--panel-w) + 14px);max-width:calc(100vw - var(--panel-w) - 90px); }
/* ズームの＋／−は既定 29px で押しづらい。他のボタンと同じ 44px に。 */
.maplibregl-ctrl-group button { width:44px;height:44px;color:var(--text); }
/* 面と角丸を他のオーバーレイにそろえる（既定は白・角丸4px固定で、ダークだと白い箱が浮いていた）。 */
.maplibregl-ctrl-group,.maplibregl-ctrl-group:not(:empty) { border:1px solid var(--line);border-radius:var(--radius-control);background:var(--control-surface);box-shadow:var(--shadow);overflow:hidden; }
.maplibregl-ctrl-group button+button { border-top:1px solid var(--line); }
/* ＋／−の絵は MapLibre が背景画像で持っていて、data-theme での切替に追従できない。
   形だけ mask で借りて、色は文字色で塗る。 */
.maplibregl-ctrl-group button .maplibregl-ctrl-icon { background-color:currentColor;-webkit-mask:var(--ctrl-icon) center/24px no-repeat;mask:var(--ctrl-icon) center/24px no-repeat; }
/* 既定の絵は .maplibregl-ctrl を含む3クラスの規則で塗られている。同じ強さで打ち消す。 */
.maplibregl-ctrl-group button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon,
.maplibregl-ctrl-group button.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon { background-image:none; }
.maplibregl-ctrl-group button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon { --ctrl-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' viewBox='0 0 29 29'%3E%3Cpath d='M14.5 8.5c-.75 0-1.5.75-1.5 1.5v3h-3c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h3v3c0 .75.75 1.5 1.5 1.5S16 19.75 16 19v-3h3c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13h-3v-3c0-.75-.75-1.5-1.5-1.5'/%3E%3C/svg%3E"); }
.maplibregl-ctrl-group button.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon { --ctrl-icon:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' viewBox='0 0 29 29'%3E%3Cpath d='M10 13c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h9c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13z'/%3E%3C/svg%3E"); }
footer { margin-top:18px;padding-top:16px;border-top:1px solid var(--line);font-size:.82rem;line-height:1.6;color:var(--muted); }
footer p { margin:0 0 8px; }
/* 共通のシェア欄は「幅が中身で決まる親」に置かれる想定で最低幅を持っている。
   ここは幅の決まったパネルの中なので外す（付けたままだと注意書きが右へはみ出して切れる）。 */
#panel .share { min-width:0;max-width:100%; }

@media (max-width:719px) {
  /* 上部バーは画面の1/4を占めていた。副題を一覧側へ移し、テーマ切替をチップの行に置いて3行に収める。 */
  .topbar { top:8px;left:8px;right:8px;grid-template-columns:1fr auto;padding:6px 8px;gap:6px;border-radius:15px; }
  .brand { grid-column:1 / -1;grid-row:1;min-width:0; }
  .brand p { display:none; }.brand-orbit{width:28px;height:28px}.brand h1{font-size:1rem}
  .search-area { grid-column:1 / -1;grid-row:2; }
  .filters { grid-column:1;grid-row:3;flex-wrap:nowrap;overflow-x:auto;padding-bottom:1px; }.filters button { flex:none; }
  #theme-toggle { grid-column:2;grid-row:3; }
  .icon-button span { display:none; }
  .panel { top:auto;left:0;right:0;bottom:0;width:auto;height:45vh;border-radius:20px 20px 0 0;border-bottom:0;transition:height .22s ease; }
  /* 広げたシートが上部バーの下に潜ると、見出し・×・つまみが押せなくなる。バーの下端で止める。
     さらに地図を60px残す。ここが暗幕＝押して縮める逃げ道になり、地図が消えていないことの合図にもなる
     （上部バーは畳んでタイトル行だけになるので、残す60pxを引いても一覧の高さは増える）。 */
  .panel.is-expanded { top:calc(var(--topbar-h) + 60px);height:auto;bottom:0; }
  .panel-content { --pad-x:14px;--pad-t:8px; }
  .sheet-handle { display:grid;place-items:center;width:100%;height:44px;border:0;background:transparent; }.sheet-handle span { width:54px;height:5px;border-radius:9px;background:var(--line); }
  .map-actions { right:10px;bottom:calc(45vh + 34px); }
  /* 属性表示が2行に折り返してシートに潜り、「現在地」の下にも隠れていた。1行に収めてシートの直上に置き、
     ボタン列はその上へ逃がす（重ねて隠さない＝ODbLの表示条件。全文はパネル末尾の出典にもある）。 */
  .maplibregl-ctrl-bottom-left { left:0;bottom:calc(45vh + 2px);max-width:100vw; }
  /* ボタン列を上へ逃がしたので幅は画面いっぱい使える。出典は切らずに出せるところまで出す。 */
  .maplibregl-ctrl-attrib { max-width:calc(100vw - 20px); }
  .maplibregl-ctrl-attrib,.maplibregl-ctrl-attrib-inner { white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
  .primary-button,.secondary-button { min-height:44px; }
  /* 地図の凡例はシートに隠れるので、一覧の見出しの下に置く。 */
  .legend { display:none; }
  .panel-subtitle { display:block;margin:4px 0 0;color:var(--muted);font-size:.82rem; }
  .list-legend { display:flex;flex-wrap:wrap;gap:4px 12px;margin:0 0 10px;color:var(--muted);font-size:.82rem;line-height:1.6; }
  .sheet-expand { display:flex;align-items:center;justify-content:center;width:100%;min-height:44px;margin-top:4px;border:1px solid var(--line);border-radius:10px;background:var(--surface-2); }
  /* すでに広げてあるなら押しても何も起きないので出さない。 */
  .panel.is-expanded .sheet-expand { display:none; }
  body.sheet-expanded .search-area,body.sheet-expanded .filters,body.sheet-expanded #theme-toggle { display:none; }
}
@media (min-width:720px) and (max-width:950px) { .topbar { grid-template-columns:200px 1fr auto; }.brand p{display:none}.filters button{padding:0 9px} }
@media (prefers-reduced-motion:reduce) { *,*::before,*::after { animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:.01ms!important; } }

/* 暗幕は下シートのときだけ。PCではパネルが地図の隣に並ぶので覆う相手がいない。 */
@media (min-width:720px) { .map-scrim { display:none!important; } }
