/* マップページ（map.php）。 */

/* ヘッダーを出していないので画面いっぱいを使う。
   ★ 背景は絵（img/map/campus.webp）の余白と同じ**白**にすること。
   地図を回したり引いたりして絵の外が見えても、同じ色なら分からない。
   これがあるので、回転を角度で制限しなくてよい（js/map/map-transform.js の clampToBounds）。
   以前（MapLibre を使っていた頃）は背景を変えられなかったが、いまは自前なので自由。
   桜色（--c-sakura）などにすると、回したときに絵の角が見える。 */
.map-page {
  position: relative;
  height: 100dvh;
  overflow: hidden;
  background: #fff;
  /* 色は冊子の配色（css/tokens.css の --c-*）をそのまま使う。面は白（絵の余白と同じ。上の注）、押した地・薄い面は桜色、
     主役の色は濃いローズ、文字はサイトの茶みの墨。マップにしか無い色・影・重なりの順は css/map-legacy/tokens.css の --map-*
     （下の注に残る「橙」は模擬店コンテストから写した頃の言葉で、いまの濃いローズのこと） */
  color: var(--c-ink);
  /* 画面全体で文字を選べなくする。地図を掴んで動かしたときに、シートの
     文字まで選択（青く反転）されて目障りだった（2026-10-18 に指摘）。
     この画面で文字を写し取ることはまず無いので、検索欄だけ例外にする。 */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

.map-page input {
  -webkit-user-select: text;
  user-select: text;
}

/* 地図を掴む所。指の縦スワイプをブラウザに取られないよう
   touch-action: none を必ず指定する（PORTING.md 5-4）。
   指定しないと、払ったときにページごと動いて地図もシートもずれる。 */
.map-canvas {
  position: relative; /* 下に敷く絵の canvas（.map-picture）の基準 */
  height: 100%;
  width: 100%;
  overflow: hidden;
  touch-action: none;
}

/* 地図の絵。表示領域と同じ大きさで、js/map/map-picture.js が毎フレーム今の倍率で描き直す（そこの注）。
   帯・ピン・札の下に敷く。指の操作は .map-canvas が受ける。
   ★ CSS の transform で拡大する箱（以前の .map-stage / .map-layers）はもう無い（js/map.js の注）。
     拡大した箱の中身は、スマホで倍率が上がるとぼやける */
.map-picture {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* 帯・札・ピン・設備・現在地を入れる箱。
   画像と**同じ矩形**に重ねる（これが 0〜1 座標の基準になる）。
   画像と同じ箱に描くと、描き直しのたびに画像ごと消えてしまう。 */
/* ピン・札・設備・現在地を入れる箱。stage の**外**にあり、表示領域と同じ大きさで変換は掛けない
   （js/map/map-layers.js の placeMarkers の注。stage の中に置くと倍率が上がったときにぼやけた）。
   箱自体は指を受けない（下の帯と地図に届くように）。中身（.map-marker）だけ受ける */
.map-overlay {
  pointer-events: none;
  position: absolute;
  inset: 0;
  /* 現在地の方位。js/map.js が書き換える */
  --user-heading: 0deg;
}

/* --- 地図の上に置くもの ---
   位置は常に中心合わせ。地図をどれだけ拡大・回転しても、中身の見た目の
   大きさと向きは変わらないよう、親（.map-stage）の変換を打ち消す。
   打ち消す値は .map-overlay の CSS 変数で、js/map.js が指の動きに合わせて
   書き換える（要素は作り直さない。search/map の .map-pins > * と同じ）。
   ★ 中身で transform を上書きしないこと ── 地図の上の別の場所へ飛ぶ。 */
/* 位置は js が transform に入れる（translate3d(画面x, 画面y) translate(-50%, -50%)）。
   ★ 中身で transform を上書きしないこと ── 位置ごと飛ぶ。 */
.map-marker {
  pointer-events: auto;
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
}

.z-pin { z-index: 20; }
.z-pin-hover { z-index: 30; }
.z-selected { z-index: 40; }
.z-me { z-index: 30; }
.z-building { z-index: 5; }
/* 店の場所の手がかりの名前（.map-text--key）はピンより上に出す。文字は押せない（pointer-events: none）ので、
   重なっていても下のピンは押せる。選んだ店の札（40）より下。
   ただし通り（大学通り・富士見通り・旭通り）はピンより下（2026-11-08）。通りの上に店が並ぶので、札が店を隠していた */
.z-building.map-text--key { z-index: 22; }
.z-building.map-text--road.map-text--key { z-index: 6; }

/* --- 地図の名前（駅・大学・公園・通り。js/lib/building-labels.js、tools/draw_map.py が書き出す） ---
   絵に焼き込まず札として重ねる（2026-10-31〜）。大きさは画面 px で一定、向きは js（uprightAngle）が直す。
   地の色の縁取り（text-shadow）で道や建物の上でも読めるようにする。描き直しのたびに入れ替わるので animation は付けない */
.map-text {
  pointer-events: none;
  white-space: nowrap;
  font-family: var(--font-main);
  line-height: 1.2;
  color: var(--c-ink-soft);
  text-shadow: 0 0 2px #fcf6f5, 0 0 2px #fcf6f5, 0 0 3px #fcf6f5, 0 0 4px #fcf6f5;
}
.map-text--road { font-size: 11px; letter-spacing: 0.08em; }
.map-text--road.is-vertical { writing-mode: vertical-rl; text-orientation: upright; letter-spacing: 0.02em; }
.map-text--campus { font-size: 12px; font-weight: 500; }
.map-text--park { font-size: 12px; font-weight: 500; color: #5b7449; }
.map-text--townhall,
.map-text--shrine { font-size: 12px; font-weight: 500; color: var(--c-ink); }
/* ほかの駅は名前だけ（駅の点は絵に描いてある） */
.map-text--station { font-size: 11px; color: var(--c-ink-soft); }

/* --- 店の場所の手がかり（エリアの名前の通り・店の最寄駅・一橋大学。lib/building-labels.js の key） ---
   一番引いた状態からいつも出し、ほかの名前より目立たせる。言い回しは冊子と同じ:
   通りは道そのものをローズで塗り（tools/draw_map.py の KEY_STREETS）、名前に店名と同じ黄色のマーカーを引く。
   駅は白い札にローズの縁（冊子の地図の駅）。一橋大学は大きく濃いローズ */
.map-text--road.map-text--key {
  padding: 0 3px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.12em;
  color: var(--c-rose-deep);
  background: linear-gradient(transparent 58%, var(--c-marker) 58%);
}
.map-text--road.map-text--key.is-vertical { background: linear-gradient(90deg, transparent 50%, var(--c-marker) 50%); padding: 3px 0; letter-spacing: 0.04em; }
.map-text--station.map-text--key {
  padding: 1px 7px;
  border: 1px solid var(--c-rose-deep);
  border-radius: 6px;
  background: #fff;
  color: var(--c-ink);
  font-size: 12px;
  font-weight: 500;
  text-shadow: none;
  box-shadow: 0 1px 3px rgba(90, 60, 58, 0.18);
}
.map-text--campus.map-text--key { font-size: 16px; letter-spacing: 0.1em; color: var(--c-rose-deep); }

/* --- 模擬店のピン ---
   地の丸＋品目のアイコンの2色だけで描く。絵文字を入れていたときは
   この縮尺で絵柄が潰れて読めなかった。面で描いた図形なら
   小さくても形が残る。 */
.shop-pin,
.selected-pin {
  animation: map-fade-in 0.2s ease-out;
}

.shop-pin {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* 名前を出すのはホバー中だけ。吹き出しはピンの内側で absolute に
   持ち上げる（外側の位置をずらすと、拡大率の分だけピンが飛んで見える）。 */
.shop-pin__name {
  position: absolute;
  bottom: 100%;
  margin-bottom: var(--sp-1);
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
  border-radius: var(--map-radius-md);
  background: #fff;
  padding: var(--sp-1) var(--sp-2);
  font-size: 0.75rem;
  line-height: 1.25;
  font-weight: 500;
  white-space: nowrap;
  color: var(--c-ink);
  box-shadow: var(--map-shadow-card);
}

/* 丸の中にアイコン。絵柄は白抜き。
   以前は橙地に濃い茶だったが、絵柄が12px四方しかないので
   形が沈んで団子に見えていた。白なら小さくても形が立つ
   （絵柄はコントラスト比ではなく「形が読めるか」で決めてよい）。
   縁は白のままにして、地図のどんな色の上でも丸が浮くようにする。 */
.shop-pin__dot {
  display: flex;
  width: 1.375rem;
  height: 1.375rem;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  border: 2px solid #fff;
  background: var(--map-pin);
  color: #fff;
  box-shadow: 0 1px 4px rgba(90, 52, 12, 0.45);
}

/* 地の色は大分類ごと（js/map/map-layers.js の kindOf）。色は css/tokens.css の --c-genre-*（「マップで見る」の札の点と同じ） */
.shop-pin__dot.g-cutlery { background: var(--c-genre-food); }      /* 飲食 */
.shop-pin__dot.g-bag     { background: var(--c-genre-shopping); }  /* 買い物 */
.shop-pin__dot.g-cross   { background: var(--c-genre-medical); }   /* 医療 */
.shop-pin__dot.g-house   { background: var(--c-genre-life); }      /* 生活 */
.shop-pin__dot.g-school  { background: var(--c-genre-education); } /* 教育 */

.pin-icon {
  width: 0.75rem;
  height: 0.75rem;
}

/* --- 選んだ模擬店の目印 ---
   丸ではなく雫形にして、先端が実際の位置を指すようにする。
   全体を箱の半分だけ上へ持ち上げて、下端＝先端を中心に合わせる
   （以前は先端が店より 32px 下にあり、押すとピンが下に動いて見えた）。 */
.selected-pin {
  pointer-events: none;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* 選んでいる店のピン。地はその店の大分類の色のまま（赤く塗ると医療の赤と取り違える）、
   ひと回り大きくして外側に輪を付ける。
   輪はサイトの「選んでいる」色（--c-rose-deep。上の店名の札の枠・タブバーの現在地と同じ）。
   以前は模擬店コンテストのままの黒に近い色で、札の枠と色が分かれていた（2026-11-06）。
   医療の赤いピンでも、白い縁が間に入るので輪と混ざらない。
   ★ transform は書かない（位置は .map-marker の transform が決めている） */
.shop-pin__dot.is-selected {
  width: 1.75rem;
  height: 1.75rem;
  box-shadow: 0 0 0 3px #8e5c58, 0 2px 8px rgba(90, 52, 48, 0.4);
}

.shop-pin__dot.is-selected .pin-icon {
  width: 1rem;
  height: 1rem;
}

/* 名前は白地に濃い橙。橙地に濃茶だと、地図の上で札そのものが
   ピンと同じ色の塊になって、どこからどこまでか分かりにくい。 */
.selected-pin__name {
  position: absolute;
  bottom: 100%;
  margin-bottom: 0.125rem;
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
  border-radius: 999px;
  border: 1px solid var(--c-rose-deep);
  background: #fff;
  padding: var(--sp-1) 0.625rem;
  font-size: 0.75rem;
  line-height: 1.25;
  font-weight: 700;
  white-space: nowrap;
  color: var(--c-rose-deep);
  box-shadow: var(--map-shadow-card);
}

/* --- 現在地 ---
   青にする。地図アプリで青い丸といえば自分の位置、という約束が
   広く通っているので、それに合わせる。オレンジは模擬店のピンで
   使っている色なので、現在地に使うと店の一つに見えてしまう。 */
.my-location {
  pointer-events: none;
  display: block;
  width: 1rem;
  height: 1rem;
}

.my-location__dot {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  border: 2px solid #fff;
  background: #2f7de1;
  box-shadow: 0 0 0 6px rgba(47, 125, 225, 0.24), 0 1px 3px rgba(0, 0, 0, 0.3);
}

/* 向きの扇。丸と同じ入れ物の中で回す（外側で回すと、地図の拡大を
   打ち消す変換と噛み合わずに位置がずれる）。
   向きには**地図の回転を足す**。入れ物は地図の回転を打ち消してあるので、
   この中では上＝画面の上。--user-heading は真北基準なので、地図が回って
   いればそのぶんずらす（--map-rotation を足す）。 */
.my-location__fan {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 3rem;
  height: 3rem;
  /* base.css の svg { max-width: 100% } が丸の幅(1rem)に押し縮め、扇が丸の下に隠れて見えなかった（2026-10-19） */
  max-width: none;
  /* 方位（北基準）に地図の回転を足して画面基準にする。どちらの変数も JS が .my-location に直接書く（js/map/map-controls.js の updateRotation の注） */
  transform:
    translate(-50%, -50%)
    rotate(calc(var(--user-heading) + var(--map-rotation, 0deg)));
}

/* ============================================================
   地図の上のボタン
   ------------------------------------------------------------
   文字のボタンを縦に4つ並べると、スマホでは地図の右側を常に
   塞いでしまう（模擬店が密集しているのは画像の中央付近なので、
   ちょうど見たい所に重なる）。丸いアイコンにして幅を詰める。
   ============================================================ */

.map-controls {
  pointer-events: none;
  position: absolute;
  inset-inline: 0;
  /* 地図の上のもの（帯 5・札 25・選んだピン 40）より上、シート（--z-sheet）より下。
     無いと札やトイレの絵がボタンに乗って押せなかった（2026-10-21 に指摘）。検索の帯は --z-overlay */
  z-index: var(--map-z-sticky);
  /* 検索の帯（.map-search。高さ 2.75rem + 上の余白）の下から */
  top: calc(2.75rem + var(--sp-3));
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  padding: var(--sp-3);
}

.map-controls__group {
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

/* 押せる大きさ(44px)は必ず確保する
   ── 学祭では歩きながら片手で操作されるため。 */
.control-button {
  display: flex;
  width: 2.75rem;
  height: 2.75rem;
  touch-action: manipulation; /* 素早く 2 回押してもブラウザがページを拡大しない */
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: color-mix(in srgb, var(--c-paper) 95%, transparent);
  color: var(--c-ink-soft);
  box-shadow: var(--map-shadow-raise);
  transition: background-color 0.15s, color 0.15s;
}

@media (hover: hover) and (pointer: fine) {
  .control-button:hover {
    background: var(--c-sakura-deep);
  }
}

/* display: flex がブラウザ既定の [hidden] に勝ってしまうので、明示する（方位針は回したときだけ出す） */
.control-button[hidden] {
  display: none;
}

.control-button[aria-pressed="true"] {
  background: var(--c-rose-deep);
  color: var(--c-paper);
}

.control-button svg {
  width: 1.25rem;
  height: 1.25rem;
}

/* 方位針。地図の回転（js/map/map-controls.js の updateRotation が方位針のボタンに --map-rotation を書く）と同じだけ回す。
   絵は「上が北」で描いてあるので、地図と同じ角度を掛ければ常に北を指す。
   transition は付けない ── 指の動きに毎フレーム追従するので、遅れて追いかけると針が泳ぐ。 */
.compass__needle {
  transform: rotate(var(--map-rotation, 0deg));
}

/* 「戻る」は PC もスマホと同じ検索の帯の左端（.map-search__back）。2026-10-21〜11-08 は PC だけ
   右上の列に出していた（左のパネルを畳む「<」と並んで紛らわしい、という理由）。今の「‹」はパネルの右端の
   真ん中にあって並ばないので、スマホと同じ左上に揃えた（2026-11-08） */
@media (min-width: 1024px) {
  .map-controls {
    left: 22rem;
    top: 0; /* PC では検索の帯は左のパネルの上端にあるので、右上はそのまま */
  }
}

/* ============================================================
   検索の帯（地図の上部に常に出す。js/map/search-bar.js）
   ------------------------------------------------------------
   [戻る] [検索欄 … (絞り込み)] を1行に置く。「絞り込み」の札は検索欄の中の右端
   （MAP検索の検索欄と同じ形。search-bar.js の冒頭の注）。検索中は下に「検索する」と
   最近の検索を垂らす。2026-10-19 までは検索欄はシートの中にあった
   （シートの中だとスマホでキーボードとぶつかる。shop-sheet.js の冒頭の注）。
   PC では左のパネルの上端に重なる（パネル側が頭を空けている）。
   ============================================================ */
.map-search {
  pointer-events: none; /* 帯の余白の下の地図は触れるように。中身だけ受ける */
  position: absolute;
  inset-inline: 0;
  top: 0;
  z-index: var(--map-z-overlay); /* シートより上。検索中の垂らしがシートに隠れないように */
  padding: var(--sp-3);
}

.map-search__row {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

/* 丸いボタン（戻る）。地図の上のボタン（.control-button）と同じ見た目 */
.map-search__back {
  position: relative;
  display: flex;
  width: 2.75rem;
  height: 2.75rem;
  touch-action: manipulation; /* 素早く 2 回押してもブラウザがページを拡大しない */
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: color-mix(in srgb, var(--c-paper) 95%, transparent);
  color: var(--c-ink-soft);
  box-shadow: var(--map-shadow-raise);
  transition: background-color 0.15s, color 0.15s;
}

/* ★ hover の色替えは、カーソルのある端末だけ。スマホでは押した要素に :hover が残り、
   別の所を押すまで色が戻らない（「押したときに色が変わらず、ほかを押したら変わる」
   2026-10-19 に指摘） */
@media (hover: hover) and (pointer: fine) {
  .map-search__back:hover {
    background: var(--c-sakura-deep);
  }

  .search-field__filter:not(.is-active):hover {
    background: var(--c-sakura-deep);
  }
}

/* 表示の切り替えは hidden 属性で行う（入力欄を差し替えないため）。
   display を持つ要素（flex のボタンや件数）にも必ず効くようにする */
.map-search [hidden] {
  display: none !important;
}

.map-search__back-icon {
  width: 1.25rem;
  height: 1.25rem;
}

/* 検索欄。丸い枠の中に [入力欄の箱] [絞り込みの札] を横に並べる（search-bar.js の注）。
   丸いボタンと同じ浮いた見た目にする。影に加えて薄い枠線も付ける
   （地図の余白が白いので、影だけだと欄の形が分からない。2026-10-19 に指摘） */
.map-search__field {
  display: flex;
  min-width: 0;
  flex: 1;
  height: 2.75rem;
  align-items: center;
  border-radius: 999px;
  border: 1px solid var(--c-rose-pale);
  background: var(--c-paper);
  padding-right: 0.375rem;
  box-shadow: var(--map-shadow-raise);
}

/* 入力欄に触れている間は枠を濃くする（枠は箱に付いているので :focus-within で見る） */
.map-search__field:focus-within {
  border-color: var(--c-ink-soft);
}

.search-field__box {
  position: relative;
  min-width: 0;
  flex: 1;
}

/* 入力欄・虫めがね・✕ の見た目は css/map-legacy/search.css（.search-field__*） */

/* 「絞り込み」の札。検索欄の中の右端。条件が効いている間・開いている間は濃い茶に白文字で件数を添える
   （橙は使わない。検索まわりの橙がうるさい、という指摘。2026-10-19。橙は地図の結果と投票ボタンだけ） */
.search-field__filter {
  display: flex;
  height: 2rem;
  flex-shrink: 0;
  touch-action: manipulation; /* 素早く 2 回押してもブラウザがページを拡大しない */
  align-items: center;
  gap: 0.25rem;
  border-radius: 999px;
  background: var(--c-sakura);
  padding: 0 0.5rem 0 0.375rem;
  font-size: 0.8125rem;
  font-weight: 500; /* Kiwi Maru は 400・500 しか読んでいないので 700 は合成の太字になって潰れる（2026-10-31） */
  white-space: nowrap;
  color: var(--c-ink);
  transition: background-color 0.15s, color 0.15s;
}

.search-field__filter.is-active {
  background: var(--c-ink-soft);
  color: #fff;
}

.search-field__filter-icon {
  width: 1rem;
  height: 1rem;
}

.search-field__filter-count {
  font-variant-numeric: tabular-nums;
}

.search-field__clear-icon {
  width: 1rem;
  height: 1rem;
}

/* 検索中に帯の下へ垂らす箱。長い履歴は中で繰る */
.map-search__panel {
  pointer-events: auto;
  margin-top: var(--sp-2);
  max-height: calc(100dvh - 8rem);
  overflow-y: auto;
  border-radius: var(--map-radius-md);
  border: 1px solid var(--map-line);
  background: var(--c-paper);
  padding: var(--sp-2);
  box-shadow: var(--map-shadow-card);
}

.map-search__panel[hidden] {
  display: none;
}

.map-search__go {
  display: flex;
  height: 2.5rem;
  width: 100%;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  border: 1px solid var(--c-rose-pale);
  background: var(--c-paper);
  font-size: var(--map-fs-sm);
  font-weight: 500; /* 帯の「絞り込み」と同じ太さ（2026-10-31） */
  color: var(--c-ink);
}

@media (hover: hover) and (pointer: fine) {
  .map-search__go:hover {
    background: var(--c-sakura-deep);
  }
}

.map-search__hint {
  padding: var(--sp-4) var(--sp-2);
  text-align: center;
  font-size: var(--map-fs-sm);
  color: var(--map-ink-faint);
}

.map-search__history-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-3) var(--sp-2) var(--sp-1);
}

.map-search__history-title {
  font-size: var(--fs-xs);
  letter-spacing: 0.16em;
  color: var(--c-ink-soft);
}

.map-search__history-clear {
  font-size: var(--map-fs-sm);
  color: var(--c-ink-soft);
  text-decoration: underline;
  text-underline-offset: 4px;
}

@media (hover: hover) and (pointer: fine) {
  .map-search__history-clear:hover {
    color: var(--c-ink);
  }
}

/* 1 行 = 語（押すとその語で検索）＋ 右端の ✕（その語だけ履歴から消す。2026-11-11） */
.map-search__history li {
  display: flex;
  align-items: center;
}

.map-search__history-remove {
  display: grid;
  width: 2.75rem;
  height: 2.75rem;
  flex-shrink: 0;
  place-items: center;
  border-radius: 50%;
  color: var(--c-ink-soft);
}

.map-search__history-item {
  display: flex;
  min-height: 2.75rem;
  min-width: 0;
  flex: 1;
  align-items: center;
  gap: 0.625rem;
  border-radius: var(--map-radius-md);
  padding: 0 var(--sp-2);
  text-align: left;
}

@media (hover: hover) and (pointer: fine) {
  .map-search__history-item:hover,
  .map-search__history-remove:hover {
    background: var(--c-sakura-deep);
  }
}

.map-search__history-icon {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  color: var(--map-ink-faint);
}

/* PC では左のパネル（幅 22rem）の上端に重ねる */
@media (min-width: 1024px) {
  .map-search {
    inset-inline: auto;
    left: 0;
    width: 22rem;
    padding: var(--sp-4) var(--sp-3) 0;
  }
}

/* ============================================================
   ボトムシート
   ------------------------------------------------------------
   PC では左側の常設パネル、スマホでは下から出るシートになる。
   検索欄はここには無く、地図の上部の帯（上の「検索の帯」）に常に出す（2026-10-19〜）。
   ============================================================ */

.sheet {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  z-index: var(--map-z-sheet);
  display: flex;
  flex-direction: column;
  border-radius: var(--map-radius-lg) var(--map-radius-lg) 0 0;
  border-top: 3px solid var(--c-rose);
  background: var(--c-paper);
  box-shadow: var(--map-shadow-float);
  /* 高さは JS が段(SNAP_HEIGHT)から入れる。
     ★ 高さに transition を掛けないこと。段が変わるときの動きは JS が transform で付ける
     （shop-sheet.js の applyHeight。高さを動かすと中の一覧の配置計算が毎フレーム走って重い）。 */
  will-change: transform;
}

/* 閉じる動きの間、シートは上にずらした状態から下りてくるので、その下に地図が一瞬見える。
   同じ色の板をシートの下に続けて置いて隠す。 */
.sheet::after {
  content: "";
  pointer-events: none;
  position: absolute;
  top: 100%;
  inset-inline: 0;
  height: 100vh;
  background: var(--c-paper);
}

/* 表示の切り替えは hidden 属性で行う（要素を差し替えると、検索欄の
   フォーカスが外れる）。display を持つ要素にも必ず効くようにする。 */
.sheet [hidden] {
  display: none !important;
}

/* つまみ。押すだけでも開閉できる（画面下端のスワイプはブラウザの
   操作と重なって掴みにくい）。指で操作する所なので touch-action を
   必ず指定する。縦横とも自分で受けるので none。 */
.sheet__handle {
  display: block;
  width: 100%;
  flex-shrink: 0;
  padding: var(--sp-3) var(--sp-4) var(--sp-2);
  cursor: grab;
  touch-action: none;
}

.sheet__grip {
  display: block;
  margin: 0 auto;
  width: 3rem;
  height: 0.375rem;
  border-radius: 999px;
  background: var(--c-rose-pale);
}

/* 検索欄まわりの帯。ここも払えば開閉する（押しただけなら地の部分でだけ）。
   縦の払いはこちらで受け取る(pan-x)。横は残す（検索欄の文字を選べるように）。 */
.sheet__head {
  flex-shrink: 0;
  padding: 0 var(--sp-3) var(--sp-2);
  touch-action: pan-x;
}

/* 高さは「絞り込みを解除」の札（2rem）に合わせて固定する。札が出たり消えたりするたびに
   行の高さが変わると、下の一覧がガタッとずれる（2026-10-19 に指摘） */
.sheet__count-row {
  margin-top: 0;
  display: flex;
  min-height: 2rem;
  align-items: center;
  gap: var(--sp-2);
}

.sheet__count {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font-size: var(--map-fs-sm);
  color: var(--c-ink-soft);
}

/* 条件を外して全件に戻す（「絞り込みを解除」）。畳んだ状態(peek)でも見える所に置く。
   枠線だけだと地に沈んで押せる物に見えなかったので、薄く塗る（2026-10-18 に指摘） */
.sheet__show-all {
  display: flex;
  height: 2rem;
  flex-shrink: 0;
  align-items: center;
  gap: 0.375rem;
  border-radius: 999px;
  border: 1px solid var(--c-rose-pale);
  background: var(--c-sakura);
  padding: 0 0.75rem 0 0.5rem;
  font-size: var(--map-fs-sm);
  font-weight: 500;
  white-space: nowrap;
  color: var(--c-rose-deep);
}

.sheet__show-all-icon {
  width: 1.125rem;
  height: 1.125rem;
  flex-shrink: 0;
}
/* 「一覧へ戻る」。詳細を開いている間だけ、検索欄と同じ場所に出す。
   本文ではなく上端に固定するのは、読み進めると本文ごと流れて
   消えてしまうため。右には今見ている店の場所を添える。 */
.sheet__back-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

/* 灰色の枠に文字の「‹」では戻るボタンに見えなかった（2026-10-18 に指摘）。
   矢印の絵柄を付け、橙の太字で「押せば一覧に戻る」と分かるようにする */
.sheet__back {
  display: flex;
  height: 2.75rem;
  flex-shrink: 0;
  align-items: center;
  gap: 0.375rem;
  border-radius: 999px;
  border: 1px solid var(--c-rose-pale);
  background: var(--c-sakura);
  padding: 0 var(--sp-4) 0 var(--sp-3);
  font-size: var(--map-fs-sm);
  font-weight: 500;
  color: var(--c-rose-deep);
  transition: background-color 0.15s, border-color 0.15s;
}

/* 休止時の地が桜色なので、地を一段濃くするだけでは弱い。縁もローズに */
@media (hover: hover) and (pointer: fine) {
  .sheet__back:hover {
    border-color: var(--c-rose-deep);
    background: var(--c-sakura-deep);
  }
}

.sheet__back-icon {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
}

.sheet__back-place {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: right;
  font-size: var(--map-fs-sm);
  color: var(--map-ink-faint);
}

/* 一覧と詳細を入れる箱。**同じ箱**なのでスクロール位置が残る
   ── 切り替えたら明示的に戻すこと（js 側で行う）。
   縦のスクロールは sheet-snap が touchmove で見ているので、
   ここで touch-action を切らない（切ると一覧が読めなくなる）。 */
.sheet__body {
  min-height: 0;
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 var(--sp-3) var(--sp-4);
}

/* --- 一覧 ---
   1件＝1枚のカード。左に広報用画像の正方形、右に 店名（2行まで）・品目・場所。
   MAP検索の一覧カード（search/map/map.css の .project-list-item）と同じ並びで、色はこの画面のもの。
   2026-10-19 までは枠の無い文字の行（店名と「品目・場所」の2行）で、区切りが分かりにくかった。 */
.sheet-list {
  display: flex;
  flex-direction: column;
  border-top: var(--rule);
}

/* 1 件 = 1 行。冊子・他のページの商店カードと同じく、箱で囲まずに罫線で区切る（2026-10-31。
   それまではコンテストのクリーム色のカードに影） */
.sheet-item {
  display: flex;
  width: 100%;
  align-items: flex-start;   /* 写真と店名の上端をそろえる（検索の店カードと同じ。店名が折り返して行の高さが変わるため。2026-11-13） */
  gap: var(--sp-3);
  border-bottom: var(--rule-dash);
  background: var(--c-paper);
  padding: var(--sp-3) var(--sp-1);
  text-align: left;
  /*
   * 画面に入っていない項目は配置計算を省く（シートの操作が重い、という指摘への対応。2026-10-19）。
   * 高さの見込み（contain-intrinsic-size）は1件ぶん（画像 4rem + 上下の余白 0.75rem×2 + 罫 = 89px）。
   */
  content-visibility: auto;
  contain-intrinsic-size: auto 89px;
}

.sheet-list > li:last-child .sheet-item {
  border-bottom: var(--rule);
}

.sheet-item:active {
  background: var(--map-press);
}

@media (hover: hover) and (pointer: fine) {
  .sheet-item:hover {
    background: var(--c-sakura-deep);
  }
}

.sheet-item:focus-visible {
  outline: 2px solid var(--c-rose-deep);
  outline-offset: -2px;
}

/* 広報用画像の正方形（shop-sheet.js の thumbEl）。正方形の絵なので cover でも切れない */
.sheet-thumb {
  display: block;
  flex-shrink: 0;
  overflow: hidden;
  border-radius: 0; /* 角は立てる（店のカード・店ページの写真と同じ。2026-11-08） */
  background: var(--c-sakura);
}

.sheet-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.sheet-thumb--list {
  width: 4rem;
  height: 4rem;
}

.sheet-item__body {
  display: flex;
  min-width: 0;
  flex: 1;
  flex-direction: column;
  gap: 0.0625rem;
}

/* 店名は折り返す（検索の店カードの .shop-card__name と同じ。2026-11-13 ユーザー: 中身は検索のカードとそろえる）。
   2026-10-21 からは 1 行で「…」にしていた（行の高さをそろえるため）が、検索のカードやトップのコマは切らずに折り返していて、
   同じ店名がページによって切れたり切れなかったりしていた */
.sheet-item__name {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: keep-all;
  overflow-wrap: anywhere;
  font-family: var(--font-main);
  font-size: var(--map-fs-base);
  font-weight: 500;
  line-height: 1.5;
  color: var(--c-ink);
}

/* 営業状態・何の店か・徒歩の行は components.css の .shop-card__now / __kind / __distance をそのまま使う
   （js/map/sheet-content.js）。行の形（.sheet-item）の中に入っていても block で積む */
.sheet-item__body .shop-card__now,
.sheet-item__body .shop-card__kind,
.sheet-item__body .shop-card__distance {
  display: block;
}
.sheet-item__body .shop-card__now {
  display: flex;
  font-size: var(--fs-xs);   /* 前の地図の一覧と同じ大きさ。検索のカード（--fs-sm）のままだと、PC の左のパネル（22rem）や
                                375px で「営業時間外・／本日11:00から」が 2 行に割れ、1 画面に見える店が減った（2026-11-13） */
}

.sheet-empty {
  padding: var(--sp-6) var(--sp-2);
  text-align: center;
  font-size: var(--map-fs-sm);
  color: var(--c-ink-soft);
}

/* --- 絞り込みのパネル（js/map/filter-panel.js） ---
   画面を覆って出す。スマホは画面いっぱいのシート（MAP検索の #genre-panel と同じ）、
   PC は検索の帯の下に垂らす箱（下の @media）。外側の暗い地を押すと閉じる。
   2026-10-19 までは一覧のシートの中身を入れ替えて出していた。 */
.filter-dialog {
  position: absolute;
  inset: 0;
  z-index: var(--map-z-modal);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(90, 60, 58, 0.42);
}

.filter-dialog[hidden] {
  display: none;
}

.filter-dialog__sheet {
  display: flex;
  width: 100%;
  height: 100%;
  flex-direction: column;
  overflow: hidden;
  background: var(--c-paper);
}

.filter-dialog__head {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--map-line);
  padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-4);
}

.filter-dialog__title {
  font-family: var(--font-main);
  font-size: var(--map-fs-base);
  font-weight: 500; /* 700 は Kiwi Maru の合成の太字（2026-10-31） */
}

.filter-dialog__close {
  display: flex;
  width: 2.75rem;
  height: 2.75rem;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  color: var(--c-ink-soft);
}

.filter-dialog__close-icon {
  width: 1.25rem;
  height: 1.25rem;
}

.filter-dialog__body {
  display: flex;
  min-height: 0;
  flex: 1;
  flex-direction: column;
  padding: var(--sp-3) var(--sp-4) calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
}

.filter-panel {
  display: flex;
  min-height: 0;
  flex: 1;
  flex-direction: column;
}

.filter-panel__scroll {
  min-height: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 var(--sp-1) var(--sp-3);
}

@media (min-width: 1024px) {
  /* PC は検索の帯の下に垂らす箱。帯は左のパネルの上端に重なっている（.sheet__head の padding-top） */
  .filter-dialog {
    align-items: flex-start;
    justify-content: flex-start;
  }

  /* 横幅はたっぷり取る。品目 13 個が 2 行に収まり、場所・部門・並び替えを合わせても
     ふつうの画面の高さに入るので、PC では繰らずに全部見える（「PC で絞り込みをスクロール
     させる意味は無い」2026-10-19 に指摘）。max-height は低い画面の保険 */
  .filter-dialog__sheet {
    width: min(46rem, calc(100vw - var(--sp-3) * 2));
    height: auto;
    max-height: calc(100dvh - 2.75rem - var(--sp-3) * 4);
    margin: calc(2.75rem + var(--sp-3) * 2) 0 0 var(--sp-3);
    border-radius: var(--map-radius-xl);
    box-shadow: var(--map-shadow-float);
  }

  /* 品目は1行目いっぱい、場所・部門・並び替えは横に並べて高さを詰める（低い画面でも繰らずに済むように） */
  .filter-dialog .filter-panel__scroll {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--sp-4) var(--sp-6);
  }

  .filter-dialog .filter-group {
    flex: 0 1 auto;
  }

  .filter-dialog .filter-group:first-child {
    flex-basis: 100%;
  }
}

.filter-group__head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
}

.filter-group__note {
  font-size: var(--fs-xs);
  color: var(--map-ink-faint);
}

/* 絞り込みのパネルではチップを一段低くする（スマホで品目13個を4行に収めるため）。検索ページは 44px のまま。 */
.filter-dialog .chip {
  height: 2.5rem;
}

.filter-panel__foot {
  display: flex;
  flex-shrink: 0;
  gap: var(--sp-2);
  border-top: 1px solid var(--map-line);
  padding-top: var(--sp-3);
}

.filter-panel__clear {
  display: flex;
  height: 2.75rem;
  align-items: center;
  border-radius: 999px;
  border: 1px solid var(--c-rose-pale);
  padding: 0 var(--sp-4);
  font-size: var(--map-fs-sm);
}

.filter-panel__done {
  display: flex;
  height: 2.75rem;
  flex: 1;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--c-rose-deep);
  font-size: var(--map-fs-sm);
  color: var(--c-paper);
}

