html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}

#map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* mix-blend-mode の影響を地図内部に限定し、兄弟の UI へ波及させない。 */
  isolation: isolate;
}

/* Issue #426: 地図 canvas と政治レイヤーの上へ薄い紙繊維と周辺の焼けを重ねる。
   MapLibre の control corner（vendor CSS で z-index: 2）にはラベル専用 deck
   canvas と attribution が入るため、z-index: 1 の本 overlay はそれらより下に
   留まる。pointer-events: none によりパン・ズーム・picking も従来どおり地図へ
   到達する。焼けは画像へ焼き込まず radial-gradient で viewport に追従させる。 */
#map::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-image:
    radial-gradient(
      ellipse at center,
      transparent 55%,
      rgba(65, 37, 14, 0.55) 100%
    ),
    url("assets/parchment-texture.webp");
  background-repeat: no-repeat, repeat;
  background-position: center, top left;
  background-size: 100% 100%, 512px 512px;
  mix-blend-mode: multiply;
  opacity: 0.18;
}

/* TASK-40: 羊皮紙/古地図デザインの共通トークン。
   パレット: クリーム地(--parchment*) / 焦茶インク(--ink*) / 真鍮(--brass*) /
   封蝋レッド(--wax*)。書体はセリフ体（和文はゴシックの明朝相当にフォールバック）。 */
:root {
  --parchment: #f4ecd7;
  --parchment-shade: #e7d9b2;
  --parchment-deep: #ddc999;
  --ink: #3a2712;
  --ink-soft: #5c3d22;
  --frame: #5c3d22;
  --frame-dark: #3a2712;
  --brass: #b8894f;
  --brass-light: #d9b878;
  --wax: #7a2e22;
  --wax-light: #a5453a;
  --font-serif:
    Georgia,
    "Times New Roman",
    "Hiragino Mincho ProN",
    "Yu Mincho",
    serif;
}

/* TASK-40: タイムラインの角の渦巻き装飾に使う SVG（インク色の
   手書き風フラーリッシュ）。data URI で自己完結し外部画像は読み込まない。 */
:root {
  --corner-flourish: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Cpath d='M6 6 C6 20 20 24 24 12 C26 6 34 8 32 16 C30 22 22 22 22 22' fill='none' stroke='%235c3d22' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E");
}

/* Issue #256: iOS Safe Area inset（ホームインジケーター・横持ちノッチ）の
   一元定義。inset の無い環境では 0px になり、レイアウトは従来と 1px も
   変わらない（index.html の viewport-fit=cover が env() 有効化の前提。#284）。
   消費側は必ず var(--safe-area-*) を参照し、env() を直接書かないこと:
   ヘッドレス検証では env() が常に 0 のため、この変数を上書きすることで
   inset をエミュレーションする（scripts/verify/checks/safe-area.ts）。 */
:root {
  --safe-area-bottom: env(safe-area-inset-bottom, 0px);
  --safe-area-left: env(safe-area-inset-left, 0px);
  --safe-area-right: env(safe-area-inset-right, 0px);
}

/* TASK-7: ホバーツールチップ（app-spec §5.2）。カーソル近傍に追従表示する。
   TASK-40: 羊皮紙トーンへ統一（クリーム地・焦茶インク・セリフ体）
   TASK-111: 長い日本語ラベル（「領邦名 — 宗主名 領」）が枠外へあふれていた。
   displayLabel の連結でラベル長に上限は無いので、幅を広げる方向ではなく
   white-space: nowrap を外して折り返しを許す。幅は指定せず絶対配置の
   shrink-to-fit に任せ（短いラベルは従来どおり小さいまま）、上限だけ
   max-width で与える。狭い画面では枠ごと画面外へ出ないよう viewport 幅にも
   従わせる（24px は左右のマージン相当）。 */
