:root {
  --bg: #faf9f7;
  --surface: #ffffff;
  /* セクションの区切りに使う、ほんの少し色を持つ面。真っ白の隣に置いて段差を作る */
  --surface-alt: #f4f3f8;
  --text: #1f1f24;
  --text-muted: #6b6b76;
  --accent: #5b5bd6;
  --accent-soft: #eeedfb;
  /* 地図の未訪問。**あえて青系から外して灰にする**(2026-08-24)。
     「行った/行っていない」を色相(灰 vs 青)で分けると、訪問済みの4段は
     明度をめいっぱい使えるようになり、中間の段の差が読めるようになる。
     以前は --accent-soft(#eeedfb)を使い回していたため、薄い段と紛れないよう
     4段を濃いほうへ寄せる必要があり、そのせいで中間2つがほぼ同じ色だった。 */
  --map-unvisited: #e6e4df;
  --accent-contrast: #ffffff;
  --border: #e4e2dd;

  /* **影**。1348行中2箇所しか使っていなかったのが「ワイヤーフレームのまま」に
     見える最大の原因だった。カードの枠線はこれに置き換える。
     2段重ね(近くの薄い影＋遠くの広い影)にすると、1本の影より自然に浮く */
  --shadow-card: 0 1px 2px rgba(31, 31, 36, 0.04), 0 6px 16px rgba(31, 31, 36, 0.06);
  --shadow-raised: 0 2px 4px rgba(91, 91, 214, 0.18), 0 8px 20px rgba(91, 91, 214, 0.22);
  --shadow-pressed: 0 1px 2px rgba(91, 91, 214, 0.24);

  /* 角丸を3段にする(以前は12px一律で、大小の階層が付かなかった) */
  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 22px;

  --accent-grad: linear-gradient(135deg, #5b5bd6 0%, #7f7ff0 100%);
}

* { box-sizing: border-box; }

/* **入力欄にフォーカスすると画面が横に動く**(実機FB)。静的にははみ出していない
   (全画面で scrollWidth === 390)が、iOSは入力欄を見せるために祖先を横にも
   スクロールさせる。ここで横方向のスクロール自体を殺す。
   **hidden ではなく clip を使う** ―― hidden はスクロールコンテナを作ってしまい、
   .form-sticky-actions の position:sticky が効かなくなる。 */
html { overflow-x: clip; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Hiragino Sans", "Yu Gothic", sans-serif;
  line-height: 1.6;
}

#splash {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 64px;
  background: var(--bg);
  z-index: 100;
}

/* ダブルタップによる拡大を止める(ピンチ操作での拡大は残す)。
   県を続けてタップするとSafariがダブルタップと解釈して勝手に拡大し、
   画面が「100%に収まっていない・右にずれている」状態になっていた。
   なお viewport metaの user-scalable=no / maximum-scale は
   **iOS Safari 10以降アクセシビリティのため無視される**ので、
   「拡大してしまってから元に戻す」方式では直せない。拡大させないのが正攻法。 */
#app, body {
  touch-action: manipulation;
}

#app {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;
  padding: calc(env(safe-area-inset-top) + 20px) calc(env(safe-area-inset-right) + 16px)
    calc(env(safe-area-inset-bottom) + 32px) calc(env(safe-area-inset-left) + 16px);
}

/* **カードが順に入ってくる**。1枚ずつ40msずらすだけで、同じ内容でも
   「組み上がった」感じが出る。既存の演出(紙吹雪・ルーレット等)には触っていない */
.stagger-in > * {
  animation: card-rise 0.32s cubic-bezier(0.22, 0.9, 0.3, 1) both;
}
.stagger-in > *:nth-child(1) { animation-delay: 0ms; }
.stagger-in > *:nth-child(2) { animation-delay: 40ms; }
.stagger-in > *:nth-child(3) { animation-delay: 80ms; }
.stagger-in > *:nth-child(4) { animation-delay: 120ms; }
.stagger-in > *:nth-child(5) { animation-delay: 160ms; }
.stagger-in > *:nth-child(n + 6) { animation-delay: 200ms; }
@keyframes card-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