/* 絞り込みの下の 2 つのボタンのホバー（css/tokens.css の決まり: 白いボタンは地を敷く、塗りのボタンは反転） */
@media (hover: hover) and (pointer: fine) {
  .filter-panel__clear:hover {
    background: var(--c-sakura-deep);
  }

  .filter-panel__done:hover {
    background: var(--c-paper);
    color: var(--c-rose-deep);
    box-shadow: inset 0 0 0 1px var(--c-rose-deep);
  }
}

.filter-panel__done-label {
  margin-left: var(--sp-1);
}

/* --- 店の詳細（シートの中。並びと中身は shop.php と同じ。js/map/sheet-content.js の detailEl） ---
   見た目の細かい所は css/map-legacy/map-page.css、券・紹介文・表は css/components.css */
.sheet-detail {
  padding: 0 var(--sp-1) var(--sp-4);
}

.sheet-detail__name {
  font-family: var(--font-main);
  font-size: var(--map-fs-lg);
  font-weight: 500;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* 現在地からの距離（現在地が分かるときだけ出る。600m 以内なら徒歩◯分も） */
.sheet-detail__walk {
  color: var(--c-rose-deep);
}

/* 店の詳細を読んでいる間、「Googleマップで行き方を見る」をシートの下に固定する（本文の下まで送らなくても押せる）。
   模擬店コンテストでは投票ボタンの場所だった。 */
.sheet__foot {
  flex-shrink: 0;
  border-top: var(--rule);
  padding: var(--sp-3);
}

.sheet__foot-link {
  display: flex;
  height: 2.75rem;
  width: 100%;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--c-rose-deep);
  padding: 0 var(--sp-4);
  font-size: var(--map-fs-base);
  color: var(--c-paper);
  transition: background-color 0.15s, color 0.15s;
}