.info-tooltip {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 20;
  max-width: min(260px, calc(100vw - 24px));
  padding: 4px 9px;
  background: var(--parchment);
  border: 1px solid var(--frame);
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
  color: var(--ink);
  font-family: var(--font-serif);
  font-size: 14px;
  line-height: 1.3;
  /* 日本語は任意位置で折り返せるが、長いラテン文字の連続（英語 NAME の
     フォールバック表示）は単語境界が無いと 1 語で max-width を超える。
     overflow-wrap: anywhere で最後の手段としてどこでも折る（break-word と違い
     shrink-to-fit の最小幅計算にも効くので、幅も内容に合わせて縮む）。 */
  overflow-wrap: anywhere;
  /* 行頭に来られない文字（長音符「ー」・小書き仮名・句読点）で折らせない。
     既定の normal だと「神聖ロ／ーマ帝国」のように長音符が行頭へ落ちる。 */
  line-break: strict;
  white-space: pre-line;
  /* ツールチップ自身がホバー判定を奪わないようにする */
  pointer-events: none;
}

.info-tooltip[hidden] {
  display: none;
}

/* TASK-6/TASK-25: タイムラインスライダー（app-spec §5.1）。
   画面左端の垂直中央帯に縦向きで固定する（上=古い 1000 / 下=新しい 1914）。
   高さは clamp した vh ベースに抑え、上下に余白を残して左上の UI・左下の
   フッターと重ならないようにする。
   TASK-40: 縦帯を木目調（繰り返しグラデーション）にし、年号はアンティーク
   真鍮のセリフ数字で表示する。 */
.timeline {
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 14px 12px 16px;
  box-sizing: border-box;
  background:
    repeating-linear-gradient(
      100deg,
      rgba(0, 0, 0, 0.12) 0px,
      rgba(0, 0, 0, 0.12) 1px,
      transparent 1px,
      transparent 7px
    ),
    linear-gradient(160deg, #5a3a22 0%, #4a2f1c 55%, #3c2716 100%);
  border: 1px solid var(--frame-dark);
  border-radius: 8px;
  box-shadow:
    0 4px 18px rgba(0, 0, 0, 0.45),
    inset 0 0 0 1px rgba(184, 137, 79, 0.35);
  color: var(--brass-light);
  font-family: var(--font-serif);
}

/* AC #3: 現在年を最上部に大きく表示（縦帯に収まるようサイズは控えめ） */
.timeline-year {
  font-size: 24px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  color: var(--brass-light);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.6);
  font-variant-numeric: tabular-nums;
}

/* TASK-25: 上=前の年代ボタン / 中央=縦スライダー / 下=次の年代ボタンの縦並び */
.timeline-controls {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.timeline-btn {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border: 1px solid var(--brass);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.25);
  color: var(--brass-light);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}

.timeline-btn:hover {
  background: rgba(184, 137, 79, 0.35);
}

.timeline-btn:disabled {
  opacity: 0.35;
  cursor: default;
}

/* TASK-25: writing-mode で range を縦向き化（vertical-lr は min が上端に来るため
   index 0 = 1000 が最上部になり「上=古い」の並びと一致。direction 反転は不要）。
   datalist の目盛りはこの縦トラックに沿って描画される。
   TASK-40: accent-color を真鍮系に変更しアンティーク調に。 */
.timeline-slider {
  flex: 0 0 auto;
  writing-mode: vertical-lr;
  height: clamp(200px, 46vh, 460px);
  accent-color: var(--brass);
  cursor: pointer;
}

/* #328: 統合アトリビューション（MapLibre 標準 AttributionControl・compact）。
   左上の独自ⓘ（出典・免責）と⚠（既知の制限）を撤去し、常設の補助 UI は
   右下のこの「ⓘ」1 個だけにした（AC1/AC2）。折りたたみ・展開は MapLibre 標準の
   <details>/<summary> なので、キーボード操作（Enter/Space）と展開状態の通知は
   ブラウザ標準の disclosure として機能する（AC10）。ここでは羊皮紙トーンへの
   意匠合わせと、展開時にビューポートからはみ出さないための寸法だけを与える。
   vendor/maplibre-gl.css より後に読み込まれるため、同一詳細度の規則は
   こちらが勝つ（index.html の <link> 順）。 */