.screen-enter-forward { animation: screen-in-forward 0.2s ease; }
.screen-enter-back { animation: screen-in-back 0.2s ease; }
@keyframes screen-in-forward {
  from { opacity: 0; transform: translateX(14px); }
  to { opacity: 1; transform: translateX(0); }
}
@keyframes screen-in-back {
  from { opacity: 0; transform: translateX(-14px); }
  to { opacity: 1; transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  .screen-enter-forward, .screen-enter-back { animation: none; }
  /* 入場のstaggerとスケルトンの明滅も止める(both指定なので、
     animation:none だと初期状態=透明で固まる。可視の状態を明示する) */
  .stagger-in > * { animation: none; opacity: 1; transform: none; }
  .skeleton { animation: none; }
  /* 点滅は止めるが、枠線は残す(どこを見ればいいかは伝える必要がある) */
  .whoami-card.needs-attention { animation: none; }
}

.home-hero-row {
  display: flex;
  flex-direction: column;
}

/* 起動時タイトル画面(桃鉄風のオリジナル演出) */
.title-screen {
  min-height: calc(100vh - 40px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 28px;
  text-align: center;
  background: linear-gradient(160deg, var(--accent) 0%, #9291f5 55%, #ff8fd6 100%);
  border-radius: var(--radius);
  color: #fff;
  padding: 32px 16px;
}
.title-screen-emoji {
  font-size: 72px;
  animation: title-logo-in 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
.title-screen-logo h1 {
  font-size: 26px;
  margin: 8px 0 0;
  color: #fff;
  animation: title-logo-in 0.6s 0.15s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
@keyframes title-logo-in {
  from { opacity: 0; transform: scale(0.5) translateY(20px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
.title-screen-start {
  width: auto;
  padding: 14px 44px;
  background: #fff;
  color: var(--accent);
  font-size: 18px;
  animation: title-start-pulse 1.4s ease-in-out infinite;
}
@keyframes title-start-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.06); }
}
@media (prefers-reduced-motion: reduce) {
  .title-screen-emoji,
  .title-screen-logo h1,
  .title-screen-start { animation: none; }
}

/* スマホを横向きにしたときの対応(高さが乏しく縦積みだと窮屈になるため)。
   max-height: 500pxはスマホの横向きを検出する一般的な条件で、タブレット/PCの
   横長画面は普通これに該当しない。 */
@media (orientation: landscape) and (max-height: 500px) {
  #app { max-width: 720px; }

  .home-hero-row {
    flex-direction: row;
    align-items: stretch;
    gap: 12px;
  }
  .home-hero-row > .home-hero-left,
  .home-hero-row > .pref-map-wrap {
    flex: 1;
    min-width: 0;
    margin-bottom: 0;
  }

  .celebration-hero { padding: 10px 16px 4px; }
  .celebration-hero .emoji { font-size: 34px; }
  .celebration-hero h1 { font-size: 20px; margin: 4px 0 2px; }

  .photo-grid { grid-template-columns: repeat(5, 1fr); }

  /* 地図タイル演出は#appの横幅いっぱいだと縦に長くなりすぎるため、
     横画面では高さを基準に収める */
  .map-reveal-frame { width: min(100%, calc((100vh - 260px) * 339 / 383)); margin-left: auto; margin-right: auto; }
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
.checkbox-chip input:focus-visible + span {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* **絵文字の並びを揃える**。今まで場所ごとに大きさも縦位置もバラバラで、
   それが「安っぽさ」の正体だった(絵文字そのものが悪いのではない ―
   名物ポップや称号はこのアプリの個性なので減らさない)。
   幅を固定すると、文字と並べたときに頭が揃う */
.emo {
  display: inline-block;
  width: 1.2em;
  text-align: center;
  line-height: 1;
  font-style: normal;
}

h1 { font-size: 22px; margin: 0 0 4px; letter-spacing: -0.01em; }
h2 { font-size: 17px; margin: 0 0 8px; }
p { margin: 0 0 8px; }

.muted { color: var(--text-muted); font-size: 13px; }

.topbar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
}
/* 「いま誰として記録するか」。**タイトルバーの中に置くので高さが増えない** */
.topbar-me {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
  max-width: 40%;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topbar h1 {
  flex: 1;
  min-width: 0;
  margin: 0;
  /* 右上のBGMボタンは廃止したので、余白は詰めてよい(2026-08-26)。
     空いたぶんは .topbar-me が使う */
  padding-right: 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.back-link {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 14px;
  padding: 10px 8px;
  margin-left: -8px;
  border-radius: 8px;
  transition: transform 0.1s ease, background 0.1s ease;
}
.back-link:active { transform: scale(0.96); background: var(--accent-soft); }

.card {
  background: var(--surface);
  /* **枠線ではなく影で浮かせる**。細枠は線が主張するわりに階層を作らない */
  border: none;
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 16px 18px;
  margin-bottom: 14px;
}

.home-badge-hero {
  text-align: center;
  margin-bottom: 12px;
}
.home-badge-hero .title-badge-row { justify-content: center; }

/* 子どもが登録されているときのヒーロー。制覇率ではなく「子どもと積み上げた記録」を
   画面の主役に置く。名前は自由入力で長くなりうるので必ず折り返す */
.home-badge-hero.is-child .child-hero-age {
  font-size: 26px;
  font-weight: 700;
  color: var(--accent);
  line-height: 1.25;
  overflow-wrap: anywhere;
}
.home-badge-hero.is-child .child-hero-sub {
  margin-top: 2px;
  font-size: 15px;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

/* 称号を進捗カードへ移したときの余白 */
.progress-card .title-badge-row { margin-top: 12px; }
.progress-title-teaser { margin: 12px 0 0; font-size: 13px; }

/* 誕生日の前後だけ出る「1年のまとめ」導線。カードだがボタンなので見た目を揃える */
.birthday-card {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  background: linear-gradient(135deg, var(--accent-soft), #fff4d6);
  border: 1px solid var(--accent);
}
.birthday-card:active { transform: scale(0.98); opacity: 0.85; }
.birthday-card-head { margin: 0; font-size: 17px; font-weight: 700; overflow-wrap: anywhere; }

/* 地図の濃淡の凡例。地図の付属物なので小さく、折り返して収める */
.map-age-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-top: 6px;
  font-size: 11px;
  color: var(--text-muted);
}
.map-age-legend-item { display: flex; align-items: center; gap: 4px; }
.map-age-legend-swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  flex-shrink: 0;
}
/* 凡例の色は www/js/map-colors.js が決めて style で直接当てる(2026-08-24)。
   10県ごとに色相が変わり47色になるので、CSSクラスでは持てない */

/* 成長の記録の写真グリッド。旅行カードより前に置くので、見出しとの間だけ空ける */
.age-section-photos { margin: 10px 0 12px; }
.age-section-photos a { display: block; }
.age-section-photos a:active { opacity: 0.8; }

/* 0県のときの「次にもらえる称号」予告。獲得済みバッジと取り違えないよう、
   色を持たせず輪郭だけの控えめな表示にする */
.home-badge-hero.is-teaser .badge-teaser-mark {
  width: 52px;
  height: 52px;
  margin: 0 auto;
  border: 2px dashed var(--border);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  font-weight: 700;
  color: var(--text-muted);
}

.export-result { margin-top: 20px; }
.export-preview {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: block;
}

.map-select-row {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}
.map-select-row > .region-select { margin-bottom: 0; }

.trip-card-age,
.trip-detail-age {
  font-size: 12px;
  color: var(--accent);
  font-weight: 600;
  margin: 2px 0 0;
}

.age-section { margin-bottom: 28px; }
.age-section-head { background: var(--accent-soft); border-color: var(--accent); }

.home-footer {
  display: flex;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 28px;
}
.home-footer a {
  /* 13px・文字高だけのタップ領域だと押しづらく、子どもの登録(このアプリの主役)が
     ここに埋もれて気づかれなかった。文字を大きくし、上下の余白でタップ領域を確保する */
  font-size: 15px;
  padding: 12px 4px;
  color: var(--text-muted);
  /* 想定外に長い名前が入っても画面全体が横スクロールしないようにする(保険) */
  max-width: 100%;
  overflow-wrap: anywhere;
}

/* 子どもが未登録のときだけ出す招待カード。押せることが分かるよう左に色帯を付ける。
   ヒーローの直後に置くので、進捗と操作ボタンを折り返しの外へ押し出さないよう薄くする */
.child-invite-card {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  width: 100%;
  text-align: left;
  margin: 12px 0 0;
  padding: 10px 14px;
  border-left: 4px solid var(--accent);
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.child-invite-card:active { transform: scale(0.99); }
.child-invite-head { margin: 0; font-weight: 600; }
.child-invite-sub { margin: 0; font-size: 13px; color: var(--text-muted); }

/* 都道府県詳細の「ここは行ったことある」 */
.visited-box { margin-top: 16px; }
.visited-box input[type="date"] { width: 100%; }
.pref-born-here {
  margin: 8px 0 0;
  font-weight: 600;
  color: var(--accent);
}

/* 圏外で古い内容を出しているときの帯。目立ちすぎず、見落とさない程度に */
.offline-badge {
  margin: 0 0 12px;
  padding: 8px 12px;
  border-radius: var(--radius);
  background: #fff4e5;
  border: 1px solid #f0d5ae;
  color: #8a5a00;
  font-size: 13px;
  text-align: center;
}

/* 圏外で写真が読めなかったタイル */
.media-tile-offline {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  border-radius: 8px;
  background: var(--accent-soft);
  font-size: 28px;
  opacity: 0.7;
}

/* 素材のクレジット。CC BY 4.0 の帰属表示なので、目立たなくても消さないこと */
.credits {
  margin-top: 32px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  font-size: 13px;
}
.credits-head { margin: 0; font-weight: 600; color: var(--text-muted); }
.credits a { color: var(--accent); }

.app-version {
  margin: 28px 0 0;
  text-align: center;
  font-size: 11px;
  color: var(--text-muted);
  opacity: 0.7;
}

.pref-specialty {
  display: flex;
  align-items: center;
  gap: 12px;
}
.pref-specialty-emoji {
  font-size: 34px;
  line-height: 1;
  flex-shrink: 0;
}

.on-this-day-card {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: inherit;
  margin-bottom: 16px;
  transition: transform 0.1s ease, opacity 0.1s ease;
}
.on-this-day-card:active { transform: scale(0.98); opacity: 0.85; }
.on-this-day-card img {
  width: 64px;
  height: 64px;
  border-radius: 8px;
  object-fit: cover;
  flex-shrink: 0;
}

.full-conquest-badge {
  text-align: center;
  background: linear-gradient(135deg, var(--accent-soft), #fff4d6);
}

/* 旅立ちの見送り画面 */
.sendoff-slideshow {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 12px;
  background: var(--accent-soft);
}
.sendoff-slideshow img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.3s ease;
}
.sendoff-slideshow img.is-fading { opacity: 0; }
.sendoff-comment { font-size: 16px; font-weight: 600; }
@media (prefers-reduced-motion: reduce) {
  .sendoff-slideshow img { transition: none; }
}

.progress-card {
  text-align: center;
  padding: 20px 16px;
}
/* **主役の数字**。以前は32pxで「2」と「47」が同じ大きさに見え、画面が平坦だった。
   分母は副次表示に落として、いま何県まで来たかだけを大きく見せる。
   tabular-nums は桁が増えても幅が揺れないようにするため(1桁→2桁で跳ねない) */
.progress-count {
  font-size: 56px;
  font-weight: 700;
  color: var(--accent);
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: baseline;
  gap: 4px;
}
.progress-count .of {
  font-size: 20px;
  font-weight: 600;
  color: var(--text-muted);
  letter-spacing: 0;
}
.progress-bar-track {
  height: 8px;
  background: var(--accent-soft);
  border-radius: 999px;
  overflow: hidden;
  margin: 10px 0 4px;
}
.progress-bar-fill { height: 100%; background: var(--accent); transition: width 0.6s ease; }

.pref-map-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  margin-bottom: 16px;
}
.region-select {
  width: 100%;
  font: inherit;
  font-size: 14px;
  padding: 8px 10px;
  margin-bottom: 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
}

.pref-map { width: 100%; height: auto; display: block; }

/* 天気予報方式の沖縄インセット枠。地図本体と取り違えないよう破線の控えめな枠にする */
.map-inset-frame {
  fill: none;
  stroke: var(--border);
  stroke-width: 1.5;
  stroke-dasharray: 4 3;
}
.map-inset-label {
  fill: var(--text-muted);
  font-size: 9px;
  font-weight: 700;
}

/* 地図上の遊び(海の生き物・乗り物・キラキラ・季節前線・雲)。
   あくまで飾りなので、県のタップ判定を邪魔しないようpointer-eventsを切る */
.map-fun-item {
  pointer-events: none;
  user-select: none;
  /* **絵文字フォントを明示する**(2026-08-24)。SVGの<text>はフォントを継承するので、
     絵文字を持たないフォントに落ちると□(豆腐)になる。実機で「星は枠がついてて
     四角い」と指摘されたのは、まさにこの症状だった。 */
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji",
    "Hiragino Sans", sans-serif;
  /* SVG要素のtransformは既定でview-box原点(0,0)基準になるため、scale()すると
     その場で拡大縮小せず原点方向へ吹き飛ぶ(名物ポップが県からずれる不具合の原因だった)。
     自分の矩形の中心を基準にする */
  transform-box: fill-box;
  transform-origin: center;
}
.map-fun-cloud { opacity: 0.55; }
.map-fun-sparkle { animation: map-fun-sparkle 1.6s ease forwards; }
@keyframes map-fun-sparkle {
  0%   { opacity: 0; transform: scale(0.6); }
  30%  { opacity: 1; transform: scale(1.15); }
  100% { opacity: 0; transform: scale(1); }
}
/* 名物ポップ。JS側のSPECIALTY_POP_MSと合わせること(3.5s)。
   出入りは元のままの速さにして、真ん中の「いちばん大きく見えている時間」だけを
   伸ばしている(全体を等倍で遅くすると、出てくる動きまで間延びして鈍く見えるため) */
.map-fun-pop { animation: map-fun-pop 3.5s ease forwards; }
@keyframes map-fun-pop {
  0%   { opacity: 0; transform: scale(0.5) translateY(0); }
  8%   { opacity: 1; transform: scale(1.25) translateY(-3px); }
  14%  { opacity: 1; transform: scale(1.1) translateY(-5px); }
  75%  { opacity: 1; transform: scale(1.1) translateY(-8px); }
  100% { opacity: 0; transform: scale(1) translateY(-16px); }
}

@media (prefers-reduced-motion: reduce) {
  .map-fun-sparkle, .map-fun-pop { animation: none; }
}
.pref-map path {
  fill: var(--map-unvisited);
  stroke: var(--surface);
  stroke-width: 0.5;
  cursor: pointer;
  transition: fill 0.15s ease;
}
.pref-map path.visited { fill: var(--accent); }

/* 訪問済みの県の色は **www/js/map-colors.js が「何番目に行ったか」から計算して
   style.fill に直接当てる**(2026-08-24)。
   同じ色相の明暗だけでは3段以上を見分けられず、実機で2度「分かりづらい」と
   言われたため、10県ごとに色相そのものを変える形にした。
   47色になるのでCSSクラスでは持てない。**未訪問(灰)はCSSのまま。** */

.pref-map path:hover { fill: var(--text-muted); }

.pref-map path.wishlist {
  fill: var(--accent-soft);
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-dasharray: 3 2;
}

.pref-map path.next-destination,
.pref-map path.in-progress {
  fill: var(--accent);
  animation: pref-pulse 1.6s ease-in-out infinite;
}
@keyframes pref-pulse {
  0%, 100% { filter: drop-shadow(0 0 0 transparent); opacity: 1; }
  50%      { filter: drop-shadow(0 0 6px var(--accent)); opacity: 0.75; }
}

.pref-map path.just-conquered {
  animation: pref-conquer 1.1s ease forwards;
}
@keyframes pref-conquer {
  0%   { fill: var(--accent-soft); filter: drop-shadow(0 0 0 transparent); }
  35%  { filter: drop-shadow(0 0 10px var(--accent)); }
  100% { fill: var(--accent); filter: drop-shadow(0 0 0 transparent); }
}

.get-pop { animation: get-pop-in 0.35s ease; }
@keyframes get-pop-in {
  from { opacity: 0; transform: scale(0.7); }
  to   { opacity: 1; transform: scale(1); }
}

.progress-count.just-updated { animation: count-pop 0.4s ease; }
@keyframes count-pop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.25); }
  100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .pref-map path.next-destination,
  .pref-map path.in-progress,
  .pref-map path.just-conquered,
  .get-pop,
  .celebration-hero .emoji.suspense-bob,
  .progress-count.just-updated { animation: none; }
}

.celebration-map-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  margin: 16px 0;
}

.celebration-hero {
  text-align: center;
  padding: 24px 16px 8px;
}
.celebration-hero .emoji { font-size: 48px; }
.celebration-hero h1 { font-size: 26px; margin: 8px 0 4px; }
.celebration-hero .emoji.suspense-bob { animation: suspense-bob 1.2s ease-in-out infinite; }
@keyframes suspense-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-8px); }
}

.celebration-progress {
  text-align: center;
  margin: 12px 0 20px;
}
.celebration-progress .progress-count { font-size: 28px; }

/* 通り名+バッジ */
.title-badge-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 6px;
}
.title-badge-shape {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
}
.title-badge-shape.bronze { background: linear-gradient(135deg, #cd7f32, #a35c22); }
.title-badge-shape.silver { background: linear-gradient(135deg, #e2e2e2, #9a9a9a); }
.title-badge-shape.gold { background: linear-gradient(135deg, #ffd76a, #d9a520); }
.title-badge-shape.platinum { background: linear-gradient(135deg, #b8f2ff, #9291f5, #ff8fd6); }
.title-badge-label { font-size: 14px; font-weight: 600; }

.title-badge-shape.large { width: 64px; height: 64px; font-size: 28px; }

/* 紙吹雪 */
.confetti-piece {
  position: fixed;
  top: -12px;
  width: 8px;
  height: 14px;
  opacity: 0.9;
  pointer-events: none;
  z-index: 200;
  animation-name: confetti-fall;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}
@keyframes confetti-fall {
  to { transform: translateY(110vh) rotate(540deg); opacity: 0.3; }
}
@media (prefers-reduced-motion: reduce) {
  .confetti-piece { display: none; }
}

/* 桃鉄風の地図タイルリビール演出(ルーレット・目的地発表で共有) */
.map-reveal-stage { margin: 16px 0; }
.map-reveal-frame {
  position: relative;
  border: 6px solid #b98a4a;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 6px 0 #8a6431, 0 10px 18px rgba(0, 0, 0, 0.2);
  /* ホームの地図と同じ天気予報方式(viewBox 98 0 339 383、沖縄は左上インセット)に
     合わせた縦横比。地図の見た目をアプリ内で統一するため、こちらもホームに揃えている */
  aspect-ratio: 339 / 383;
}
.reel-map-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background: #bfe4fb;
}
.reel-map-bg .pref-map { width: 100%; height: 100%; }
.reel-map-bg .pref-map path {
  fill: #8fce8f;
  stroke: #6bab6b;
  stroke-width: 0.5;
  cursor: default;
}
.reel-map-bg .pref-map path:hover { fill: #8fce8f; }
.map-reveal-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: repeat(4, 1fr);
  gap: 0;
  width: 100%;
  height: 100%;
  perspective: 500px;
}
.map-reveal-caption {
  margin-top: 10px;
  /* 文字が入る前と後で高さが変わると、結果表示の瞬間に枠がガタつく。
     min-heightではなく固定の高さ+中央揃えにして、常に同じ大きさに保つ */
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 15px;
  font-weight: 700;
  color: #7a2a05;
  background: #fff8e6;
  border: 3px solid #2b1d0e;
  border-radius: 12px;
  padding: 10px 14px;
}
.map-reveal-tile {
  border: 1px solid rgba(255, 255, 255, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 2px;
  font-size: 15px;
  line-height: 1.1;
  font-weight: 900;
  color: #7a2a05;
  background: transparent;
  overflow: hidden;
}
.map-reveal-tile.spinning {
  animation: map-reveal-spin 0.9s linear;
  background: #fff;
}
.map-reveal-tile.winner {
  background: #ffd93d;
  border-color: #e2521a;
  animation: get-pop-in 0.35s ease;
}
@keyframes map-reveal-spin {
  0% { transform: rotateY(0deg); background: transparent; }
  15% { background: #fff; }
  100% { transform: rotateY(1080deg); background: #fff; }
}
@media (prefers-reduced-motion: reduce) {
  .map-reveal-tile.spinning,
  .map-reveal-tile.winner { animation: none; }
}

.trip-card {
  display: flex;
  gap: 12px;
  text-decoration: none;
  color: inherit;
  transition: transform 0.1s ease, opacity 0.1s ease;
}
.trip-card:active { transform: scale(0.98); opacity: 0.85; }
.trip-card-thumb,
.trip-card-thumb-placeholder {
  width: 96px;
  height: 96px;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  flex-shrink: 0;
}
.trip-card-thumb { object-fit: cover; }
.trip-card-thumb-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
}
.trip-card-body { flex: 1; min-width: 0; }
.trip-card-title { font-weight: 600; font-size: 15px; }
.trip-card-meta { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.trip-card-tags { margin-top: 4px; font-size: 14px; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--accent-soft);
  color: var(--text);
  border-radius: 999px;
  padding: 6px 12px;
  font-size: 13px;
  margin: 0 6px 6px 0;
  text-decoration: none;
  transition: transform 0.1s ease;
}
a.chip:active { transform: scale(0.95); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  border: none;
  border-radius: var(--radius);
  padding: 12px 18px;
  min-height: 46px;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  width: 100%;
  transition: transform 0.1s ease, opacity 0.1s ease;
}
.btn:active { transform: scale(0.97); opacity: 0.9; }
.btn:disabled { opacity: 0.6; cursor: default; transform: none; box-shadow: none; }
/* 「押した感」は縮小より**影が沈む**ほうが効く。浮いている物が押し込まれる感じ */
.btn-primary {
  background: var(--accent-grad);
  color: var(--accent-contrast);
  box-shadow: var(--shadow-raised);
  transition: box-shadow 0.12s ease, transform 0.1s ease;
}
.btn-primary:active { box-shadow: var(--shadow-pressed); }
.btn-primary:disabled { box-shadow: none; }
.btn-outline { background: transparent; color: var(--accent); border: 1.5px solid var(--accent); }
/* めったに押さない・押すと戻せない操作。**押しやすくしない**のが目的なので、
   アクセント色をやめて灰色にし、視線が止まらないようにする(消す/締め出す系) */
.btn-danger-quiet { color: var(--text-muted); border-color: var(--border); }
.btn-danger { background: transparent; color: #c0392f; border: 1.5px solid #c0392f; }
.btn + .btn { margin-top: 8px; }

form label,
.field-label {
  display: block;
  font-size: 13px;
  color: var(--text-muted);
  margin: 14px 0 4px;
}
/* 「使う人」の追加欄は<form>の外にあるので、下の form input のルールに拾われない。
   放っておくとブラウザ既定の高さ21px・文字13.3pxになり、そこだけ別のアプリのように
   見える(実測で発覚)。同じ見た目になるよう明示的に並べる。 */
/* **.field-input は<form>の外で使うための同義クラス**。
   オンボーディングは<form>を使っていないので、付け忘れるとラベルがinlineのまま
   入力欄と同じ行に並び、入力欄も既定の高さ21pxになる
   (「はじめに」の対象登録で実際にそうなっていた。CLAUDE.mdの罠と同じ種類)。 */
.field-input,
.user-add-name,
form input[type="text"],
form input[type="date"],
form select,
form textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  /* **16px以上にする**: iOS Safariはこれ未満の入力欄にフォーカスすると自動でズームし、
     画面が拡大したまま戻らない(ログイン欄で先に踏んだのと同じ問題) */
  font-size: 16px;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
}
form textarea { min-height: 80px; resize: vertical; }

.checkbox-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.pref-region-group {
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 8px;
  overflow: hidden;
}
.pref-region-group summary {
  padding: 10px 12px;
  font-weight: 600;
  cursor: pointer;
  background: var(--surface);
  list-style: none;
}
.pref-region-group summary::-webkit-details-marker { display: none; }
.pref-region-group summary::after { content: '▾'; float: right; color: var(--text-muted); }
.pref-region-group[open] summary::after { content: '▴'; }
.pref-region-group .checkbox-grid { padding: 10px 12px; margin: 0; }
.checkbox-chip {
  position: relative;
}
.checkbox-chip input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}
.checkbox-chip span {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  /* 44px はタップ目標の下限(2026-08-21に38pxから引き上げ)。都道府県のチップは
     47個並ぶので、小さいまま指で押すと隣を選んでしまう */
  min-height: 44px;
  border: 1.5px solid var(--border);
  border-radius: 999px;
  padding: 8px 14px;
  font-size: 14px;
  transition: transform 0.1s ease, border-color 0.1s ease, background 0.1s ease;
}
.checkbox-chip input:checked + span {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}
.checkbox-chip input:active + span { transform: scale(0.95); }
.checkbox-chip.is-hidden { display: none; }

.pref-filter-input {
  margin-bottom: 10px;
}

.quick-select-row {
  display: flex;
  /* **折り返し必須**。以前は父/母の2つ固定だったので溢れなかったが、使う人の一覧に
     使うようになり人数が増えると、横に伸びて**ページ全体が横スクロール**した
     (8人で scrollWidth 583 / clientWidth 390)。 */
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}
.quick-select-btn {
  border: 1.5px solid var(--border);
  background: var(--surface);
  border-radius: 8px;
  padding: 8px 16px;
  min-height: 44px; /* タップ目標の下限(2026-08-21に40pxから) */
  font-size: 14px;
  cursor: pointer;
  transition: transform 0.1s ease, border-color 0.1s ease;
}
.quick-select-btn:active { transform: scale(0.95); }
.quick-select-btn.selected {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}

.day-tabs-row {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  margin-top: 4px;
}
.day-tab-btn {
  flex: 0 0 auto;
  border: 1.5px solid var(--border);
  background: var(--surface);
  border-radius: 8px;
  padding: 8px 14px;
  min-height: 44px; /* タップ目標の下限(2026-08-21に40pxから) */
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 0.1s ease, border-color 0.1s ease;
}
.day-tab-btn:active { transform: scale(0.95); }
.day-tab-btn.selected {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}

.dirty-mark {
  display: none;
  margin-left: 10px;
  font-size: 12px;
  font-weight: 700;
  color: #c0392f;
  vertical-align: middle;
}

.all-photos-details > summary {
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  padding: 6px 0;
}

.text-input {
  display: block;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 15px;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
  min-height: 80px;
  resize: vertical;
}

.photo-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin: 8px 0;
}
.photo-grid img,
.photo-grid video {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 8px;
  background: var(--accent-soft);
}

/* 削除ボタン付きのタイル。指で押しやすいよう28pxを確保する */
.media-tile { position: relative; }
.media-tile-delete {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.media-tile-delete:active { transform: scale(0.9); }
.media-tile-delete:disabled { opacity: 0.5; }

/* 写真の「何日目か」。写真の上に重ねるので、読めるだけの最小限の面積にする */
.media-tile-date,
.media-tile-date-select {
  position: absolute;
  left: 4px;
  bottom: 4px;
  max-width: calc(100% - 8px);
  border: none;
  border-radius: 999px;
  padding: 3px 8px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 11px;
  line-height: 1.3;
  cursor: pointer;
}
.media-tile-date:active { transform: scale(0.95); }
.media-tile-date-select { border-radius: 8px; }
.media-tile-date-select:disabled { opacity: 0.6; }

/* 写真削除の取り消し。消したタイルの位置ではなくグリッド下に出す(3画面で共通) */
/* 称号バッジを「通り名の一覧」への入口にする。ボタンだと分からせつつ、
   見た目はバッジのままにしたいので枠も背景も持たせない */
.title-badge-button {
  display: block;
  width: 100%;
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  text-align: inherit;
}
.title-badge-button:active { transform: scale(0.97); }

/* 通り名の一覧 */
.title-list { margin-top: 12px; }
.title-list-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  margin-bottom: 10px;
}
/* **左揃え。★は先頭で縦に揃える**(実機で「マークが縦でそろってないからきもい。
   左揃えのが好み」と言われた)。バッジの形は固定幅にして、名前の長さで動かさない */
.title-list-row .title-badge-row {
  flex: 1;
  min-width: 0;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  text-align: left;
  gap: 12px;
}
.title-list-row .title-badge-shape,
.title-list-row .title-badge-shape.is-locked {
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  margin: 0;
}
.title-list-row .title-badge-label { text-align: left; flex: 1; min-width: 0; }
.title-list-note {
  margin: 0;
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap;
}
/* 未達成は伏せる。**名前は見せる**(何を目指すか分からないと意味がない) */
.title-badge-shape.is-locked {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--map-unvisited);
  color: #b9b6ae;
}
.title-badge-shape.is-locked::before { content: '★'; }
.title-list-row:not(.is-earned) .title-badge-label { color: var(--text-muted); }

/* **新しい通り名を取ったら画面を全部奪う。** 年に数回しか来ない瞬間なので遠慮しない。
   背景タップでは閉じない(見逃すのが惜しいため)。閉じ方はボタン1つ */
.title-celebration {
  position: fixed;
  inset: 0;
  z-index: 110;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: linear-gradient(160deg, #2f2f8f 0%, #5b5bd6 55%, #ff8fd6 100%);
  animation: title-celebration-in 0.3s ease;
}
.title-celebration-inner { text-align: center; color: #fff; max-width: 340px; width: 100%; }
.title-celebration-lead {
  margin: 0 0 20px;
  font-size: 17px;
  font-weight: 700;
  animation: title-celebration-rise 0.4s 0.1s ease both;
}
.title-celebration-badge { animation: title-celebration-pop 0.5s 0.25s cubic-bezier(.2,1.5,.4,1) both; }
.title-celebration-badge .title-badge-label { color: #fff; font-size: 22px; }
.title-celebration-sub {
  margin: 16px 0 0;
  font-size: 15px;
  opacity: 0.9;
  animation: title-celebration-rise 0.4s 0.6s ease both;
}
.title-celebration-close {
  margin-top: 32px;
  background: #fff;
  color: var(--accent);
  animation: title-celebration-rise 0.4s 0.8s ease both;
}
@keyframes title-celebration-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes title-celebration-rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
@keyframes title-celebration-pop {
  from { opacity: 0; transform: scale(0.4); }
  to { opacity: 1; transform: scale(1); }
}

/* 写真のスライドショー */
.slideshow {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(0, 0, 0, 0.94);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: env(safe-area-inset-top) 8px env(safe-area-inset-bottom);
}
.slideshow-media { max-width: 100%; max-height: 100%; object-fit: contain; cursor: pointer; }
.slideshow-caption {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: calc(env(safe-area-inset-bottom) + 44px);
  margin: 0;
  color: #fff;
  font-size: 14px;
  text-align: center;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);
}
.slideshow-counter {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(env(safe-area-inset-bottom) + 16px);
  margin: 0;
  color: rgba(255, 255, 255, 0.75);
  font-size: 13px;
  text-align: center;
}
.slideshow.is-paused .slideshow-counter::after { content: ' ⏸'; }
.slideshow-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 64px;
  border: none;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
}
.slideshow-nav-prev { left: 6px; }
.slideshow-nav-next { right: 6px; }

@media (prefers-reduced-motion: reduce) {
  .title-celebration,
  .title-celebration-lead,
  .title-celebration-badge,
  .title-celebration-sub,
  .title-celebration-close { animation: none; }
}

/* 写真1枚の全画面表示(LINE相当)。どこを触っても閉じる */
.media-viewer {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(0, 0, 0, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: env(safe-area-inset-top) 8px env(safe-area-inset-bottom);
  animation: media-viewer-in 0.15s ease;
}
@keyframes media-viewer-in { from { opacity: 0; } to { opacity: 1; } }
.media-viewer-media {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.media-viewer-close {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 12px);
  right: 12px;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
@media (prefers-reduced-motion: reduce) {
  .media-viewer { animation: none; }
}

.photo-undo-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 10px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text-muted);
  font-size: 14px;
}
.photo-undo-bar[hidden] { display: none; }
.photo-undo-btn {
  flex: 0 0 auto;
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 6px 14px;
  background: var(--surface);
  color: var(--accent);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.photo-undo-btn:active { transform: scale(0.97); }
.photo-undo-btn:disabled { opacity: 0.5; }

/* カード内の控えめな編集リンク。主CTAのボタンと見た目を競合させない */
.card-edit-link {
  display: block;
  width: 100%;
  margin-top: 10px;
  /* 44px はタップ目標の下限。見た目は控えめなままにしたいので、
     文字を大きくせず padding で高さを確保する(2026-08-23に31pxから) */
  min-height: 44px;
  padding: 6px 0;
  border: none;
  background: none;
  color: var(--text-muted);
  font-size: 13px;
  text-align: center;
  cursor: pointer;
}
.card-edit-link:active { opacity: 0.6; }

.photo-preview-item {
  position: relative;
}
.photo-preview-item img,
.photo-preview-item video {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 8px;
  background: var(--accent-soft);
  display: block;
}

.daily-reminder {
  margin: 6px 0 0;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
  font-size: 14px;
  display: inline-block;
}

.file-input-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
}
.photo-preview-remove {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: rgba(31, 31, 36, 0.7);
  color: #fff;
  border: none;
  font-size: 14px;
  line-height: 24px;
  text-align: center;
  cursor: pointer;
  padding: 0;
}
.photo-preview-remove:active { transform: scale(0.9); }

.form-sticky-actions {
  position: sticky;
  bottom: 0;
  background: var(--bg);
  padding: 12px 0 calc(env(safe-area-inset-bottom) + 8px);
  margin-top: 20px;
  border-top: 1px solid var(--border);
}
.form-sticky-actions .btn { margin-top: 0; }
.form-sticky-actions .btn + .btn { margin-top: 8px; }

.error-box {
  background: #fbe9e6;
  color: #c0392f;
  border-radius: 8px;
  padding: 12px 14px;
  font-size: 14px;
  margin-bottom: 12px;
}

.empty-state {
  text-align: center;
  color: var(--text-muted);
  padding: 32px 16px;
  font-size: 14px;
}

.loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 64px 0;
  color: var(--text-muted);
  font-size: 13px;
}

/* **スケルトン**。スピナーは「待たされている」しか伝えないが、こちらは
   「何が出てくるか」を先に見せるので、同じ待ち時間でも短く感じる */
.skeleton-screen { padding-top: 4px; }
.skeleton {
  background: linear-gradient(90deg, var(--surface-alt) 25%, #eceaf4 37%, var(--surface-alt) 63%);
  background-size: 400% 100%;
  border-radius: var(--radius-sm);
  animation: skeleton-sheen 1.4s ease-in-out infinite;
}
.skeleton-card {
  background: var(--surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 16px 18px;
  margin-bottom: 14px;
}
.skeleton-line { height: 12px; margin-bottom: 10px; }
.skeleton-line:last-child { margin-bottom: 0; }
.skeleton-block { height: 180px; border-radius: var(--radius); }
@keyframes skeleton-sheen {
  0%   { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}
.spinner {
  width: 30px;
  height: 30px;
  border: 3px solid var(--accent-soft);
  border-top-color: var(--accent);
  border-radius: 50%;
  margin-bottom: 10px;
  animation: spin 0.7s linear infinite;
}
@keyframes spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; }
}

/* ---- 使う人(ユーザー登録) ---- */
/* Homeの「この端末は誰?」。未選択のままでは日ごとの記録が保存できないので、
   気づかれる位置(ヒーロー直後)に出す。文字サイズは対象登録カードと揃える */
.whoami-card { text-align: left; }
/* 「＋ 自分を追加」。人の名前のボタンと同じ大きさだが、**選ぶものではない**ので
   破線と控えめな色にして、名前の並びの中で見分けが付くようにする */
.whoami-add {
  border-style: dashed;
  color: var(--text-muted);
}
/* 「旅行の記録を続ける」を押したのに使う人が未選択のとき、ここへ連れてきて光らせる */
.whoami-card.needs-attention {
  animation: whoami-flash 1.2s ease-out 2;
  border: 2px solid var(--accent);
}
@keyframes whoami-flash {
  0%, 100% { box-shadow: var(--shadow-card); }
  50% { box-shadow: 0 0 0 4px var(--accent-soft), var(--shadow-raised); }
}
.whoami-head { margin: 0; font-size: 15px; font-weight: 600; }
.whoami-sub { margin: 2px 0 10px; font-size: 12px; color: var(--text-muted); }

.user-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
}
.user-row:last-child { border-bottom: none; }
.user-row-name { flex: 1; min-width: 0; overflow-wrap: anywhere; }
/* 44px はタップ目標の下限。絵文字1つのボタンは見た目が小さくなりがちなので明示する */
.user-row-btn {
  border: none;
  background: none;
  font-size: 18px;
  min-width: 44px;
  min-height: 44px;
  cursor: pointer;
}
.user-row-btn:active { transform: scale(0.9); }

/* 呼び名の入力とアイコン選択(追加・編集・オンボーディングで共通) */
.user-add-form { margin-top: 12px; }
.user-add-name { width: 100%; }
.user-edit-buttons { display: flex; gap: 8px; margin-top: 12px; }
.user-edit-buttons .btn { flex: 1; margin-top: 0; }

/* **アイコンは選ぶ**(2026-08-21)。自由入力だと絵文字を出す手段が端末ごとに違い、
   空欄を見ても何を入れる場所か分からなかった。
   **8列→6列に減らした**(同日): 8列だと1マスが約35pxで、タップ目標の下限44pxを
   割っていた。8列のまま min-height だけ足すと縦長のマスになるので、列を減らして
   正方形のまま大きくする(17個が3行に収まる) */
.icon-picker {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 6px;
  margin-top: 4px;
  /* 横画面で1マスが104pxまで膨らんだので上限を付ける(縦画面では当たらない) */
  max-width: 360px;
}
.icon-chip {
  aspect-ratio: 1;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 20px;
  line-height: 1;
  padding: 0;
  cursor: pointer;
  transition: transform 0.1s ease, border-color 0.1s ease, background 0.1s ease;
}
.icon-chip:active { transform: scale(0.92); }
.icon-chip.selected {
  border-color: var(--accent);
  background: var(--accent-soft);
  /* 枠だけだと選択中が分かりにくいので、外側にもう1本足して確実に見せる */
  box-shadow: 0 0 0 2px var(--accent-soft);
}

/* 写真タイルの持ち主。自分の写真には出さない(✕が出ない理由の説明) */
.media-tile-owner {
  position: absolute;
  left: 4px;
  bottom: 4px;
  padding: 1px 6px;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 11px;
  line-height: 1.6;
  pointer-events: none;
}

/* 書かれた記録を読むだけのカード。旅行中画面(ほかの人の記録)と旅行詳細(日付ごと)で
   同じものを使う。**読むだけ**なので、入力欄と見た目をはっきり分ける */
.log-card {
  margin-top: 12px;
  padding: 10px 12px;
  border-left: 3px solid var(--accent-soft);
  background: var(--bg);
  border-radius: 0 8px 8px 0;
}
/* 自分の記録だけ縁を濃くする。日付ごとに何人ぶんも並ぶので、
   どれが自分のものかを色で拾えるようにする(文字は足さない) */
.log-card.is-mine { border-left-color: var(--accent); }
.log-card-who { margin: 0; font-size: 12px; color: var(--text-muted); }
.log-card-tags { margin: 4px 0 0; font-size: 13px; }
.log-card-comment { margin: 4px 0 0; font-size: 14px; overflow-wrap: anywhere; white-space: pre-wrap; }

/* 「日ごとの記録」の見出し。総括(旅行全体の感想)を出すカードのすぐ下に日付が
   続くと、どこからが「日ごと」なのか読み取れなかった(実測で73px差) */
.trip-days-title {
  margin: 28px 0 0;
  font-size: 15px;
  color: var(--text-muted);
}

/* その日をまだ書いていない人。責める見た目にはしない(薄い文字だけ) */
.trip-day-missing {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--text-muted);
  opacity: 0.75;
}

/* 旅行詳細の日付ブロック。1日ぶんの「記録＋その日の写真」をひとまとまりにする */
.trip-day-block {
  margin-top: 24px;
  padding-top: 4px;
  border-top: 1px solid var(--border);
}
.trip-day-head {
  margin: 8px 0 4px;
  font-size: 15px;
  font-weight: 600;
}
.trip-day-block .photo-grid { margin-top: 12px; }

/* 今日、誰が記録を書いたか(旅行中カード)。相手が書いたことに気づく手段がこれまで
   無く、その日のタブを開くまで分からなかった */
.today-writers {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--text-muted);
}
.today-writer { opacity: 0.55; }
.today-writer.is-written {
  opacity: 1;
  color: var(--accent);
  font-weight: 600;
}

/* 「誰として保存するか」。書く直前に出さないと、間違った人として書き続けても
   気づけない(以前は保存のたびに父/母を選んでいたので気づけた) */
.as-who {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--text-muted);
}
.as-who-change {
  border: none;
  background: none;
  padding: 6px 4px;
  font: inherit;
  font-size: 13px;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
}

/* 合言葉の入力。<form>の中なので form input のルールに拾われるが、
   type=password は別セレクタなので明示的に並べる(高さ21pxの既定に落ちるのを防ぐ) */
.login-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  /* **16px以上にする**: iOS Safariはこれ未満の入力欄にフォーカスすると自動でズームし、
     画面が拡大したまま戻らない。壁の画面でそれをやられると印象が悪い */
  font-size: 16px;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
}

/* ---- 直近の旅行を大きく見せるカード ---- */
/* 旅行アルバムなのに写真が84pxのサムネイルしか無く、それが「味気ない」の
   最大の原因だった。**写真が0枚でも成立する**ように、無いときは県名の面を出す */
.hero-trip-card {
  display: block;
  text-decoration: none;
  color: inherit;
  margin-bottom: 14px;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.hero-trip-card:active { transform: scale(0.985); box-shadow: var(--shadow-pressed); }

.hero-trip-media {
  position: relative;
  aspect-ratio: 16 / 10;
  background: var(--accent-soft);
}
.hero-trip-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* 写真が無いとき。灰色の空箱ではなく、行った県の名前を大きく置く */
.hero-trip-fallback {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px 20px 48px;
  box-sizing: border-box;
  background: var(--accent-grad);
  color: #fff;
  font-size: 24px;
  font-weight: 700;
  text-align: center;
  letter-spacing: 0.02em;
  overflow-wrap: anywhere;
}
/* 写真の上に白文字を載せるので、下半分を暗くして必ず読めるようにする */
.hero-trip-veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 45%, rgba(0, 0, 0, 0.62) 100%);
  pointer-events: none;
}
.hero-trip-body {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 14px 16px;
  color: #fff;
}
.hero-trip-title {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.3;
  overflow-wrap: anywhere;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
.hero-trip-meta {
  margin: 2px 0 0;
  font-size: 12px;
  opacity: 0.92;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
.hero-trip-count {
  position: absolute;
  top: 10px;
  right: 10px;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  font-size: 11px;
  line-height: 1.6;
}

/* その日の1枚目を2×2で大きく。1枚しか無い日には当てない(render.js側で判定) */
.photo-grid.has-feature > *:first-child {
  grid-column: span 2;
  grid-row: span 2;
}
.photo-grid.has-feature > *:first-child img,
.photo-grid.has-feature > *:first-child video {
  height: 100%;
}

/* 中身が無い画面。文字だけだと「壊れている」ようにも見えるので、絵と一言を置く */
.empty-state-rich {
  text-align: center;
  padding: 28px 20px;
  background: var(--surface-alt);
  border-radius: var(--radius);
}
.empty-state-emo { font-size: 40px; line-height: 1; }
.empty-state-head { margin: 10px 0 0; font-weight: 600; }

/* 横画面の大判カード。**このブロックはファイル末尾に置くこと** —
   .hero-trip-media の定義より前に書くと、同じ詳細度なので後勝ちで負ける
   (実際に一度それで効かなかった)。16:10のままだと横画面で高さ430pxになり、
   画面の高さ390pxに収まらない */
@media (orientation: landscape) and (max-height: 500px) {
  .hero-trip-media { aspect-ratio: 21 / 9; }
  .hero-trip-title { font-size: 18px; }
}

/* 日付欄の使い方と、選んだ日の読み返し。
   iPhoneの日付ドラムは日の列を回し忘れると今日の日付のまま確定するので、
   **選ばれた日を日本語で見せて気づけるようにする**のがこの2行の役目 */
.date-hint { margin: 4px 0 0; font-size: 12px; }
.date-echo {
  margin: 2px 0 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--accent);
  min-height: 1.6em;
}
.date-echo:empty { min-height: 0; }