@media (hover: hover) and (pointer: fine) {
  /* 塗りのボタンは反転（css/tokens.css の決まり） */
  .sheet__foot-link:hover {
    background: var(--c-paper);
    color: var(--c-rose-deep);
    box-shadow: inset 0 0 0 1px var(--c-rose-deep);
  }

  .sheet-toggle:hover {
    background: var(--c-sakura-deep);
    color: var(--c-ink);
  }
}

/* PC では左に寄せた常設パネルにする */
@media (min-width: 1024px) {
  .sheet {
    inset-inline: auto;
    left: 0;
    top: 0;
    bottom: 0;
    width: 22rem;
    height: auto !important;
    border-radius: 0;
    border-top: 0;
    border-right: 1px solid var(--map-line);
    transition: width 0.3s cubic-bezier(0, 0, 0.2, 1);
  }

  /* 畳んだときは幅0。**開き直すボタンはこの中に置かないこと**
     ── 一緒に切り取られて二度と開けなくなる（PORTING.md 5-6）。 */
  .sheet.is-collapsed {
    width: 0;
    overflow: hidden;
    border-right: 0;
  }

  .sheet__handle {
    display: none;
  }

  /* 上端には検索の帯（.map-search）が重なるので、そのぶん空ける */
  .sheet__head {
    padding-top: calc(var(--sp-4) + 2.75rem + var(--sp-3));
  }

  /* 畳む／開くボタンはパネルの**外**、右端の縦中央に置く */
  .sheet-toggle {
    position: absolute;
    top: 50%;
    left: 22rem;
    z-index: var(--map-z-sheet);
    display: flex;
    width: 1.5rem;
    height: 3.5rem;
    transform: translateY(-50%);
    align-items: center;
    justify-content: center;
    border-radius: 0 var(--map-radius-md) var(--map-radius-md) 0;
    border-width: 1px 1px 1px 0;
    border-style: solid;
    border-color: var(--map-line);
    background: var(--c-paper);
    color: var(--c-ink-soft);
    box-shadow: var(--map-shadow-raise);
    transition: left 0.3s cubic-bezier(0, 0, 0.2, 1);
  }

  .sheet-toggle.is-collapsed {
    left: 0;
  }
}

@media (max-width: 1023px) {
  .sheet-toggle {
    display: none;
  }
}