.maplibregl-ctrl.maplibregl-ctrl-attrib {
  background-color: var(--parchment);
  color: var(--ink);
  font-family: var(--font-serif);
  font-size: 11px;
  line-height: 1.4;
}

/* 折りたたみ時（ⓘ ボタンだけ）の見た目。#328 以前の左上の円形トグルと
   同系のトーンに揃える */
.maplibregl-ctrl-attrib.maplibregl-compact {
  border: 1px solid var(--brass);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

/* ⓘ ボタン自身は透明にしてカード地（羊皮紙）を透かす。アイコンは MapLibre の
   ⓘ グリフをそのまま使う（背景画像なので繰り返さないよう明示する） */
.maplibregl-ctrl-attrib-button {
  background-color: transparent;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 24px 24px;
}

.maplibregl-ctrl-attrib.maplibregl-compact-show .maplibregl-ctrl-attrib-button {
  background-color: rgba(58, 39, 18, 0.08);
}

/* 展開時のカード。幅は viewport 内に収め（左右 32px の余白）、狭い画面でも
   横スクロールを生まないようにする（AC11） */
.maplibregl-ctrl-attrib.maplibregl-compact-show {
  max-width: min(
    46ch,
    calc(100vw - 32px - var(--safe-area-left) - var(--safe-area-right))
  );
}

/* 展開時の本文。内容が高くなっても下端・上端がビューポートから出ないよう
   高さに上限を与え、収まらない分はここが内部スクロールする（AC11）。
   スクロール終端で背後の地図へ操作が伝播しないよう overscroll-behavior は
   contain。dvh はモバイルの URL バーを除いた実表示高さで、未対応ブラウザは
   直前の vh 版へフォールバックする */
.maplibregl-ctrl-attrib-inner {
  max-height: calc(100vh - 96px);
  max-height: calc(100dvh - 96px);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* 羊皮紙の意匠を壊さない控えめなスクロールバー */
  scrollbar-width: thin;
  scrollbar-color: var(--frame) transparent;
}

.maplibregl-ctrl-attrib a {
  color: var(--wax);
}

.maplibregl-ctrl-attrib a:hover {
  color: var(--wax-light);
}

/* TASK-9: ロード中スピナー（app-spec §5.4）。地図中央にオーバーレイ。
   TASK-40: 真鍮アクセントに統一 */
.loading-spinner {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 30;
  width: 40px;
  height: 40px;
  margin: -20px 0 0 -20px;
  border: 4px solid rgba(58, 39, 18, 0.25);
  border-top-color: var(--brass);
  border-radius: 50%;
  animation: loading-spin 0.8s linear infinite;
  pointer-events: none;
}

.loading-spinner[hidden] {
  display: none;
}

@keyframes loading-spin {
  to {
    transform: rotate(360deg);
  }
}

/* prefers-reduced-motion 時は回転を止め、静的なインジケータにする */
@media (prefers-reduced-motion: reduce) {
  .loading-spinner {
    animation: none;
  }
}

/* TASK-9: fetch 失敗時のエラートースト + 再試行（app-spec §5.4）。上部中央に表示。
   TASK-40: 封蝋レッド（--wax）に統一しつつ警告としての視認性は維持 */
.error-toast {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(520px, calc(100% - 32px));
  padding: 10px 14px;
  background: var(--wax);
  border: 1px solid var(--frame-dark);
  border-radius: 6px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.4);
  color: var(--parchment);
  font-family: var(--font-serif);
  font-size: 14px;
}

.error-toast[hidden] {
  display: none;
}

.error-toast-message {
  line-height: 1.3;
}

