/* くまもと防災ポケット — 大きな文字・高コントラスト・軽量 */
:root {
  --red: #b91c1c;
  --red-dark: #7f1d1d;
  --ink: #1c1917;
  --paper: #fffdf7;
  --card: #ffffff;
  --line: #d6d3d1;
  --green: #15803d;
  --blue: #1d4ed8;
  --orange: #c2410c;
  --fs-base: 20px;
  --fs-big: 26px;
  --fs-huge: 34px;
}
html.font-xl {
  --fs-base: 24px;
  --fs-big: 31px;
  --fs-huge: 40px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { font-size: var(--fs-base); }
body {
  /* UDフォント(BIZ UDPGothic)を最優先。Windowsで確実に適用され、iOS/AndroidはOS標準の高可読フォントへ */
  font-family: "BIZ UDPGothic", "Hiragino Sans", "Yu Gothic UI", "Meiryo", sans-serif;
  background: var(--paper);
  color: var(--ink);
  line-height: 1.55;
  -webkit-text-size-adjust: 100%;
  /* 日本語の改行位置。指定が無いと1文字単位で折り返され、
     「ト|イレ」「エコノミー|クラス」のように語の途中で切れる
     (利用者から「単語の途中でぶつ切りだと視覚的に見にくい」と指摘があった)。

     strict … 禁則処理。小書きのかな(ョ ォ っ 等)・長音符・句読点を行頭に置かない。
              既定の auto では「ステーシ|ォーム」のような行頭が実際に出ていた。
              Chrome / Safari / Firefox いずれも対応。全体にかけてよい。

     overflow-wrap は指定しない。指定すると URL のような切れ目の無い長い文字列を
     途中で割れるようになる代わりに、日本語まで巻き込んで元の症状へ戻る。 */
  line-break: strict;
}

/* 文節の切れ目で折り返す(カタカナ語が途中で切れなくなる)。
   Chrome 119+ / Edge のみ。非対応の環境(iOS Safari 等)ではこの1行が
   無視されるだけで、body の line-break: strict の効果は残る。

   **本文(main)だけに限定している。** 文節折り返しは行の詰まり方が緩くなるぶん
   行数が増える。地震バナーは高さの上限(40vh)が緊急電話ボタンとの兼ね合いで
   決まっているため、1行増えると全文が入りきらずスクロールに逃げる
   =「震度と場所が隠れる」ことになる。狭い帯より本文の読みやすさを取る。 */
main { word-break: auto-phrase; }

/* safe-area(ノッチ・パンチホール・下端のバー)の扱い方はこのファイル全体で同じ型にする:
     1. env(safe-area-inset-*) は**必ずカスタムプロパティに受ける**
        (変数 → padding の配線を test/layout-browser.mjs が値を差し替えて実測できる。
         padding に env() を直書きすると、配線が切れても headless では
         インセットが常に0なので誰も気づけない)
     2. env() には必ず 0px のフォールバックを書く。
        フォールバック無しの env() は未対応の環境で padding ごと無効になる
     3. 画面の端に固定する要素は**左右も**受ける。iPhoneを横向きにすると
        ノッチ側の左右に最大44pxのインセットが入り、そこに文字やボタンが隠れる

   headless Chrome ではインセットが常に0なので、ここでの見た目は変わらない。
   実機(iOS PWA)の縦横・ノッチ・ホームインジケータでの見え方は未確認。 */
.app-header {
  background: var(--red);
  color: #fff;
  --header-safe-top: env(safe-area-inset-top, 0px);
  --header-safe-right: env(safe-area-inset-right, 0px);
  --header-safe-left: env(safe-area-inset-left, 0px);
  /* 上端に貼り付く帯。横向きではタイトルと「更新/文字大」がノッチに食われる */
  padding:
    calc(var(--header-safe-top) + 12px)
    calc(var(--header-safe-right) + 16px)
    12px
    calc(var(--header-safe-left) + 16px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.app-header h1 { font-size: var(--fs-big); letter-spacing: 0.02em; }
/* 状態の文字が長くなると(「接続できません」など)、320px+文字特大では
   更新・文字大のボタンが押しつぶされて1文字ずつ縦に並ぶ。
   折り返しを許し、ボタンの中の文字は必ず横一列に保つ */
.header-status { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 10px; }
.font-toggle { white-space: nowrap; }
#net-status { font-size: 0.75rem; padding: 4px 10px; border-radius: 999px; background: #14532d; white-space: nowrap; }
@media (max-width: 380px) {
  /* 小さい画面+文字大でヘッダーが1文字ずつ縦に崩れるのを防ぐ */
  .app-header { flex-wrap: wrap; }
  .app-header h1 { flex: 1 1 100%; font-size: 1.15rem; }
}
/* 文字特大では題名(10文字・約310px)が「更新」「文字標準」と同じ行に入らず、
   残った150pxほどに押し込まれて「くまもと防|災ポケット」と割れていた
   (実機の全画面で発生。共有ヘッダーなのでどの画面でも出る)。
   幅を広げるのではなく**行を分ける**。文字は小さくしない —— 題名を縮めると
   高齢の利用者がいちばん最初に読む文字が読みにくくなる */
@media (max-width: 480px) {
  /* 文字サイズによらず題名を独立行にする。
     題名は keep-all で割らない方針(アプリの名前を「くまもと防|災ポケット」と
     割らない)なので、1行に 文字標準260px / 文字特大310px 必要になる。
     ボタン(更新・文字大)と同じ行に置くと 390px でも4pxはみ出し、
     ページ全体が横スクロールできる状態になっていた(実測)。
     文字を小さくして詰めるのではなく、行を分ける */
  .app-header { flex-wrap: wrap; }
  .app-header h1 { flex: 1 1 100%; }
}
#net-status.net-ng { background: #78350f; }
.font-toggle {
  font-size: 0.8rem;
  min-height: 44px;
  padding: 8px 12px;
  border: 2px solid #fff;
  border-radius: 10px;
  background: transparent;
  color: #fff;
  cursor: pointer;
}

/* 緊急地震速報 全画面警報

   320x480・文字特大では、中身(タイトル+震源+行動+注記+ボタン)が画面より高くなる。
   以前は justify-content: center のまま overflow の指定が無かったため、
   はみ出した分が**上下の両方**へ出ていた。実測(320x480/文字24px):
     overlay clientHeight 480 / scrollHeight 552 / overflow-y: visible
     タイトル top: -72     → 画面の上へ出て読めない
     とじる  bottom: 552   → 画面の下へ出て押せない(実クリックが当たらない)
   上へ出た分はスクロールでも戻れない(スクロール量は負にならない)。
   **緊急地震速報が出た瞬間に全画面が閉じられなくなり、119にも避難所にも
   到達できなくなっていた**(監査P0-6)。

   直し方:
   - overflow-y: auto。入りきらない分はスクロールして最後まで届かせる
   - justify-content は flex-start(上寄せ)。中央寄せのままだと、
     はみ出した分の半分が「戻れない上方向」へ消える
   - 余裕があるときだけ、最初と最後の要素の auto マージンで中央へ寄せる。
     余裕が無ければ auto は 0 になるので、上へはみ出さない
   - flex-shrink を止める。縮めて収めると文字が潰れる = 隠して解決になる
   - safe-area を4方向とも内側の余白に足す(ノッチや下端のバーにボタンが隠れないように)。
     env() は変数に受けておく。test/layout-browser.mjs が
       (a) 各変数が対応する env(safe-area-inset-*) を参照していること(CSSOMで読む)
       (b) その変数に値を入れると本当に padding が動くこと(差し替えて実測)
     の**両方**を見る。片方だけだと、値を直接差し替える試験は
     env() を消しても通ってしまう(監査 指摘7)。 */
.eew-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--red-dark);
  color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* 上寄せ。中央寄せは下の auto マージンで「余裕があるときだけ」効かせる */
  justify-content: flex-start;
  text-align: center;
  --eew-safe-top: env(safe-area-inset-top, 0px);
  --eew-safe-right: env(safe-area-inset-right, 0px);
  --eew-safe-bottom: env(safe-area-inset-bottom, 0px);
  --eew-safe-left: env(safe-area-inset-left, 0px);
  padding:
    calc(var(--eew-safe-top) + 16px)
    calc(var(--eew-safe-right) + 16px)
    calc(var(--eew-safe-bottom) + 16px)
    calc(var(--eew-safe-left) + 16px);
  gap: 14px;
  overflow-y: auto;
  overflow-x: hidden;
  /* 警報の中でスクロールしたとき、背後の本文まで一緒に動かさない */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
/* 縮めて収めない。縮むと文字が潰れて読めなくなる(隠して解決しない)。
   入りきらない分はスクロールで届かせる */
.eew-overlay > * { flex: 0 0 auto; max-width: 100%; }
/* 画面に余裕があるときだけ中央へ寄せる。
   余裕が無ければ auto マージンは 0 になり、タイトルが上へ消えない */
.eew-overlay > :first-child { margin-top: auto; }
.eew-overlay > :last-child { margin-bottom: auto; }
.eew-overlay.hidden { display: none; }
.eew-title {
  font-size: var(--fs-huge);
  font-weight: 900;
  background: #fff;
  color: var(--red-dark);
  padding: 8px 22px;
  border-radius: 14px;
}
.eew-body { font-size: var(--fs-big); font-weight: 800; line-height: 1.5; }
.eew-advice { font-size: 1.1rem; font-weight: 800; background: rgba(255,255,255,0.15); border-radius: 12px; padding: 12px 16px; }
.eew-sub { font-size: 0.75rem; opacity: 0.85; }
.eew-close {
  font-size: 1rem;
  font-weight: 800;
  padding: 14px 34px;
  /* 指で確実に押せる大きさを下限として決めておく(小さい画面でも縮まない) */
  min-height: 48px;
  border-radius: 12px;
  border: 3px solid #fff;
  background: transparent;
  color: #fff;
  cursor: pointer;
}

/* 起動直後や地震発生時に出る帯。画面上部に固定する。
   固定したままだと、その下の 119/110/171 と避難所ボタンを覆ってしまう
   (320px+文字特大では帯が4行になり、緊急電話のボタンに完全に重なる)。
   帯の文字を小さくしたり省略したりして隠すのではなく、実測した帯の高さぶん
   body に余白を作り、重なりを物理的に無くす(高さは app.js が測って
   --quake-banner-h に入れる)。閉じるボタンで消せば余白も消える */
.quake-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 950;
  background: #fef3c7;
  border-bottom: 4px solid var(--orange);
  color: var(--ink);
  /* 画面の上端いっぱいに固定する帯。横向きでは震源名と「✕ 閉じる」が
     ノッチ側に食われるので、左右のインセットも受ける */
  --banner-safe-top: env(safe-area-inset-top, 0px);
  --banner-safe-right: env(safe-area-inset-right, 0px);
  --banner-safe-left: env(safe-area-inset-left, 0px);
  padding:
    calc(var(--banner-safe-top) + 12px)
    calc(var(--banner-safe-right) + 12px)
    12px
    calc(var(--banner-safe-left) + 16px);
  font-size: 0.95rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(0,0,0,0.25);
  display: flex;
  align-items: flex-start;
  gap: 8px;
  /* 縦の短い端末(320x480など)で帯が画面の4割を超えると、下げた本文の
     119/110/171 が画面の外へ出てしまう。高さの上限を決めて押し出しを止める。
     文字は省略しない。あふれた分は帯の中をスクロールすれば最後まで読める */
  max-height: 40vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* 画面の縦が短い端末では4割でも足りない(下げた119が画面の外へ出る)。
   帯の取り分をさらに減らし、緊急電話が必ず見えている状態を優先する */
@media (max-height: 560px) {
  .quake-banner { max-height: 28vh; }
}
/* 下の「保存できていません」の帯と同時に出ているときだけ、上限を app.js が
   実測で決め直す(320x480・文字特大では、上下の帯と171pxのヘッダーで
   119/110/171 の下に29pxしか残らない。バナーに少し譲ってもらって
   下の帯が使える高さを作る)。バナーの文字は消えない —— 譲った分は
   バナーの中をスクロールすれば最後まで読める */
html.offline-warn-open .quake-banner { max-height: var(--quake-banner-max, 40vh); }
@media (max-height: 560px) {
  html.offline-warn-open .quake-banner { max-height: var(--quake-banner-max, 28vh); }
}
.quake-banner-text { flex: 1 1 auto; min-width: 0; }
.quake-banner-close {
  flex: 0 0 auto;
  min-height: 44px;
  min-width: 44px;
  padding: 8px 10px;
  font-size: 0.78rem;
  font-weight: 800;
  line-height: 1.2;
  color: #7c2d12;
  background: #fff;
  border: 2px solid #7c2d12;
  border-radius: 10px;
  cursor: pointer;
}
:root { --quake-banner-h: 0px; }
html.quake-banner-open body { padding-top: var(--quake-banner-h); }

/* 圏外用の保存が欠けているときだけ出す。見落とすと圏外で何も出せない */
/* 起動1.5〜2.5秒後に出るため、通常の流れに置くと画面全体が下へずれ、
   119を押そうとした指が別の場所に当たる。画面下に固定して押し下げないようにする。
   ただし固定しただけだと、今度は帯が 119/110/171 を上から覆う
   (320x480・文字特大では帯の高さが299pxになり、3つのボタンの中心を突くと
   すべて帯に当たっていた —— 電話がかけられない)。地震バナーと同じ型で直す:
     1. 実測した高さを --offline-warn-h に入れ、body の下に同じだけ余白を作る
     2. 高さの上限を決めて、緊急電話の上まで伸びないようにする
   上限は画面の高さの割合(vh)では決められない。119/110/171 の下に残る隙間は
   実測で 35px〜431px まで幅があり(ヘッダーの高さと地震バナーの有無で変わる)、
   35vh のような固定値では狭い端末で必ず重なる。app.js が緊急電話の位置を測って
   --offline-warn-max に入れる(vhの値はそれが使えない環境のための保険)。
   文字は削らない。上限にかかった分は帯の中をスクロールすれば最後まで読める */
.offline-warn {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 900;
  background: #fee2e2;
  border-top: 4px solid var(--red);
  color: var(--ink);
  /* 画面の下端いっぱいに固定する帯。下はホームインジケータ、
     横向きでは左右のノッチに「保存し直す/✕ 閉じる」が食われる */
  --warn-safe-right: env(safe-area-inset-right, 0px);
  --warn-safe-bottom: env(safe-area-inset-bottom, 0px);
  --warn-safe-left: env(safe-area-inset-left, 0px);
  padding:
    12px
    calc(var(--warn-safe-right) + 16px)
    calc(var(--warn-safe-bottom) + 12px)
    calc(var(--warn-safe-left) + 16px);
  font-size: 0.95rem;
  font-weight: 700;
  /* 狭いときの潰れ方を決めておく。1行目(文面)は必ず1行ぶん残り、
     余った高さを文面が使い、それでも入らなければ帯の中でスクロールする。
     単純な折り返し(flex-wrap)だと、上限にかかったときにボタンだけが
     帯の外へ完全に押し出されて押せなくなる */
  display: grid;
  /* 下限を外して等幅にする(理由は .home-grid のコメント) */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: minmax(1.6em, 1fr) auto;
  gap: 8px 10px;
  max-height: var(--offline-warn-max, 35vh);
  overflow-y: auto;
  overscroll-behavior: contain;
  box-shadow: 0 -2px 10px rgba(0,0,0,0.2);
}
/* --offline-warn-max を置けない環境(古い端末)向けの保険。
   縦の短い端末では上の地震バナー(28vh)と合わせて画面を食い尽くすため、
   下の帯の取り分も減らし、緊急電話が見えている状態を優先する */
@media (max-height: 560px) {
  .offline-warn { max-height: var(--offline-warn-max, 30vh); }
}
#offline-warn-text {
  grid-column: 1 / -1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.offline-warn-btn {
  background: var(--red);
  color: #fff;
  border: 0;
  border-radius: 8px;
  /* 320px幅+文字特大でも「保存し直す」が1行に収まる大きさ。
     はみ出すとボタンが2行になり、その分だけ帯が高くなって緊急電話に近づく */
  padding: 8px 10px;
  min-height: 44px;
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
}
/* 「保存し直す」を出さない場面(保存し直している最中)は、閉じるを横いっぱいに */
#offline-warn-retry[hidden] + .offline-warn-close { grid-column: 1 / -1; }
/* 閉じるボタン。地震バナーの「✕ 閉じる」と同じ見た目にして、
   本文の「保存し直す」(赤い実塗り)と取り違えないようにする */
.offline-warn-close {
  background: #fff;
  color: var(--red-dark);
  border: 2px solid var(--red-dark);
}
:root { --offline-warn-h: 0px; }
html.offline-warn-open body { padding-bottom: var(--offline-warn-h); }

main { max-width: 640px; margin: 0 auto; padding: 16px 14px 40px; }
.view.hidden, .hidden { display: none; }

/* ホーム最上部: 命に直結する常時表示 */
.emergency-bar {
  background: #fff1f2;
  border: 3px solid var(--red);
  border-radius: 16px;
  padding: 12px;
  margin-bottom: 14px;
}
/* 119/110/171。ここが親をはみ出すとページ全体が横スクロールになり、
   実機で緊急電話の帯だけ幅が足りないように見える。下限を外して必ず3等分にする */
.emg-calls { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.emg-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 66px;
  border-radius: 12px;
  text-decoration: none;
  color: #fff;
  background: var(--red);
  padding: 6px 2px;
}
.emg-btn strong { font-size: 1.35rem; line-height: 1.1; }
.emg-btn span { font-size: 0.68rem; }
.emg-110 { background: #1d4ed8; }
.emg-171 { background: #6b21a8; }
.emg-shelter {
  width: 100%;
  margin-top: 10px;
  min-height: 52px;
  font-size: 1.02rem;
  font-weight: 800;
  color: #fff;
  background: var(--green);
  border: none;
  border-radius: 12px;
  cursor: pointer;
}
.emg-status { font-size: 0.76rem; color: #44403c; margin-top: 8px; }
.emg-sub {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-top: 8px;
  font-size: 0.72rem;
  color: #57534e;
}
.emg-lang {
  font-size: 0.75rem;
  font-weight: 700;
  padding: 8px 12px;
  min-height: 36px;
  border: 2px solid #4338ca;
  border-radius: 10px;
  background: #fff;
  color: #4338ca;
  cursor: pointer;
}

/* 避難所: 状態バッジ(色だけに頼らず文字でも示す) */
.official-cta {
  display: block;
  background: var(--red);
  color: #fff;
  font-weight: 800;
  text-align: center;
  padding: 14px 12px;
  border-radius: 12px;
  text-decoration: none;
  margin-bottom: 12px;
}
.badge-open, .badge-unknown, .badge-welfare {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 800;
  padding: 3px 8px;
  border-radius: 999px;
  margin-right: 6px;
  vertical-align: middle;
}
.badge-open { background: #14532d; color: #fff; }
.badge-welfare { background: #4338ca; color: #fff; }
.badge-unknown { background: #e7e5e4; color: #44403c; border: 1px solid #a8a29e; }
.open-item { border-left: 8px solid var(--green); }
.warn-item { border-left: 8px solid var(--orange); background: #fff7ed; font-size: 0.9rem; }
.shelter-meta { font-size: 0.76rem; color: #57534e; margin-top: 2px; }

/* ホーム */
.home-lead { font-size: 0.9rem; margin-bottom: 14px; }
/* `1fr` には「中身の最小幅より狭くしない」という下限が自動で付く。
   「開いている避難所 / 県発表+安全な場所の候補」のカードは最小幅190pxを要求するため、
   390px幅の実機で列が 189.375px + 169px の不揃いになり、gap を足すと
   親(362px)を8px超えていた。ページ全体が横スクロールできる状態になり、
   iPhoneではヘッダーと緊急カードだけ幅が足りないように見えていた(実機のスクリーンショットで発覚)。
   minmax(0, 1fr) で下限を外し、2列を必ず等幅にする。
   はみ出した分はカードの中で折り返す(文字は消さない)。 */
/* 【1列/2列の切り替え】
   「開いている避難所」は「・」が無く、途中で割る以外に折り返す場所がありません。
   1行に必要な幅を実測すると 168px(390px・文字標準)、文字特大では約200px。
   一方カードの中で使える幅は 153px(390px)/ 118px(320px)しかなく、
   **2列では物理的に入りません**。keep-all で割らないようにすると列からはみ出し、
   overflow-wrap で逃がすと語の途中で割れる —— どちらかしか選べませんでした
   (実機のスクリーンショットで「開いている避難 / 所」「水・食料・ト / イレ」と判明)。

   auto-fit + minmax(200px, 1fr) にして、**入る幅のときだけ2列**にします。
   iPhoneは1列(ラベルが必ず1行に収まる)、タブレットや横向きでは2列のまま。
   文字特大でも自動的に1列へ落ちます。
   200px の根拠: 文字特大でいちばん長い「開いている避難所」の1行ぶん(約200px)。 */
.home-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; }
.home-btn {
  min-height: 128px;
  border: 3px solid var(--line);
  border-radius: 18px;
  background: var(--card);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 12px 8px;
  text-align: center;
  color: var(--ink);
  box-shadow: 0 2px 6px rgba(0,0,0,0.08);
}
.home-btn:active { transform: scale(0.97); }
.btn-icon { font-size: 2rem; line-height: 1.2; }
.btn-label { font-size: 1.05rem; font-weight: 800; }
.btn-sub { font-size: 0.68rem; color: #57534e; }

/* 短いラベルは語の途中で切らない。
   実機(iPhone)で「トイ|レ」「風|呂」「避難|所」「家|族」「ボ|ランティア」と
   割れていると指摘があった。本文には main の word-break: auto-phrase を効かせているが、
   **auto-phrase は Chrome / Edge だけ**で、iOS Safari では何も起きない。
   短いラベルはもともと「・」で区切られた語の並びなので、CJKの連なりを割らない
   keep-all が使える(Chrome / Safari / Firefox すべて対応)。

   実測(390px / 360px / 320px × 文字標準・特大 の6通り、auto-phraseを無効にして
   Safari相当にしたうえで計測): 語中改行 8〜13件 → **全構成で0件**、はみ出しも0件。

   ただし keep-all だけでは足りない。狭い画面では「割れない代わりにはみ出す」ので、
   下の overflow-wrap: anywhere と必ず対で使う(理由はそちらのコメント)。 */
/* 【対象の決め方】ここは「短いラベル」に当てる規則。
   以前は .btn-label / .btn-sub / .sub-btn … と**個別に列挙**していたが、
   そのやり方では取りこぼす。実際に、ヘッダーの題名・避難所ボタン・
   くらしのタブ・二次メニューを順に見落とし、実機の指摘で1つずつ足していた。

   そこで **test/layout-browser.mjs が「短いラベル」として走査する集合と
   同じセレクタ**を書く。検査する範囲とCSSが効く範囲が一致するので、
   テストが見つけたものは必ずここに含まれる(取りこぼしが構造的に起きない)。
   片方を変えたらもう片方も変えること —— そのことを検査でも固定している。 */
button,
a.emg-btn,
a.emg-wlink,
.btn-label,
.btn-sub,
.sub-btn,
h1, h2, h3,
.emg-status,
.life-tab,
[role="tab"] {
  /* CJKの連なりを割らない。Chrome / Safari / Firefox すべて対応。
     main の word-break: auto-phrase は Chrome / Edge だけなので、
     iOS Safari で効くのはこちらだけ */
  word-break: keep-all;
  /* **overflow-wrap: anywhere はここでは指定しない。**
     一度は「入りきらないときだけ割る逃げ道」として全体に付けたが、
     anywhere は禁則(行頭に来てはいけない文字)まで無視するため、
     実測で「ことがあります|)」「住まい|・お金」のように
     閉じ括弧や中点が行頭に来た。
     グリッドを auto-fit(入る幅のときだけ多列)にしたことで、
     いまは逃げ道が無くてもはみ出さない —— 実測(320px・9画面・文字標準/特大):
       anywhere あり = 語中改行0・はみ出し0・**禁則違反1**
       anywhere なし = 語中改行0・**禁則違反0**・はみ出し1(下の .big-action だけ)
     残る1箇所にだけ個別に付ける(下を参照)。 */
}
/* 【逃げ道を付ける2つだけ】どちらも「・」の無い長い一続きの文言で、
   keep-all のままでは狭い画面に**物理的に入らない**:
     .big-action   「📞 災害用伝言ダイヤル 171 に電話」
     .emg-shelter  「🏠 いま開いている避難所をさがす」(14文字)
       320px・文字特大では 14×25px = 350px 必要で、入れ物は292px。
       実測のはみ出し: 320px標準 +23px / 320px特大 +80px / 390px特大 +10px
   文字を小さくすれば入るが、**この2つは被災者がいちばん最初に押すボタン**なので
   縮めない。割れることを受け入れる。
   全体に anywhere を付けると禁則(行頭の「)」「・」)が壊れるので、
   入らないと実測できたこの2つに限定する。 */
.big-action,
.emg-shelter { overflow-wrap: anywhere; }

.btn-quake { border-color: var(--red); }
.btn-shelter { border-color: var(--green); }
.btn-road { border-color: var(--blue); }
.btn-support { border-color: var(--orange); }
.btn-safety { border-color: #a21caf; }
.btn-life { border-color: #0e7490; }
.btn-lang { border-color: #4338ca; }

/* くらし・手続き */
.life-seg { flex-wrap: wrap; }
.life-seg .seg-btn { flex: 1 1 30%; border-color: #0e7490; color: #0e7490; }
.life-seg .seg-btn.active { background: #0e7490; color: #fff; }
.life-card {
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  padding: 14px;
  margin-bottom: 12px;
}
.life-card h3 { font-size: 1rem; margin-bottom: 6px; }
.life-card p, .life-card li { font-size: 0.9rem; }
.life-card ul, .life-card ol { padding-left: 1.4em; margin: 6px 0; }
.life-card ol li { margin: 6px 0; }
.life-card .lc-desc { font-size: 0.78rem; color: #57534e; }
.life-card a { color: var(--blue); font-weight: 700; }
.life-card.warn { border-color: var(--orange); background: #fff7ed; }
.life-src { font-size: 0.7rem; color: #57534e; margin-top: 6px; }

/* 災害ごみ仮置場の「本日は開いているか」。色だけでなく文字でも示す */
.gomi-state { margin-bottom: 8px; }
.gomi-open, .gomi-closed, .gomi-unknown {
  display: inline-block;
  font-size: 0.88rem;
  font-weight: 800;
  padding: 6px 12px;
  border-radius: 999px;
}
.gomi-open { background: #14532d; color: #fff; }
.gomi-closed { background: #7f1d1d; color: #fff; }
.gomi-unknown { background: #e7e5e4; color: #44403c; border: 1px solid #a8a29e; }

.dial171 { margin-top: 16px; display: flex; flex-direction: column; gap: 10px; }
.dial171-btn {
  display: block;
  background: var(--red);
  color: #fff;
  text-decoration: none;
  text-align: center;
  font-size: 1.1rem;
  font-weight: 800;
  padding: 18px 12px;
  border-radius: 14px;
}
.dial171-btn strong { font-size: 1.4em; }
.dial171-web {
  color: var(--blue);
  font-size: 0.9rem;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* 共通部品 */
.back-btn {
  font-size: 1rem;
  font-weight: 700;
  background: #e7e5e4;
  border: none;
  border-radius: 10px;
  padding: 12px 18px;
  margin-bottom: 14px;
  cursor: pointer;
  color: var(--ink);
}
.back-btn-bottom {
  display: block;
  width: 100%;
  margin-top: 20px;
  margin-bottom: 0;
}
h2 { font-size: var(--fs-big); margin-bottom: 12px; }
.section-lead { font-size: 0.9rem; margin-bottom: 12px; }
.updated-note { font-size: 0.8rem; color: #57534e; margin: 8px 0; }
.note-box {
  margin-top: 18px;
  background: #f5f5f4;
  border-radius: 12px;
  padding: 12px 14px;
  font-size: 0.8rem;
  color: #44403c;
}
.note-box .mid-btn { margin-top: 10px; }
.mid-btn {
  font-size: 0.95rem;
  font-weight: 700;
  padding: 12px 16px;
  border-radius: 12px;
  border: 2px solid var(--ink);
  background: var(--card);
  cursor: pointer;
  color: var(--ink);
}
.big-action {
  width: 100%;
  font-size: 1.1rem;
  font-weight: 800;
  padding: 18px 12px;
  border-radius: 14px;
  border: none;
  background: var(--green);
  color: #fff;
  cursor: pointer;
  margin-bottom: 10px;
}

/* 地震リスト */
/* 「開いている避難所」/「安全な場所の候補」の切り替え。
   文字特大では前者に182px要るのに、2つ横並びだと177pxしか無く
   「開いている避|難所」と割れていた(実測・390px)。
   入らないときは縦に積む。flex-wrap + 下限で、広い画面では横並びのまま */
.seg { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.seg-btn {
  /* 空きがあれば伸びるが、**中身より狭くはならない**。
     以前は flex:1(= basis 0)で等分に潰していたため、文字特大で
     「開いている避|難所」と割れていた(実測: 必要182px / 実際177px)。
     190px のような固定値を入れると、同じ .seg-btn を使う「くらし」の
     7つのタブが押し潰される(実測: 必要114px / 実際92px)。
     fit-content なら、どの並びでも中身の幅は必ず確保される */
  flex: 1 1 auto;
  min-width: fit-content;
  font-size: 0.95rem;
  font-weight: 700;
  padding: 12px 8px;
  border-radius: 12px;
  border: 2px solid var(--red);
  background: var(--card);
  color: var(--red);
  cursor: pointer;
}
.seg-btn.active { background: var(--red); color: #fff; }
.quake-list { list-style: none; }
.quake-item {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  padding: 12px 14px;
  margin-bottom: 10px;
}
.shindo {
  min-width: 2.6em;
  height: 2.6em;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.15rem;
  font-weight: 900;
  color: #fff;
  background: #57534e;
  flex-shrink: 0;
}
.shindo-1, .shindo-2 { background: #2563eb; }
.shindo-3 { background: #0e7490; }
.shindo-4 { background: #eab308; color: #1c1917; } /* 黄色は黒文字(白だとコントラスト2.94で不足) */
.shindo-5 { background: var(--orange); }
.shindo-6 { background: var(--red); }
.shindo-7 { background: #6b21a8; }
.quake-body { flex: 1; }
.quake-place { font-size: 1rem; font-weight: 800; }
.quake-meta { font-size: 0.78rem; color: #57534e; }

/* 避難所 */
.search-box {
  width: 100%;
  font-size: 1rem;
  padding: 14px;
  border: 2px solid var(--line);
  border-radius: 12px;
  margin-bottom: 10px;
  background: var(--card);
  color: var(--ink);
}
.shelter-list { list-style: none; }
.shelter-item {
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 14px;
  padding: 12px 14px;
  margin-bottom: 10px;
}
/* 「あと何か所あるか」と続きの出し方。黙って打ち切らないための行 */
.shelter-more {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin: 4px 0 12px;
}
.shelter-more .mid-btn { flex: 1 1 auto; min-height: 52px; }
.shelter-all-btn {
  flex: 0 0 auto;
  min-height: 52px;
  padding: 12px 14px;
  font-size: 0.85rem;
  font-weight: 700;
  border: 2px solid var(--blue);
  border-radius: 12px;
  background: #fff;
  color: var(--blue);
  cursor: pointer;
}
.shelter-name { font-size: 1rem; font-weight: 800; }
.shelter-addr { font-size: 0.8rem; color: #57534e; }
.shelter-dist { font-size: 0.95rem; font-weight: 800; color: var(--green); }
.shelter-map {
  display: inline-block;
  margin-top: 8px;
  font-size: 0.9rem;
  font-weight: 700;
  color: #fff;
  background: var(--blue);
  border-radius: 10px;
  padding: 10px 16px;
  text-decoration: none;
}

/* リンク集 */
.link-list { list-style: none; }
.link-h {
  font-size: 1rem;
  font-weight: 900;
  margin: 18px 0 8px;
  padding-left: 4px;
  border-left: 6px solid var(--red);
  padding-left: 10px;
}
.link-card {
  display: block;
  background: var(--card);
  border: 2px solid var(--line);
  border-left: 8px solid var(--blue);
  border-radius: 14px;
  padding: 14px;
  margin-bottom: 10px;
  text-decoration: none;
  color: var(--ink);
}
.link-card .lc-title { font-size: 1rem; font-weight: 800; }
.link-card .lc-desc { font-size: 0.78rem; color: #57534e; margin-top: 2px; }
.link-card.lc-official { border-left-color: var(--red); }
.link-card.lc-volunteer { border-left-color: var(--orange); }
.link-card.lc-life { border-left-color: var(--green); }

/* 支援: 自動巡回ボックス */
.support-status {
  background: #fff7ed;
  border: 2px solid var(--orange);
  border-radius: 14px;
  padding: 12px 14px;
  margin-bottom: 14px;
}
.support-status.hidden { display: none; }
.ss-head { font-size: 0.95rem; font-weight: 900; margin-bottom: 6px; }
.ss-head span { font-weight: 400; font-size: 0.75rem; color: #57534e; }
.ss-list { list-style: none; }
.ss-list li { margin: 6px 0; font-size: 0.85rem; }
.ss-src { font-weight: 800; }
.ss-list a { color: var(--blue); text-decoration: underline; }
.ss-ng { color: #78716c; }
.ss-note { font-size: 0.72rem; color: #57534e; margin-top: 8px; }

/* 安否 */
.safety-status { display: flex; gap: 8px; margin-bottom: 10px; }
.status-btn {
  flex: 1;
  font-size: 0.95rem;
  font-weight: 800;
  padding: 14px 6px;
  border-radius: 12px;
  border: 3px solid var(--line);
  background: var(--card);
  cursor: pointer;
  color: var(--ink);
}
.status-btn.active { border-color: var(--ink); background: #fef9c3; }
.chk-line { display: block; font-size: 0.9rem; margin-bottom: 10px; }
.chk-line input { width: 1.3em; height: 1.3em; vertical-align: middle; }
.safety-text {
  width: 100%;
  font-size: 1rem;
  padding: 12px;
  border: 2px solid var(--line);
  border-radius: 12px;
  margin-bottom: 12px;
  font-family: inherit;
  background: var(--card);
  color: var(--ink);
}
/* 「Threadsに投稿」は文字特大で188px要るのに、2列だと176pxしか無く
   「eadsに投|稿」と割れていた(実測・390px)。入る幅のときだけ2列にする。
   195px の根拠: 実測188px + 余白 */
.share-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(195px, 1fr)); gap: 10px; }
.share-btn {
  font-size: 0.95rem;
  font-weight: 800;
  padding: 16px 8px;
  border-radius: 12px;
  border: 2px solid var(--ink);
  background: var(--card);
  cursor: pointer;
  color: var(--ink);
}
#share-native { grid-column: 1 / -1; }
/* LINEは日本の安否連絡で最も使われるため最優先で見せる。LINE緑は明るいので文字は黒(コントラスト7.75) */
.share-line {
  grid-column: 1 / -1;
  background: #06C755;
  border-color: #05a648;
  color: #1c1917;
  font-size: 1.05rem;
}
#share-sms { grid-column: 1 / -1; background: var(--green); border-color: var(--green); color: #fff; }
.share-head {
  font-size: 0.95rem;
  font-weight: 900;
  margin: 18px 0 8px;
  padding-left: 10px;
  border-left: 6px solid var(--ink);
}
.share-note {
  font-size: 0.78rem;
  color: #57534e;
  background: #fff7ed;
  border-radius: 10px;
  padding: 10px 12px;
  margin-top: 12px;
}

/* 家族メモ */
.memo-ng { color: var(--red); font-weight: 700; }
.memo-label { display: block; font-size: 0.95rem; font-weight: 800; margin: 12px 0 4px; }
.memo-box {
  width: 100%;
  font-size: 1rem;
  padding: 12px;
  border: 2px solid var(--line);
  border-radius: 12px;
  font-family: inherit;
  background: var(--card);
  color: var(--ink);
}

.app-footer {
  max-width: 640px;
  margin: 0 auto;
  padding: 0 14px 32px;
  font-size: 0.72rem;
  color: #57534e;
}
.app-footer p { margin-bottom: 6px; }
.footer-owner {
  font-weight: 700;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}

/* 480px以上は auto-fit が自然に2列にするので、上書きは不要
   (ここで 1fr 1fr に固定すると、文字特大で 200px を割っても2列のままになり、
   ラベルがまた割れる) */

/* 安否: 誤解を防ぐ警告 */
.emg-warning {
  font-size: 0.85rem;
  background: #fef2f2;
  border: 2px solid var(--red);
  border-radius: 12px;
  padding: 10px 12px;
  margin-bottom: 12px;
  color: var(--ink);
}
.emg-warning a { color: var(--red); font-weight: 800; }

/* タップで再試行できる状態表示 */
.tappable { cursor: pointer; text-decoration: underline dotted; }

/* ホーム: 二次メニュー */
.home-sub-grid {
  display: grid;
  /* 「支援する方へ(ボランティア)」が2列だと入らず「ボランティ|ア」と割れていた
     (実機・文字特大)。ホームのメニューと同じく、入る幅のときだけ2列にする。
     160px の根拠: 文字特大でいちばん長い「支援する方へ(ボランティア)」は
     括弧と「・」で折り返せるので、ホームの200pxより狭くて足りる */
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 8px;
  margin-top: 12px;
}
.sub-btn {
  min-height: 48px;
  font-size: 0.82rem;
  font-weight: 700;
  padding: 8px 6px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
}
.btn-med { border-color: #be123c; }
.btn-lifeline { border-color: #a16207; }
.btn-house { border-color: #7c3aed; }
.inline-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--blue);
  text-decoration: underline;
  cursor: pointer;
}

/* 安否画面から家族メモへの導線 */
.memo-cta { margin: 14px 0 4px; }
.memo-cta .mid-btn { width: 100%; text-align: left; font-size: 0.9rem; }

/* 避難所: いま何を見ているかの説明 */
.shelter-lead {
  font-size: 0.85rem;
  background: #f5f5f4;
  border-left: 6px solid #a8a29e;
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 10px;
}
.shelter-lead.lead-open { background: #f0fdf4; border-left-color: var(--green); }
/* 開設情報が古い/時点不明のとき。緑(＝開設中)と見分けがつく色にする */
.shelter-lead.lead-stale { background: #fef3c7; border-left-color: var(--orange); }
.emg-status.home-status-warn { color: #7c2d12; font-weight: 700; }

/* 気象・洪水・土砂災害・避難情報への導線(地震以外の災害) */
.emg-weather { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.emg-wlink {
  /* min-width を大きく取ると、長い文言のときに毎回フル幅へ折り返して3行になる。
     基準幅を0にして、3つが1行に並ぶようにする */
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
  background: #fff;
  color: #7c2d12;
  border: 2px solid #fdba74;
  border-radius: 8px;
  padding: 8px 4px;
  font-size: 0.72rem;
  font-weight: 700;
  text-decoration: none;
  line-height: 1.3;
}

/* 画面を切りかえたとき、読み上げ・キーボード操作のために見出しへフォーカスを移している。
   その副作用でマウス/タップ操作の人にも青い枠が見えてしまうため、
   プログラムで当てたフォーカスの枠は消す。キーボード操作(:focus-visible)では残す */
/* 見出しは押せる部品ではないので、枠は一切出さない。
   前回 :focus-visible に青い枠を残したところ、それ自体が「青い枠」として見えてしまった。
   フォーカスの移動は読み上げのために残すが、見た目には出さない */
/* :focus-visible を知らない古いブラウザでは、セレクタ一覧に混ぜるとルールごと無効になる。
   確実に効く :focus を単独で書き、:focus-visible は別ルールにする */
.view h2:focus, .view:focus { outline: none; box-shadow: none; }
.view h2:focus-visible, .view:focus-visible { outline: none; box-shadow: none; }

/* 読み上げ・キーボード操作のためだけの見出し。画面には表示しない */
.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;
}
/* 保存版を表示中であることを、正常(緑)とは別の色で示す */
#net-status.net-stale { background: #78350f; }

/* 登録時の本人確認ウィジェット。使わない設定のときは常に hidden */
.turnstile-box { margin: 10px 0; min-height: 0; }