.error-toast-retry {
  flex: 0 0 auto;
  padding: 5px 13px;
  border: 1px solid var(--frame-dark);
  border-radius: 4px;
  background: var(--parchment);
  color: var(--wax);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}

.error-toast-retry:hover {
  background: var(--brass-light);
}

.error-toast-close {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border: 1px solid rgba(244, 236, 215, 0.55);
  border-radius: 4px;
  background: rgba(244, 236, 215, 0.15);
  color: var(--parchment);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.error-toast-close:hover {
  background: rgba(244, 236, 215, 0.3);
}

/* =========================================================================
   TASK-132: 小画面（スマートフォン縦持ち）向けブレークポイント
   Issue #252: 同じスタイルをスマートフォン横持ちにも適用する

   閾値 480px は TASK-132 で採用した既存の小画面境界を維持する。主要
   スマートフォンの論理幅（320〜430px）を全て包含する。481px 以上は既存レイアウトを 1px も
     変えない（AC #5。変更はこの @media 内に閉じる）。

   横持ち条件 (max-height: 480px) and (pointer: coarse) の根拠
   （Issue #252。844x390 の実測に基づく）:
   - 幅条件だけでは横持ち（論理幅 568〜932px）でデスクトップ配置に戻り、
     縦タイムライン（高さ 358px）が 390px 高のほぼ全域を占め、タップ対象も
     34px 以下に縮む。縦持ちの論理幅 320〜430px は横持ちでは論理高になる
     ため、高さ側にも同じ閾値 480px を適用して同じ端末集合を捕捉する。
   - (pointer: coarse) を併置し、タッチ主体の端末に限定する。マウス操作の
     デスクトップはウィンドウを低くしても pointer: fine のため対象外で、
     従来レイアウトを 1px も変えない。
   - この条件では縦持ちと同じ下端横帯レイアウトになるため、縦タイムラインが
     地図を覆うことはなく、44px のタップ当たり判定も共通に確保される。

   小画面の配置（#284 で「案C: タイムラインを最下部へ移動」を採用し、
   #328 で左上のⓘ・⚠を撤去して右下アトリビューションへ統合した）:
   - 最下部（Safe Area 直上）: タイムライン 1 段バー（年号・前後ボタン・
     横スライダー。高さ 60px）
   - その直上の右端: MapLibre のアトリビューション「ⓘ」（44px。起動時は
     折りたたみ済みで、タップすると上方向へ本文が開く）
   - 上端には常設 UI が無い（#328 でトグル行を撤去）
   - 中央の広い帯（タイムライン上端まで）には常時 UI が無く、地図が主役になる
   ========================================================================= */
@media (max-width: 480px), (max-height: 480px) and (pointer: coarse) {
  /* --- タイムライン: 左端の縦帯 → Safe Area 直上の最下部 1 段バー
     （#284 AC3） ---
     縦帯は幅 92px x 高さ 531px（画面高の 65%）で左端の中央帯を常時覆う。
     1 段バーにすると高さ 60px で、地図の
     中央部を一切覆わない。writing-mode を横書きへ戻すことで range は
     「左=古い / 右=新しい」になり、時間軸の慣習とも一致する。
     Safe Area 変数（--safe-area-bottom）でホームインジケーターの内側に置く
     （#284 AC8。inset の無い端末では 0px で従来どおり画面最下部）。
     Issue #256: 横持ちノッチ（left/right inset）でもバー全体と両端の操作対象
     （年号・◀ボタン）が安全領域内に収まるよう、左右も inset 分だけ内側へ。 */
  .timeline {
    left: calc(var(--safe-area-left) + 8px);
    right: calc(var(--safe-area-right) + 8px);
    top: auto;
    bottom: calc(var(--safe-area-bottom) + 8px);
    transform: none;
    flex-direction: row;
    gap: 10px;
    padding: 8px 10px;
  }

  .timeline-year {
    /* 横帯の高さを 44px ボタンで決めるため、年号は一回り小さくする */
    font-size: 20px;
    flex: 0 0 auto;
  }

  .timeline-controls {
    flex: 1 1 auto;
    flex-direction: row;
    gap: 6px;
    min-width: 0;
  }

  .timeline-btn {
    /* タップ当たり判定 44px（AC #4） */
    width: 44px;
    height: 44px;
    /* 縦帯の▲（上=古い）/▼（下=新しい）を横帯の◀（左=古い）/▶（右=新しい）に
       向け直す。HTML のグリフはそのままに回転だけで済ませる（円形ボタンなので
       枠の見た目は変わらない） */
    transform: rotate(-90deg);
  }

  .timeline-slider {
    /* 縦向き化（writing-mode: vertical-lr）を横書きへ戻す。min が左端に
       来るため index 0 = 1000 が左になり「左=古い」の並びと一致する */
    writing-mode: horizontal-tb;
    flex: 1 1 auto;
    min-width: 0;
    /* 縦帯用の clamp(200px, 46vh, 460px) を無効化し、入力ボックス自体を
       44px にしてタップ当たり判定を確保する（AC #4。トラックは中央に描画） */
    height: 44px;
  }

  /* --- アトリビューション「ⓘ」: 最下部タイムラインバーの直上（AC5/AC8/AC9） ---
     下端アンカーをタイムラインバー（高さ 60px + 下余白 8px）+ 8px の位置へ
     上げる。展開・格納の操作性は MapLibre 標準のまま（1 タップで全文へ到達
     できる。AC3）。
     Issue #256: 横持ちノッチでは right inset 分だけ内側へ寄せる（maplibre
     標準 CSS の right: 0 の上書き。inset 0 では従来と同値）。
     展開した本文は地図上へ伸びるため、小画面では地図より前面に上げる。
     エラートーストの z-index 40 よりは下に置く。 */
  .maplibregl-ctrl-bottom-right {
    right: var(--safe-area-right);
    bottom: calc(var(--safe-area-bottom) + 76px);
    z-index: 21;
  }

  /* ⓘ のタップ当たり判定 44px（AC9）。ボタンは絶対配置でカード右上に重なる
     ため、カード側にも同じだけの余白（右 44px + 8px）と最低高を与えて
     本文とアイコンが重ならないようにする */
  .maplibregl-ctrl-attrib-button {
    width: 44px;
    height: 44px;
    border-radius: 22px;
  }

  .maplibregl-ctrl-attrib.maplibregl-compact {
    min-height: 44px;
    padding: 0 44px 0 0;
    border-radius: 22px;
  }

  .maplibregl-ctrl-attrib.maplibregl-compact-show {
    padding: 6px 52px 8px 12px;
  }

  /* 展開時の本文の高さ上限。下端はタイムラインバー（60px + 余白 8px）+
     ⓘ の位置（+8px）+ Safe Area、上端は画面上端に 16px 残す */
  .maplibregl-ctrl-attrib-inner {
    max-height: calc(100vh - var(--safe-area-bottom) - 160px);
    max-height: calc(100dvh - var(--safe-area-bottom) - 160px);
  }

  /* --- Issue #254: 展開後のパネル内のリンクも 44px 相当に ---
     常時表示のトグルだけでなく、展開後のインタラクティブ要素（統合
     attribution の本文リンク）も 44px 相当の当たり判定にする。
     タップ当たり判定だけを広げ、文字組みは変えない: リンク（inline）の縦
     padding は行送りに影響せず当たり判定だけが広がり、横 padding は同量の
     負 margin で打ち消して字面の位置を不変に保つ。行末で padding が
     カードの横 padding（12px）に収まるため、横スクロールは生まない
     （#328 AC11）。 */
  .maplibregl-ctrl-attrib-inner a {
    padding: 17px 12px;
    margin: -17px -12px;
  }
}
