/*
 * 立替アプリ の見た目。
 *
 * 配色・角丸・文字の決めごとは Android 版 docs/UI_DESIGN.md をそのまま持ってきている。
 * 落ち着いた深緑を基調に、金額の正負が一目で分かることを両立させる。
 *
 * **色だけで情報を伝えない。** 差額には必ず符号（+ / - / ±）も併記する。
 */

:root {
  /* ── 基本色（ライト）───────────────────────────── */
  --primary: #2f6f5e;
  --on-primary: #ffffff;
  --primary-container: #cfe9e0;
  --on-primary-container: #10352b;
  --secondary: #7a5c3e;
  --secondary-container: #f0e0cd;
  --on-secondary-container: #3a2a17;
  --tertiary-container: #dfe3f2;
  --on-tertiary-container: #2a2f45;

  --background: #f7f5f2;
  --surface: #ffffff;
  --surface-variant: #eceae6;
  --surface-high: #f1efeb;
  --on-surface: #1b1c1b;
  --on-surface-variant: #4c534f;
  --outline: #d5d2cd;

  /* ── 意味色 ────────────────────────────────────
   * plus  … 多く払っている / minus … 立替えてもらっている */
  --plus: #1b6b45;
  --minus: #b3261e;
  --neutral: #4c534f;
  --error-container: #fbdad7;
  --on-error-container: #6b1610;
  --warn-container: #fdf0d5;
  --on-warn-container: #58421a;

  /* ── 角丸（UI_DESIGN.md の shapes）──────────────── */
  --r-tag: 8px;
  --r-small: 12px;
  --r-card: 16px;
  --r-dialog: 24px;
  --r-pill: 999px;

  --max-width: 760px;
  --nav-height: 60px;

  /* ── 影 ────────────────────────────────────────
   *
   * **枠線 1px だけだと、どこまでが 1 枚か分かっても「浮いている」感じが出ない。**
   * 白と緑だけの画面が平坦に見えていた原因はここ（2026-08-24）。
   * 黒ではなく**深緑を薄めた影**にする。灰色の影を白地に落とすと濁って見える。 */
  --shadow-1: 0 1px 2px rgba(16, 53, 43, 0.05), 0 2px 6px rgba(16, 53, 43, 0.05);
  --shadow-2: 0 2px 6px rgba(16, 53, 43, 0.07), 0 10px 24px rgba(16, 53, 43, 0.09);
  --shadow-3: 0 8px 20px rgba(16, 53, 43, 0.12), 0 24px 48px rgba(16, 53, 43, 0.16);

  /* ── 面のグラデーション ───────────────────────
   *
   * **色を増やさずに濃淡を足す。** 同じ緑の濃さを変えるだけなので、
   * 「白と緑が基調」は崩れない。
   *
   * **--grad-primary と --grad-hero を分けてある。理由を必ず読むこと。**
   *
   *   --grad-primary … `--primary` の濃淡。**文字は `--on-primary` を載せる。**
   *                    暗い配色では `--primary` 自体が明るい薄荷色になるので、
   *                    こちらも明るくならなければならない。
   *   --grad-hero    … 立替金額の帯だけに使う。**明暗どちらでも深緑で、文字は白。**
   *
   * 1 つにまとめていたとき、暗い配色で「登録する」ボタンが
   * **深緑の地に深緑の文字**になって読めなくなった（2026-08-24）。 */
  /* **いちばん明るい止まりでも、白い文字が読めること。**
     `#3c8471` だと白との明暗差が 4.44:1 で、4.5:1 に届いていなかった
     （2026-08-24 に tests/screens.test.cjs が見つけた）。 */
  --grad-primary: linear-gradient(135deg, #357a67 0%, #2f6f5e 55%, #245a4c 100%);
  --grad-hero: linear-gradient(135deg, #357a67 0%, #2f6f5e 55%, #245a4c 100%);
  --grad-surface: linear-gradient(180deg, #ffffff 0%, #fbfaf8 100%);
  --grad-wash:
    radial-gradient(720px 420px at 12% -8%, rgba(47, 111, 94, 0.10), transparent 62%),
    radial-gradient(560px 380px at 108% 4%, rgba(122, 92, 62, 0.07), transparent 60%);

  /* ── 動き ──────────────────────────────────────
   *
   * **速さと曲線をここだけで決める。** ばらばらだと、画面ごとに
   * 「別のアプリを触っている」感じになる。
   * prefers-reduced-motion が指定された端末では、下の方でまとめて止める。 */
  --ease: cubic-bezier(0.22, 0.9, 0.28, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-1: 0.14s;
  --dur-2: 0.24s;
  --dur-3: 0.42s;

  /* 端末のノッチ・ホームバーのぶん。viewport-fit=cover が無いと常に 0 になる。
     **固定したものと、その下敷きになる余白の両方で同じ値を使う。**
     片方に足し忘れると、最後の 1 行がホームバーに隠れて永久に読めなくなる。 */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

@media (prefers-color-scheme: dark) {
  :root {
    --primary: #7fd3bc;
    --on-primary: #063428;
    --primary-container: #1f4d41;
    --on-primary-container: #cfe9e0;
    --secondary: #e4c29b;
    --secondary-container: #4b3826;
    --on-secondary-container: #f0e0cd;
    --tertiary-container: #333a52;
    --on-tertiary-container: #dfe3f2;

    --background: #14171a;
    --surface: #1d2125;
    --surface-variant: #272c31;
    --surface-high: #232830;
    --on-surface: #e3e3e0;
    --on-surface-variant: #bfc5c1;
    --outline: #3a4046;

    --plus: #79d6a5;
    --minus: #ffb4ab;
    --neutral: #bfc5c1;
    --error-container: #5b1c17;
    --on-error-container: #ffdad6;
    --warn-container: #4a3a18;
    --on-warn-container: #f6e0b5;

    /* 暗い地では、影は「濃い黒」でしか見えない。薄い緑の影は消える */
    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.35), 0 2px 6px rgba(0, 0, 0, 0.25);
    --shadow-2: 0 2px 6px rgba(0, 0, 0, 0.4), 0 10px 24px rgba(0, 0, 0, 0.34);
    --shadow-3: 0 8px 20px rgba(0, 0, 0, 0.5), 0 24px 48px rgba(0, 0, 0, 0.45);

    /* **明るい薄荷色にする。** 上の説明のとおり、ここに載る文字は
       --on-primary（濃い緑）なので、地が暗いと読めなくなる */
    --grad-primary: linear-gradient(135deg, #9ce2cd 0%, #7fd3bc 55%, #6ac5ad 100%);
    /* 立替金額の帯だけは、明暗どちらでも深緑。文字は白で固定してある */
    --grad-hero: linear-gradient(135deg, #2a6153 0%, #1f4d41 55%, #173b33 100%);
    --grad-surface: linear-gradient(180deg, #21262b 0%, #1c2024 100%);
    --grad-wash:
      radial-gradient(720px 420px at 12% -8%, rgba(127, 211, 188, 0.08), transparent 62%),
      radial-gradient(560px 380px at 108% 4%, rgba(228, 194, 155, 0.05), transparent 60%);
  }
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--background);
  /* **薄い光のにじみを 2 つ置くだけ。** 面が一色だと、どれだけ部品を整えても
     画面全体が「紙」に見える。色は増やさず、緑と銅をごく薄く敷く。
     fixed にしてあるので、スクロールしても光の位置が動かない（酔わない） */
  background-image: var(--grad-wash);
  background-attachment: fixed;
  background-repeat: no-repeat;
  color: var(--on-surface);
  /* ホーム画面アプリ（standalone）で、行き止まりまで引っ張ると画面全体が
     ゴムのように弾む。中の一覧のスクロールと見分けが付かず、壊れて見える */
  overscroll-behavior-y: none;
  font-family: -apple-system, BlinkMacSystemFont, 'Hiragino Kaku Gothic ProN', 'Noto Sans JP',
    'Yu Gothic UI', Meiryo, sans-serif;
  font-size: 15px;
  line-height: 1.6;
  -webkit-text-size-adjust: 100%;
}

/* 金額には等幅数字を効かせる。
   プロポーショナル数字だと桁がずれ、縦に並べたときに読み比べられない */
.num,
.amount,
td.num,
th.num {
  font-feature-settings: 'tnum';
  font-variant-numeric: tabular-nums;
}

h1,
h2,
h3 {
  margin: 0;
  font-weight: 600;
}

button {
  font: inherit;
  cursor: pointer;
}

input,
select,
textarea {
  font: inherit;
  color: inherit;
  /* **16px を下回らせない。** iOS は 15px 以下の入力欄にフォーカスすると
     画面を勝手に拡大し、そのまま戻らない。body が 15px なので明示して上書きする。 */
  font-size: max(16px, 1em);
}

/* ══════════════════════════ 骨組み ══════════════════════════ */

#app {
  max-width: var(--max-width);
  margin: 0 auto;
  /* 下は「ナビの高さ + ホームバー + 余白」。ナビ側と同じ --safe-bottom を使う */
  padding: 12px 12px calc(var(--nav-height) + var(--safe-bottom) + 24px);
}

.appbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: -12px -12px 8px;
  /* standalone ではステータスバーの下に潜り込むので、その高さぶん上に足す */
  padding: calc(10px + var(--safe-top)) 16px 10px;
  /* **透けないほうを先に書く。** backdrop-filter が効かない端末では、
     下の帳簿が透けて読めなくなるより、素の下地のほうがよい */
  background: var(--background);
  border-bottom: 1px solid var(--outline);
  transition: box-shadow var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}

/* すりガラス。**対応している端末でだけ効かせる。**
   スクロールした帳簿が薄く透けて見えることで、「上に載っている帯」だと分かる */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .appbar {
    background: color-mix(in srgb, var(--background) 78%, transparent);
    -webkit-backdrop-filter: saturate(1.6) blur(14px);
    backdrop-filter: saturate(1.6) blur(14px);
  }
}

/* 少しでもスクロールしたら、帯を持ち上げる。
   **app.js が付け外しする**（IntersectionObserver。scroll を毎フレーム拾わない） */
.appbar.is-stuck {
  box-shadow: var(--shadow-1);
  border-bottom-color: transparent;
}

.appbar h1 {
  flex: 1;
  min-width: 0;
  font-size: 17px;
  /* **見出しは折り返させない。** 折り返すと帯そのものが縦に伸びて、
     sticky で居座る帯が画面の何割も占める（グループが 2 つ以上になって
     右に select が出たときに実際にそうなっていた）。あふれたら省略する */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 表示名は 30 文字まで入る。**縮められるようにして、あふれたら省略する。**
   ここが伸びると、狭い画面では見出しごと押し出される */
.appbar .who {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  color: var(--on-surface-variant);
}

/* 画面下のナビゲーション。3 枚を常設する。
 *
 * **中身（#app）と同じ最大幅に収める。** left:0/right:0 のままだと、
 * PC では中身が 760px の中央にあるのにナビだけ画面いっぱいに伸びて、
 * どこにも属していない帯に見える（実際にそう見えていた）。
 *
 * **高さは safe-area を「足した」値にする。** height を固定したまま
 * padding-bottom だけ足すと、ホームバーのぶんボタンが内側へ潰れる。 */
.nav {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  z-index: 30;
  width: min(100%, var(--max-width));
  display: flex;
  box-sizing: border-box;
  height: calc(var(--nav-height) + var(--safe-bottom));
  padding-bottom: var(--safe-bottom);
  background: var(--surface);
  border-top: 1px solid var(--outline);
  box-shadow: 0 -1px 2px rgba(16, 53, 43, 0.04), 0 -8px 24px rgba(16, 53, 43, 0.06);
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .nav {
    background: color-mix(in srgb, var(--surface) 84%, transparent);
    -webkit-backdrop-filter: saturate(1.6) blur(16px);
    backdrop-filter: saturate(1.6) blur(16px);
  }
}

.nav button {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  border: 0;
  background: none;
  color: var(--on-surface-variant);
  font-size: 12px;
  /* 押したことが指に返る。**色だけだと、押したのか外したのか分からない** */
  transition: color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}

.nav button:active {
  transform: scale(0.94);
}

.nav button .dot {
  width: 44px;
  height: 26px;
  border-radius: var(--r-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  transition:
    background var(--dur-2) var(--ease),
    color var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease);
}

/* 「選ばれている色」は緑ひとつに揃える。
   2 系統あると、どれがいま選ばれているのか読み取れなくなる */
.nav button[aria-current='page'] {
  color: var(--primary);
  font-weight: 600;
}

.nav button[aria-current='page'] .dot {
  background: var(--primary-container);
  color: var(--on-primary-container);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
}

/* **タブを変えたときだけ、選んだ印がふわっと広がる。**
   画面を描き直すたびに動かすと、ただうるさい。
   だから app.js は「画面が変わった描き直し」にだけ .view-enter を付ける
   （→ app.js の viewKey()）。 */
.nav.view-enter button[aria-current='page'] .dot {
  animation: nav-pop var(--dur-3) var(--ease-out) both;
}

@keyframes nav-pop {
  0% {
    transform: scale(0.7);
    opacity: 0.35;
  }
  60% {
    transform: scale(1.06);
    opacity: 1;
  }
  100% {
    transform: scale(1);
  }
}

/* ══════════════════════════ 部品 ══════════════════════════ */

.card {
  position: relative;
  background: var(--surface);
  background-image: var(--grad-surface);
  border: 1px solid var(--outline);
  border-radius: var(--r-card);
  padding: 14px;
  margin-bottom: 12px;
  box-shadow: var(--shadow-1);
  transition:
    box-shadow var(--dur-2) var(--ease),
    transform var(--dur-2) var(--ease),
    border-color var(--dur-2) var(--ease);
}

/* カードの見出しには細い縦棒を添える。
   カードを縦に積む画面なので、これがないと 1 枚の切れ目を目で追えない */
.card > h2 {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  margin-bottom: 10px;
  letter-spacing: 0.01em;
}

.card > h2::before {
  content: '';
  width: 3px;
  height: 14px;
  border-radius: 2px;
  /* 単色だった縦棒に濃淡を入れる。**1 本の線でも、平坦さはここから抜ける** */
  background: var(--grad-primary);
}

.hint {
  font-size: 12px;
  line-height: 1.7;
  color: var(--on-surface-variant);
  margin: 4px 0 0;
}

.field {
  margin-bottom: 14px;
}

.field > label,
.field-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 6px;
}

/* **入力欄の見た目。型を書き並べる形にしない。**
 *
 * ここは長らく text / password / number / date / month / search / select だけを
 * 並べていて、**`type="email"` が丸ごと抜けていた。**
 * ログイン画面のメールアドレス欄だけがブラウザ既定の細い箱のまま出ていて、
 * 下のパスワード欄と幅が揃っていなかった（2026-08-24 に画面を撮って気づいた）。
 *
 * だから**「押しボタン類ではない input はすべて」**と書く形に変えた。
 * 新しい型（tel・url など）を使い始めても、書き足さなくてよい。
 * 型を増やすたびに直す決まりは、必ずどこかで忘れる。 */
input:not([type='checkbox']):not([type='radio']):not([type='file']):not([type='range']):not([type='color']):not([type='button']):not([type='submit']):not([type='reset']),
select,
textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--outline);
  border-radius: var(--r-small);
  background: var(--surface);
  min-height: 44px;
  /* 縮められることを明示する。flex の中では既定が min-width:auto なので、
     中身の最小幅より小さくならず、親をはみ出す */
  min-width: 0;
  max-width: 100%;
}

/* **ファイルを選ぶ欄には、上の一括指定が掛かっていない。**
 *
 * `:not([type='file'])` で除いてあるので、`max-width` も `min-width:0` も付かない。
 * 端末が描く「参照… / 選択されていません」の固有幅がそのまま出るため、
 * **320px では枠から 9px はみ出していた**（設定 › データ の「読み込む」。
 * 2026-08-30 に screens.test.cjs が拾った。それまで撮れていなかった画面）。
 *
 * 除いてあるのは正しい。枠線や padding を自前で描くと、端末ごとに
 * 「参照」ボタンの見た目が壊れる。**要るのは、はみ出させない歯止めだけ。** */
input[type='file'] {
  max-width: 100%;
  /* flex の中に置かれたときに縮めるようにする（既定は min-width:auto） */
  min-width: 0;
}

/* **日付・月の欄は iOS だけ別扱いが要る。**
 *
 * iOS Safari は date / month を「置換要素」として扱い、値と暦アイコンぶんの
 * 固有幅を持たせる。この幅は width:100% では縮まないので、狭い画面で欄から
 * はみ出す（実際に支払日で起きた）。appearance を落とすと固有幅が外れる。
 * 見た目は自前の枠線に揃い、押したときの暦の出方は変わらない。 */
input[type='date'],
input[type='month'] {
  -webkit-appearance: none;
  appearance: none;
  /* iOS は既定で中身を中央寄せにする。枠だけ自前にすると位置が揃わない */
  text-align: left;
}

/* 暦アイコンを右端に寄せる（appearance を落とすと左に寄る端末がある） */
input[type='date']::-webkit-calendar-picker-indicator,
input[type='month']::-webkit-calendar-picker-indicator {
  margin-left: auto;
}

input:focus-visible,
select:focus-visible,
button:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

input.amount-input {
  font-size: 24px;
  font-weight: 600;
  text-align: right;
  padding: 8px 12px;
}

.row {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}

/* **flex の子は既定で min-width:auto。** 中身の最小幅より小さくならないので、
   何も言わないと狭い画面で親をはみ出す。縮んでよいものは全部ここで許す */
.row > * {
  min-width: 0;
}

.grow {
  flex: 1;
  min-width: 0;
}

/* 実支払の行に並ぶ名前。**幅を固定しない。**
   width:96px + flex:none だと、長い名前がそのまま欄の外へ出る */
.paid-name {
  flex: 0 1 96px;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* 利用者が入れた文字が入る場所は、切れ目の無い長い文字列でも折り返す。
   備考は 200 文字まで入るので、URL のような文字列が来ると横に溢れる */
.hint,
.notice,
.empty,
.acc-title {
  overflow-wrap: anywhere;
}

/* ボタン。
 *
 * **display を必ず自分で決める。**
 * `<button>` の既定は inline-block なので padding も min-height も効くが、
 * `<a>` の既定は **inline**。inline では min-height が無視され、上下の padding が
 * 行の高さを押し広げないまま外へ膨らむので、**前後の文にボタンの下地が重なる**。
 * 書き出しの `<a class="btn">` で実際にそうなっていた（スマホで顕著）。
 *
 * inline-flex にすると、a でも button でも同じ箱になり、中身も中央にそろう。 */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid transparent;
  border-radius: var(--r-small);
  padding: 10px 16px;
  min-height: 44px;
  background: var(--surface-variant);
  color: var(--on-surface);
  /* a には button の font: inherit が効かない。下線も消す */
  font: inherit;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition:
    transform var(--dur-1) var(--ease),
    box-shadow var(--dur-2) var(--ease),
    background var(--dur-2) var(--ease),
    filter var(--dur-1) var(--ease);
}

/* **押した手応えを返す。** 見た目が何も変わらないと、
   通信の間に「効いていないのでは」と二度押しされる */
.btn:not(:disabled):active {
  transform: scale(0.97);
}

.btn.primary {
  background: var(--primary);
  /* 主要なボタンだけ濃淡を持つ。**画面の中で押すべき場所が 1 つに決まる** */
  background-image: var(--grad-primary);
  color: var(--on-primary);
  font-weight: 600;
  box-shadow: var(--shadow-1);
}

.btn.primary:not(:disabled):active {
  box-shadow: none;
}

.btn.outline {
  background: transparent;
  border-color: var(--outline);
}

.btn.text {
  background: none;
  padding: 8px 10px;
  color: var(--primary);
}

.btn.danger {
  background: transparent;
  border-color: var(--minus);
  color: var(--minus);
}

/* 「押せば済む近道」は銅で目立たせる（実支払のクイックボタン） */
.btn.quick {
  background: var(--secondary-container);
  color: var(--on-secondary-container);
  border-radius: 999px;
  padding: 8px 14px;
  min-height: 40px;
  font-size: 13px;
}

.btn.block {
  width: 100%;
}

.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* チップ（項目・種別） */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* 項目を選ぶチップ。いまは <button> なので既定の inline-block で箱になるが、
   display は自分で決めておく（.btn と同じ理由。要素が変わっても崩れない） */
.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border: 1px solid var(--outline);
  background: var(--surface);
  border-radius: var(--r-small);
  padding: 8px 14px;
  /* 押せるものは 44px 以上。入力画面でいちばんよく押す場所なので、ここを削らない */
  min-height: 44px;
  font-size: 14px;
}

.chip[aria-pressed='true'] {
  background: var(--primary-container);
  color: var(--on-primary-container);
  border-color: transparent;
  font-weight: 600;
}

/* 種別切替（セグメンテッドボタン） */
.segmented {
  display: flex;
  border: 1px solid var(--outline);
  border-radius: var(--r-small);
  overflow: hidden;
}

.segmented button {
  flex: 1;
  border: 0;
  background: var(--surface);
  padding: 10px;
  min-height: 44px;
}

.segmented button[aria-pressed='true'] {
  background: var(--primary-container);
  color: var(--on-primary-container);
  font-weight: 600;
}

/* **編集中に押せないほうの種別。**
   支出を直しているつもりで精算として更新されると、その 1 件は出費の合計から
   抜けて立替金額だけが動く。別物に化けたことに気づけないので、切り替えを塞ぐ。
   色は変えず、薄くするだけにする（新しい配色を足すと、暗い側の明暗差を
   もう一度確かめることになる） */
.segmented button:disabled {
  opacity: 0.45;
  cursor: default;
}

/* タグ。下地は種類ごとに変える。同じ色だと並んだとき区別が付かない */
.tag {
  display: inline-block;
  border-radius: var(--r-tag);
  padding: 1px 7px;
  font-size: 11px;
  line-height: 1.7;
  white-space: nowrap;
  background: var(--surface-variant);
  color: var(--on-surface-variant);
}

.tag.fixed {
  background: var(--secondary-container);
  color: var(--on-secondary-container);
}

.tag.settlement {
  background: var(--tertiary-container);
  color: var(--on-tertiary-container);
}

.tag.editing {
  background: var(--primary-container);
  color: var(--on-primary-container);
}

/* 参考 / ◯月分 は枠線のみ */
.tag.ref {
  background: transparent;
  border: 1px solid var(--outline);
  color: var(--on-surface-variant);
}

/* 注意帯 */
.notice {
  border-radius: var(--r-small);
  padding: 10px 12px;
  font-size: 13px;
  line-height: 1.7;
  margin-bottom: 12px;
}

.notice.warn {
  background: var(--warn-container);
  color: var(--on-warn-container);
}

.notice.error {
  background: var(--error-container);
  color: var(--on-error-container);
}

.notice.info {
  background: var(--surface-variant);
  color: var(--on-surface-variant);
}

/* 「金額とぴったり合っています」の帯。
   **色は .notice.info と同じにして、左の印だけ変える。**
   前景色と背景色の組を増やすと、暗い配色での明暗差をもう一度確かめることになる */
.notice.ok {
  background: var(--surface-variant);
  color: var(--on-surface-variant);
  border-left: 3px solid var(--plus);
}

/* ══════════════════════════ 入力の 3 段 ══════════════════════════ */

/* **いま何段目か。押して戻れる。**
 *
 * 支出の入力は「金額 → だれの分 → 確認」の 3 段に分けてある。
 * 1 枚に全部あった頃は、負担すべき額（個別金額）と実際に出した額（実支払金額）が
 * 同じ枠に並んでいて、**意味がまるで違うのに見た目で区別できなかった。** */
.stepbar {
  display: flex;
  gap: 6px;
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
}

.stepbar-item {
  flex: 1 1 0;
  min-width: 0;
}

.stepbar-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  min-height: 40px;
  padding: 6px 4px;
  border: 1px solid var(--outline);
  border-radius: var(--r-small);
  background: var(--surface);
  color: var(--on-surface-variant);
  font-size: 11px;
}

/* まだ進んでいない段。**押せないことを、見た目でも示す** */
.stepbar-btn:disabled {
  opacity: 0.55;
  cursor: default;
}

/* いま居る段 */
.stepbar-btn[aria-current='step'] {
  background: var(--primary);
  color: var(--on-primary);
  border-color: var(--primary);
  font-weight: 600;
}

.stepbar-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 18px;
  height: 18px;
  border-radius: 999px;
  background: var(--surface-variant);
  color: var(--on-surface-variant);
  font-size: 11px;
  font-weight: 700;
}

.stepbar-btn[aria-current='step'] .stepbar-num {
  background: var(--on-primary);
  color: var(--primary);
}

/* 320px では段の名前が入りきらない。**あふれたら省略する**（数字は必ず残る） */
.stepbar-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* その段で何を聞かれているのか。**画面のいちばん上の問いかけ** */
.card > h2.step-title {
  align-items: flex-start;
  font-size: 15px;
  line-height: 1.6;
  margin-bottom: 14px;
}

/* 2 行に折り返す見出しなので、添える縦棒は 1 行目の高さに合わせる */
.card > h2.step-title::before {
  margin-top: 4px;
}

/* 段の中の、1 つの問い。**枠で囲って、聞かれていることを 1 つに絞る** */
.step-box {
  border: 1px solid var(--outline);
  border-radius: var(--r-small);
  padding: 12px;
  margin-bottom: 12px;
}

.step-box > h3 {
  font-size: 14px;
  margin-bottom: 4px;
}

/* 「この支払は、誰の分ですか？」のチェック。
   **人数が増えても縦に伸びきらないよう、横に並べて折り返す** */
.split-targets {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 14px;
}

.split-target {
  flex: 0 1 auto;
  min-width: 0;
}

/* 個別に設定していないときに出す、いまの按分の要約 */
.split-current {
  font-size: 13px;
  line-height: 1.7;
  margin: 0 0 10px;
  overflow-wrap: anywhere;
}

/* 金額の正負 */
.plus {
  color: var(--plus);
}

.minus {
  color: var(--minus);
}

.zero {
  color: var(--neutral);
}

/* スイッチ */
.switch {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  cursor: pointer;
}

.switch input {
  width: 20px;
  height: 20px;
  accent-color: var(--primary);
}

/* 横スクロールする場所。メンバーが増えると帯も表も画面幅に収まらない */
.scroll-x {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* ══════════════════════════ 立替金額の帯 ══════════════════════════ */

/* **この帯がこのアプリの主役。**
 * 「いくら立て替えているか」を見に来る人がほとんどなので、
 * ここだけは色の面にして、ひと目で視線が止まるようにする。
 * 中の数字は白抜きになるので、色は必ず --on-primary 側で書くこと。 */
.balance-bar {
  position: relative;
  overflow: hidden;
  background: #2f6f5e;
  background-image: var(--grad-hero);
  /* **白で固定する。** 中の意味色（明るい薄荷・薄い桃）も白地の上を前提に選んである。
     --on-primary を使うと、暗い配色のとき深緑の地に深緑の文字になる */
  color: #ffffff;
  border: 0;
  border-radius: var(--r-card);
  padding: 14px;
  margin-bottom: 12px;
  box-shadow: var(--shadow-2);
}

/* 斜めの光。**面が一色だと、大きいぶんかえって平坦に見える** */
.balance-bar::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(115deg, rgba(255, 255, 255, 0.16) 0%, rgba(255, 255, 255, 0) 46%);
}

.balance-bar .head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}

.balance-bar .head h2 {
  font-size: 13px;
  letter-spacing: 0.04em;
}

.balance-bar .head .as-of {
  font-size: 11px;
  /* **薄くしすぎない。** 0.72 だと白い文字と緑の地の明暗差が 3.1:1 しかなく、
     11px の文字には足りない（4.5:1 要る）。0.9 でも 4.47:1 で届かなかった */
  color: rgba(255, 255, 255, 0.95);
}

.balance-cards {
  display: flex;
  gap: 8px;
  position: relative;
}

/* 緑の面の上に置くので、**下地は「暗くする」透かし**にする。
 *
 * --surface-variant のままだと色の上で濁って読めない。
 * かといって**白の透かしにすると、地が明るくなって白い文字が読めなくなる**
 * （実際に 2.7:1 まで落ちていた。2026-08-24）。
 * 黒の透かしなら、緑の色みを保ったまま白い文字との差が開く。 */
.balance-cards .who {
  flex: 1 0 auto;
  min-width: 118px;
  background: rgba(0, 0, 0, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--r-small);
  padding: 8px 10px;
}

.balance-cards .who .name {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.92);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.balance-cards .who .value {
  font-size: 19px;
  font-weight: 700;
}

/* **緑の上では、意味色をそのまま使えない。**
 * --plus（濃緑）は地に沈み、--minus（濃赤）も暗くて読めない。
 * 明るい側の色に置き換える。**符号は文字として必ず出ている**ので、
 * 色が読み取れなくても意味は伝わる（→ style.css の頭の決めごと）。 */
.balance-bar .plus {
  color: #a9ecc9;
}

.balance-bar .minus {
  color: #ffc7c0;
}

.balance-bar .zero {
  color: rgba(255, 255, 255, 0.86);
}

/* **緑の地の上に、暖色の文字は載せられない。**
 * どれだけ明るくしても 12px で 4.5:1 に届かなかった（いちばん明るくて 4.3:1）。
 * だから**この一言だけ、暗い帯を敷いて、その上に載せる。**
 * 色を薄めて妥協するのではなく、載せる場所のほうを変える。 */
.balance-bar .unrecorded {
  margin: 10px 0 0;
  padding: 8px 10px;
  border-radius: var(--r-small);
  background: rgba(0, 0, 0, 0.24);
  font-size: 12px;
  line-height: 1.6;
  color: #ffd9b0;
}

/* ══════════════════════════ 表 ══════════════════════════ */

table.member-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

table.member-table th,
table.member-table td {
  padding: 6px 8px;
  text-align: right;
  white-space: nowrap;
}

table.member-table th:first-child,
table.member-table td:first-child {
  text-align: left;
  position: sticky;
  left: 0;
  background: var(--surface);
}

table.member-table thead th {
  font-size: 12px;
  color: var(--on-surface-variant);
  font-weight: 600;
  border-bottom: 1px solid var(--outline);
}

/* 1 行おきに下地を敷く。推移は 14 行並ぶので、これがないと隣の月の数字を読む */
table.member-table tbody tr:nth-child(odd) td {
  background: var(--surface-high);
}

table.member-table tbody tr:nth-child(odd) td:first-child {
  background: var(--surface-high);
}

table.member-table tfoot td {
  border-top: 1px solid var(--outline);
  font-weight: 600;
}

/* ══════════════════════════ 明細 ══════════════════════════ */

.entry-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.entry {
  border: 1px solid var(--outline);
  border-radius: var(--r-small);
  background: var(--surface);
  overflow: hidden;
}

/* 総差額 ≠ 0 の行は左端に赤い縦線（Web 版の .bad に相当） */
.entry.bad {
  border-left: 3px solid var(--minus);
}

.entry.is-settlement {
  background: var(--surface-variant);
}

.entry > .summary {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  border: 0;
  background: none;
  text-align: left;
  padding: 10px 12px;
  min-height: 48px;
}

.entry .date {
  font-size: 12px;
  color: var(--on-surface-variant);
  width: 40px;
  flex: none;
}

.entry .title {
  flex: 1;
  min-width: 0;
}

.entry .title .name {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 14px;
}

.entry .title .note {
  font-size: 12px;
  color: var(--on-surface-variant);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.entry .money {
  font-weight: 600;
  white-space: nowrap;
}

.entry .detail {
  border-top: 1px solid var(--outline);
  padding: 10px 12px;
}

.entry .detail .parts {
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
  font-size: 12px;
  color: var(--on-surface-variant);
}

.entry .detail .parts li {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 0;
}

/* ══════════════════════════ 項目別の出費（横棒） ══════════════════════════ */

.bars {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.bars .bar-row {
  display: grid;
  /* 項目名 / 金額 / 割合。**棒は 3 列ぶんをまたぐ** */
  grid-template-columns: 1fr auto auto;
  gap: 2px 8px;
  font-size: 13px;
}

/* 割合。**桁が変わっても右端がそろうように幅を決めておく**（100% まで） */
.bars .pct {
  min-width: 3.4em;
  color: var(--on-surface-variant);
}

/* **何を 100% としているかを、その場に置く。**
   合計が見えないと、上の % が何に対するものか分からない */
.bar-total {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--outline);
  font-size: 13px;
  font-weight: 600;
}

.bar-total .pct {
  min-width: 3.4em;
  color: var(--on-surface-variant);
}

.bars .track {
  grid-column: 1 / -1;
  height: 8px;
  border-radius: 4px;
  background: var(--surface-variant);
  overflow: hidden;
}

.bars .fill {
  /* **display を書かないと棒が出ない。**
     span はインライン要素で、インラインには width も height も効かない。
     app.js の widthFill() が幅を入れても、block にしていなければ何も見えないまま。
     （2026-08-23 に画面を撮って気づいた。**野辺専用版にも同じ問題がある**） */
  display: block;
  height: 100%;
  background: var(--primary);
  border-radius: 4px;
}

/* ══════════════════════════ ダイアログ ══════════════════════════ */

dialog {
  border: 0;
  border-radius: var(--r-dialog);
  padding: 0;
  width: min(440px, calc(100vw - 32px));
  background: var(--surface);
  color: var(--on-surface);
}

dialog::backdrop {
  background: rgba(0, 0, 0, 0.45);
}

dialog .dialog-body {
  padding: 20px;
}

dialog h2 {
  font-size: 16px;
  margin-bottom: 10px;
}

/* 確認ダイアログの本文は縦スクロールさせる。
   長い確認文が小さい画面で末尾が切れると、同意すべき内容が読めない */
dialog .scroll {
  max-height: min(46vh, 380px);
  overflow-y: auto;
  font-size: 13px;
  line-height: 1.8;
  white-space: pre-wrap;
}

/* 中身が多いダイアログ用（招待の結果など）。**QR を出すと 46vh では窮屈** */
dialog .scroll.tall {
  max-height: min(64vh, 560px);
}

dialog .actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 16px;
}

/* ══════════════════════════ 通知 ══════════════════════════ */

.snackbar {
  position: fixed;
  left: 50%;
  bottom: calc(var(--nav-height) + 16px);
  transform: translateX(-50%);
  z-index: 40;
  max-width: calc(100vw - 32px);
  padding: 12px 16px;
  border-radius: var(--r-small);
  background: var(--on-surface);
  color: var(--surface);
  font-size: 13px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
}

.snackbar.error {
  background: var(--minus);
  color: #fff;
}

/* ══════════════════════════ ログイン ══════════════════════════ */

.auth {
  max-width: 380px;
  margin: 48px auto;
  padding: 0 16px;
}

.auth h1 {
  font-size: 20px;
  margin-bottom: 4px;
}

/* ══════════════════════════ はじめての案内 ══════════════════════════ */

.guide-card {
  background: var(--surface);
  border: 1px solid var(--outline);
  border-radius: var(--r-card);
  padding: 12px 14px;
  margin-bottom: 12px;
}

.guide-card .head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.guide-card .dots {
  display: flex;
  gap: 6px;
  flex: 1;
  align-items: center;
}

.guide-card .dots i {
  width: 6px;
  height: 6px;
  border-radius: 3px;
  background: var(--surface-variant);
}

.guide-card .dots i.done {
  background: var(--primary);
}

.guide-card .dots i.now {
  width: 16px;
}

.guide-card .step-no {
  font-size: 12px;
  color: var(--on-surface-variant);
}

.guide-card .close {
  border: 0;
  background: none;
  color: var(--on-surface-variant);
  font-size: 18px;
  line-height: 1;
  padding: 6px 8px;
}

.guide-card h3 {
  font-size: 15px;
  margin-bottom: 4px;
}

/* ══════════════════════════ 設定 ══════════════════════════ */

.menu {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.menu button {
  display: block;
  width: 100%;
  text-align: left;
  border: 1px solid var(--outline);
  border-radius: var(--r-card);
  background: var(--surface);
  padding: 14px;
  min-height: 60px;
}

.menu button .label {
  font-weight: 600;
  font-size: 15px;
}

.menu button .summary {
  display: block;
  font-size: 12px;
  color: var(--on-surface-variant);
}

/* メンバーの合計と保存は画面下に固定する。
   100 人ぶん送ってから保存ボタンを探すことにならないように */
.sticky-actions {
  position: sticky;
  bottom: calc(var(--nav-height) + 8px);
  z-index: 10;
  background: var(--surface);
  border: 1px solid var(--outline);
  border-radius: var(--r-card);
  padding: 10px 12px;
  margin-top: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.member-row {
  border: 1px solid var(--outline);
  border-radius: var(--r-small);
  padding: 10px;
  margin-bottom: 8px;
}

.member-row .top {
  display: flex;
  gap: 8px;
  align-items: center;
}

/* 名前の欄。**ここを主役にする。**
   狭い画面で潰れると、左に何を入れる欄なのかが読めなくなる */
.member-row .top .grow {
  flex: 1 1 auto;
  min-width: 0;
}

/* 按分率の欄。**設定のメンバー画面と、入力画面の按分の枠で共に使う。**
 *
 * **`width` だけで細くしようとすると効かない。**
 * 上の `input:not([type='checkbox'])…` は :not() を 8 つ並べているので
 * 詳細度が (0,8,1) あり、`.percent`（0,1,0）の `width` を食う。
 * 結果 `width:100%` のまま `flex:none`（basis:auto → その 100%・縮まない）になり、
 * **率の欄だけが行いっぱいに膨らんで枠からはみ出し、左の名前が 0 まで潰れていた。**
 *
 * だから幅は `flex-basis` で持たせる。basis は width より先に効くので、
 * 上の一括指定に負けない。詳細度の勝ち負けを持ち込まない形にしておく。
 *
 * **メンバー画面の中に閉じ込めない。** 閉じ込めていたせいで、入力画面に
 * 同じ欄を足したときに同じ罠を踏み直すところだった。 */
.percent {
  flex: 0 0 68px;
  width: 68px;
  padding-left: 8px;
  padding-right: 8px;
}

/* 数値欄の上下ボタン。**指では押せない大きさなのに、内側の幅を食う。**
   欄を細くしたので消す（キーボードの上下キーは効いたまま） */
.percent::-webkit-outer-spin-button,
.percent::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* 欄に添える単位（%）。欄と一緒に縮ませない */
.unit {
  flex: none;
  color: var(--neutral);
}

/* 切り上げの行。**スマホで 3 行に折り返していた。**
   文言を短くしたうえで、折り返させずに 1 行へ収める */
.member-row .bottom {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: nowrap;
  margin-top: 6px;
}

.member-row .bottom .switch {
  flex: 1 1 auto;
  min-width: 0;
  gap: 8px;
}

.member-row .bottom .switch span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.member-row .bottom .btn {
  flex: none;
  white-space: nowrap;
  padding-left: 8px;
  padding-right: 8px;
}

dl.terms {
  margin: 0;
}

dl.terms dt {
  font-weight: 600;
  font-size: 14px;
  margin-top: 12px;
}

dl.terms dd {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--on-surface-variant);
  line-height: 1.8;
}

.muted {
  color: var(--on-surface-variant);
}

.empty {
  padding: 24px 8px;
  text-align: center;
  color: var(--on-surface-variant);
  font-size: 13px;
}

.hidden {
  display: none !important;
}

/* ══════════════════════════ 年月アコーディオン ══════════════════════════
 *
 * 全期間だと明細は 1,681 件ある。そのまま並べると縦に数万 px になり、
 * スクロールバーが用をなさない。年 → 月の 2 段に畳む。**3 段にはしない。**
 *
 * 素の <details>/<summary> を使う。開閉・キーボード操作・ブラウザ内検索が
 * 最初から効くので、div と onclick で作り直す理由がない。 */

.acc {
  border: 1px solid var(--outline);
  border-radius: var(--r-small);
  background: var(--surface);
  margin-bottom: 8px;
  overflow: hidden;
}

.acc > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  min-height: 44px;
  box-sizing: border-box;
  cursor: pointer;
  list-style: none;
  background: var(--surface-high);
  font-weight: 600;
}

/* 既定の三角を消して、自前の印に置き換える（向きを自分で決めるため） */
.acc > summary::-webkit-details-marker {
  display: none;
}

.acc > summary::before {
  content: '▸';
  color: var(--on-surface-variant);
  font-size: 12px;
  transition: transform 0.12s ease;
}

.acc[open] > summary::before {
  transform: rotate(90deg);
}

.acc > summary:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}

/* 見出しに要約を出す。**開かなくても分かることが増えるほど、開く回数が減る** */
.acc-title {
  flex: 1;
  min-width: 0;
}

.acc-meta {
  font-size: 12px;
  font-weight: 400;
  color: var(--on-surface-variant);
  white-space: nowrap;
}

.acc-body {
  padding: 4px 8px 8px;
}

/* 年の中に入る月は、一段内側に見せる */
.acc .acc {
  margin: 6px 0;
  background: var(--background);
}

.acc .acc > summary {
  background: transparent;
  font-weight: 500;
}

.acc-tools {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-bottom: 8px;
}

/* ══════════════════════════ 画面の幅で変える ══════════════════════════
 *
 * **スマホを既定にして、広い方へ足す。** 分岐は 3 つまで。
 * 4 つ目が要ると感じたら、それは分岐ではなく組み方の問題。 */

/* ── タブレット以上 ───────────────────────────────── */
@media (min-width: 768px) {
  #app {
    padding: 16px 16px calc(var(--nav-height) + var(--safe-bottom) + 32px);
  }

  .appbar {
    margin: -16px -16px 12px;
  }

  /* 中身と同じ幅に収まるので、両脇に境目を出して「面」であることを示す */
  .nav {
    border-left: 1px solid var(--outline);
    border-right: 1px solid var(--outline);
    border-top-left-radius: var(--r-card);
    border-top-right-radius: var(--r-card);
  }

  /* 立替金額のカードは 2 枚並ぶ。1 列のままだと間延びする */
  .balance-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 12px;
  }
}

/* ── PC ───────────────────────────────────────────── */
@media (min-width: 1024px) {
  /* 押せる場所にカーソルを乗せたことが分かるように。
     タッチ端末では :hover が張り付くので、ここでだけ効かせる */
  .btn:hover,
  .chip:hover,
  .acc > summary:hover {
    filter: brightness(0.97);
  }

  .entry:hover {
    background: var(--surface-high);
  }
}

/* ── 動きを減らす設定を尊重する ────────────────────── */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── 印刷 ─────────────────────────────────────────── */
@media print {
  .nav,
  .appbar,
  .snackbar,
  .acc-tools {
    display: none !important;
  }

  #app {
    max-width: none;
    padding: 0;
  }

  /* 畳んであっても紙には全部出す */
  .acc-body {
    display: block !important;
  }
}

/* ══════════════════════════ 一般公開版で足したもの ══════════════════════════
 *
 * **ここから下は野辺専用版に無い。**
 *
 * ── 余白の小さなクラスについて ──────────────────────────────
 *
 * 野辺専用版は style="margin-top:8px" のような属性を約 40 か所で使っていて、
 * そのために CSP の style-src に 'unsafe-inline' を許していた（積み残し B-1）。
 *
 * **一般公開版は最初からクラスで書く。**
 * `style-src 'self'` だけで通るので、万一どこかに文字列を流し込まれても、
 * そこから見た目を書き換えられない。
 *
 * **新しく画面を書くときも、style 属性を使わないこと。**
 * 唯一の例外は棒グラフの幅で、そこは app.js の widthFill() が CSSOM で入れている
 * （CSSOM への書き込みは CSP の対象外）。
 */

/* ── 余白 ─────────────────────────────────────────── */
.mt-6 { margin-top: 6px; }
.mt-8 { margin-top: 8px; }
.mt-10 { margin-top: 10px; }
.mb-6 { margin-bottom: 6px; }
.mb-8 { margin-bottom: 8px; }
.mb-10 { margin-bottom: 10px; }
.mb-14 { margin-bottom: 14px; }
.gap-top { margin-top: 10px; }

/* 「この月の入力はまだありません」のような、囲みの中の 1 行 */
.tight { margin: 0 0 10px; }

/* ── 幅と揃え ───────────────────────────────────────── */
/* 幅を決め打ちする欄。
 *
 * **`width` だけでは効かない。** 上の `input:not([type='checkbox'])…` は
 * :not() を 8 つ並べていて詳細度が (0,8,1) あるので、クラス 1 つ（0,1,0）の
 * `width` を食って `width:100%` のままにする。
 * `.row`（flex）の中では basis も 100% になり、**欄だけで 1 行を占めて折り返す。**
 * 実際に「この明細だけの按分」と「内訳」の行が 2〜3 行に割れていた。
 *
 * そこで `flex-basis` でも幅を持たせる。basis は width より先に効くので
 * 一括指定に負けず、flex でない親では黙って無視される。 */
.right { text-align: right; }
.w-110 { flex: 0 1 110px; width: 110px; }
.w-120 { flex: 0 1 120px; width: 120px; }

/* 立替金額のように、1 つだけ大きく見せる数字 */
.big-figure {
  font-size: 26px;
  font-weight: 700;
  margin: 6px 0 12px;
}

/* ── 文字づかい ─────────────────────────────────────── */

/* メールアドレス・招待の URL・合言葉。**等幅で出す**（似た文字を見分けるため） */
.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
}

/* 長い URL を折り返す。はみ出して横スクロールが出ないように */
.break {
  word-break: break-all;
  line-height: 1.5;
}

.strong {
  font-weight: 600;
}

/* 行の左に置く見出し。「メールアドレス」など */
.label-inline {
  color: var(--on-surface-variant);
  font-size: 13px;
  min-width: 8em;
}

/* ── ログイン・登録の画面 ───────────────────────────────── */

.auth .lead {
  color: var(--on-surface-variant);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 16px;
}

.auth-links {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin-top: 16px;
}

.hint-list {
  color: var(--on-surface-variant);
  font-size: 13px;
  line-height: 1.7;
  margin: 12px 0 0;
  padding-left: 1.2em;
}

/* ── グループの切り替え（上の帯） ─────────────────────────── */

/* 見出し（表示中のグループ）とプルダウンの 2 段組み。**幅の上限はここで決める。**
 *
 * **共通の入力欄の決まり（width:100%）を、この囲みで受け止める。**
 * select は上の「入力欄の見た目」で width:100% を持たされている。帯は flex なので、
 * 囲み無しで直に置くと「残りぜんぶ寄こせ」になり、見出しが 0px まで潰れて
 * 縦に折り返し、帯の高さが 300px 近くまで伸びていた
 * （グループを 2 つめに作った瞬間に起きる）。
 *
 * **幅の上限は vw ではなく % で決める。** 中身は 760px で頭打ちなのに 40vw は
 * 画面幅に付いていくので、PC では上限が効かないのと同じだった。 */
.group-field {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 0 1 auto;
  min-width: 0;
  max-width: min(45%, 200px);
  cursor: pointer;
}

.group-field-label {
  font-size: 11px;
  line-height: 1.2;
  color: var(--on-surface-variant);
  /* 文言は固定なので、折り返させず、狭ければ省略する（帯を縦に伸ばさない） */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.group-switch {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  /* 指で押す。戻るボタン（.btn）と同じ高さに揃える */
  min-height: 44px;
  /* **16px を下回らせない。** 下回ると iOS が focus のたびに画面を拡大する
     （→ 入力欄の共通の決まりと同じ理由）。名前が長ければ幅の上限側で省略される */
  font-size: 16px;
  padding: 4px 8px;
  border: 1px solid var(--outline);
  border-radius: 8px;
  background: var(--surface);
  color: var(--on-surface);
}

/* 横幅に余裕があるなら、見出しはプルダウンの左に置く。
 * 2 段組みのままだと帯だけが 15px 高くなり、そのぶん帳簿が下へ押される。
 *
 * **分岐の位置は上の「画面の幅で変える」と同じ 768px。** 新しい分岐ではない。
 * 上の塊に書くと、この下の `.group-field` に後から上書きされて効かないので、
 * 打ち消す相手のすぐ後ろに置いている（同じ強さなら後に書いた方が勝つ）。 */
@media (min-width: 768px) {
  .group-field {
    flex-direction: row;
    align-items: center;
    gap: 8px;
    max-width: min(55%, 330px);
  }

  .group-field-label {
    flex: 0 0 auto;
    font-size: 12px;
  }

  .group-field .group-switch {
    flex: 1 1 auto;
    width: auto;
  }
}

/* ── 一覧の行（参加している人・招待） ───────────────────────── */

.list-row {
  align-items: flex-start;
  padding: 10px 0;
  border-bottom: 1px solid var(--outline);
}

.list-row:last-child {
  border-bottom: 0;
}

/* ── 招待の QR コード ─────────────────────────────────── */

/* **白地に黒のまま置く。** 中身（svg）が白い下地を持っているので、
   ダークモードでも反転しない。反転するとカメラが読めない。
   周りに白い枠を少し足して、暗い地に置いても切れて見えないようにする */
.qr-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin: 12px 0;
}

.qr {
  /* **小さくしすぎない。** 1 マスが 4px を切るとカメラが拾いにくくなる。
     220px なら型番 7（45 マス）でも 1 マス 4.8px */
  width: min(220px, 70%);
  height: auto;
  border-radius: 8px;
  /* 白地が背景と地続きに見えないように */
  border: 1px solid var(--outline);
}

/* 行の右端に並ぶボタン。**狭い画面では折り返して縦に積む。**
   「参加者にする」と「外す」が横に並ぶと、320px では名前の欄が潰れる */
.row-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 4px;
  flex: 0 1 auto;
  min-width: 0;
}

.list-row .sub {
  color: var(--on-surface-variant);
  font-size: 12px;
  line-height: 1.6;
  margin-top: 2px;
}

/* ── 取り返しのつかない操作をまとめた囲み ───────────────────── */

.danger-card {
  border-color: var(--minus);
}

.danger-card h2 {
  color: var(--minus);
}

.btn.text.danger {
  color: var(--minus);
}

/* 参加している人・招待の一覧を入れる箱。行の区切りは .list-row が持つ */
.list {
  margin-top: 8px;
}

/* ══════════════════════════ 利用規約・プライバシーポリシー ══════════════════════════
 *
 * **ログインしていなくても読めなければならない。**（登録する前に読むもの）
 * そのため terms.html / privacy.html は JavaScript を使わない静的なページにしてある。
 * ここはその 2 枚のためだけのまとまり。
 */

.doc {
  max-width: 720px;
  margin: 0 auto;
  padding: 24px 16px calc(48px + var(--safe-bottom));
  line-height: 1.8;
}

.doc h1 {
  font-size: 22px;
  margin: 8px 0 4px;
}

.doc h2 {
  font-size: 16px;
  margin: 28px 0 8px;
  padding-top: 16px;
  border-top: 1px solid var(--outline);
}

.doc p,
.doc ul {
  margin: 8px 0;
}

.doc ul {
  padding-left: 1.4em;
}

.doc li {
  margin: 4px 0;
}

.doc code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  background: var(--surface-variant);
  border-radius: 4px;
  padding: 1px 4px;
}

/* 目立たせたい段落。免責や保持期間など、読み飛ばされると困るところ */
.doc-lead {
  background: var(--surface-high);
  border-left: 3px solid var(--outline);
  border-radius: 0 var(--r-small) var(--r-small) 0;
  padding: 10px 12px;
}

.doc-meta,
.doc-note {
  color: var(--on-surface-variant);
  font-size: 13px;
}

.doc-back {
  margin: 16px 0;
}

/* 表。**狭い画面でははみ出すので、囲みごと横に送れるようにする** */
.doc-table {
  display: block;
  overflow-x: auto;
  width: 100%;
  border-collapse: collapse;
  margin: 12px 0;
  font-size: 14px;
}

.doc-table th,
.doc-table td {
  border: 1px solid var(--outline);
  padding: 8px 10px;
  text-align: left;
  vertical-align: top;
}

.doc-table th {
  background: var(--surface-variant);
  font-weight: 600;
  white-space: nowrap;
}

/* 利用規約・プライバシーポリシーへの入口。**ログインの画面にも必ず出す** */
.legal-links {
  text-align: center;
  font-size: 13px;
  color: var(--on-surface-variant);
  margin-top: 20px;
}

.legal-links a {
  color: var(--on-surface-variant);
}

.legal-links span {
  margin: 0 4px;
}

/* ── 使い方ガイド（guide.html）─────────────────────────────
 *
 * **はじめて来た人が最初に見るページ。** JavaScript を使わない静的なページ。
 * 画面の写真は、本物の画面をそのまま撮ったもの。
 */

.guide .shot {
  margin: 16px 0 20px;
}

.guide .shot img {
  display: block;
  width: 100%;
  /* 撮影は 500px 幅。**それ以上に引き伸ばすとぼやける** */
  max-width: 400px;
  height: auto;
  margin: 0 auto;
  border: 1px solid var(--outline);
  border-radius: var(--r-small);
  /* 白い画面が背景に溶けないよう、薄い影を付ける */
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}

.guide .shot figcaption {
  text-align: center;
  color: var(--on-surface-variant);
  font-size: 13px;
  margin-top: 8px;
}

.guide-cta {
  text-align: center;
  margin: 32px 0 8px;
}

.guide-cta .btn {
  min-width: 200px;
}

/* ログイン画面から使い方へ。**はじめての人がいちばん先に目を留めるところに置く** */
.guide-link {
  text-align: center;
  margin: 0 0 16px;
  padding: 10px;
  background: var(--surface-high);
  border-radius: var(--r-small);
  font-size: 14px;
}

/* ══════════════════════════ 動き ══════════════════════════
 *
 * **動くのは 3 つの場面だけ。**
 *
 *   ① 画面が変わったとき（タブ・グループ・設定の区分）
 *   ② 自分で開け閉めしたとき（ダイアログ・年月・明細）
 *   ③ 押したとき（ボタン・チップ・ナビ）
 *
 * **描き直しのたびに動かさない。** この画面は状態が変わるたびに要素を作り直すので、
 * 何も考えずに animation を付けると、チェックを 1 つ入れただけで画面じゅうが動く。
 * ①は app.js が「さっきと違う画面か」を見て `.view-enter` を付けたときだけ効かせる
 * （→ app.js の viewKey()）。
 *
 * **transform を #app そのものに掛けない。**
 * 掛けると position:fixed の入れ物になってしまい、中の sticky（上の帯・保存の帯）の
 * 基準がずれる。動かすのは中の 1 枚 1 枚。
 *
 * 動きを減らす設定（prefers-reduced-motion）は、下の方でまとめて止めてある。
 */

@keyframes fade-up {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(16px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* ── ① 画面が変わったとき ────────────────────────────── */

/* 上の帯は動かさない。**居座るものが動くと、位置が定まらないように見える** */
#app.view-enter > *:not(.appbar):not(.scroll-sentinel) {
  animation: fade-up var(--dur-3) var(--ease-out) both;
}

/* 上から順に、ほんの少しずつ遅らせる。**5 枚目から先は待たせない**
   （待たせるほど「重いアプリ」に感じる）。
   **1 番目は見張りの目印、2 番目は上の帯**なので、中身は 3 番目から始まる
   （→ app.js の render()）。 */
#app.view-enter > *:nth-child(3) { animation-delay: 0.02s; }
#app.view-enter > *:nth-child(4) { animation-delay: 0.05s; }
#app.view-enter > *:nth-child(5) { animation-delay: 0.08s; }
#app.view-enter > *:nth-child(6) { animation-delay: 0.11s; }

/* 明細の 1 行ずつ。**10 行までにする。**
   全部に遅れを付けると、下のほうが「遅れて出てくる列」になって読みにくい */
#app.view-enter .entry-list > .entry {
  animation: fade-up var(--dur-2) var(--ease-out) both;
}

#app.view-enter .entry-list > .entry:nth-child(1) { animation-delay: 0.02s; }
#app.view-enter .entry-list > .entry:nth-child(2) { animation-delay: 0.04s; }
#app.view-enter .entry-list > .entry:nth-child(3) { animation-delay: 0.06s; }
#app.view-enter .entry-list > .entry:nth-child(4) { animation-delay: 0.08s; }
#app.view-enter .entry-list > .entry:nth-child(5) { animation-delay: 0.1s; }
#app.view-enter .entry-list > .entry:nth-child(6) { animation-delay: 0.12s; }
#app.view-enter .entry-list > .entry:nth-child(7) { animation-delay: 0.14s; }
#app.view-enter .entry-list > .entry:nth-child(8) { animation-delay: 0.16s; }
#app.view-enter .entry-list > .entry:nth-child(9) { animation-delay: 0.18s; }
#app.view-enter .entry-list > .entry:nth-child(n + 10) { animation-delay: 0.2s; }

/* 設定のメニューも 1 枚ずつ */
#app.view-enter .menu > button {
  animation: fade-up var(--dur-2) var(--ease-out) both;
}

#app.view-enter .menu > button:nth-child(1) { animation-delay: 0.02s; }
#app.view-enter .menu > button:nth-child(2) { animation-delay: 0.05s; }
#app.view-enter .menu > button:nth-child(3) { animation-delay: 0.08s; }
#app.view-enter .menu > button:nth-child(4) { animation-delay: 0.11s; }
#app.view-enter .menu > button:nth-child(5) { animation-delay: 0.14s; }
#app.view-enter .menu > button:nth-child(n + 6) { animation-delay: 0.17s; }

/* ログイン・登録・グループを作る画面 */
.auth.view-enter,
.view-enter.card {
  animation: rise-in var(--dur-3) var(--ease-out) both;
}

/* ── 棒グラフは、左から伸びる ───────────────────────────
 *
 * **幅ではなく scaleX を動かす。** 幅は app.js が CSSOM で入れているので、
 * そこへ動きを重ねると、値と動きのどちらが正なのか分からなくなる。 */
@keyframes bar-grow {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

.bars .fill {
  transform-origin: left center;
  /* 単色だった棒に濃淡を入れる。**並ぶほど効く** */
  background-image: var(--grad-primary);
}

#app.view-enter .bars .fill {
  animation: bar-grow var(--dur-3) var(--ease-out) both;
}

#app.view-enter .bars .bar-row:nth-child(1) .fill { animation-delay: 0.04s; }
#app.view-enter .bars .bar-row:nth-child(2) .fill { animation-delay: 0.08s; }
#app.view-enter .bars .bar-row:nth-child(3) .fill { animation-delay: 0.12s; }
#app.view-enter .bars .bar-row:nth-child(4) .fill { animation-delay: 0.16s; }
#app.view-enter .bars .bar-row:nth-child(n + 5) .fill { animation-delay: 0.2s; }

/* ── ② 開け閉め ──────────────────────────────────────── */

@keyframes dialog-in {
  from {
    opacity: 0;
    transform: translateY(12px) scale(0.96);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

dialog[open] {
  animation: dialog-in var(--dur-2) var(--ease-out) both;
  box-shadow: var(--shadow-3);
}

dialog::backdrop {
  animation: fade-in var(--dur-2) var(--ease) both;
  /* うしろをぼかす。**手前だけを見ればよいことが、ひと目で伝わる** */
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

/* 年月アコーディオンの中身。**開いた瞬間だけ動く**
   （閉じているあいだは中身が描かれないので、閉じるときは動かない） */
@keyframes acc-open {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.acc[open] > .acc-body {
  animation: acc-open var(--dur-2) var(--ease-out) both;
}

/* 開閉の印は、向きが回って変わる */
.acc > summary::before {
  transition: transform var(--dur-2) var(--ease);
}

/* 明細を開いたときの内訳 */
.entry .detail {
  animation: acc-open var(--dur-2) var(--ease-out) both;
}

/* 通知は下から出る */
@keyframes snack-in {
  from {
    opacity: 0;
    transform: translate(-50%, 14px);
  }
  to {
    opacity: 1;
    transform: translate(-50%, 0);
  }
}

.snackbar {
  animation: snack-in var(--dur-2) var(--ease-out) both;
  box-shadow: var(--shadow-2);
}

/* ── ③ 押したとき ────────────────────────────────────── */

.chip,
.segmented button,
.menu button,
.entry > .summary,
.acc > summary {
  transition:
    background var(--dur-1) var(--ease),
    border-color var(--dur-1) var(--ease),
    color var(--dur-1) var(--ease),
    transform var(--dur-1) var(--ease),
    box-shadow var(--dur-2) var(--ease);
}

.chip:active,
.segmented button:active,
.menu button:active {
  transform: scale(0.98);
}

/* 選ばれたチップが、ぽんと決まる。**押した本人にだけ分かればよい短さ** */
@keyframes chip-pop {
  0% {
    transform: scale(0.94);
  }
  55% {
    transform: scale(1.04);
  }
  100% {
    transform: scale(1);
  }
}

.chip[aria-pressed='true'],
.segmented button[aria-pressed='true'] {
  animation: chip-pop var(--dur-2) var(--ease-out) both;
}

/* ── 焦点の輪。**キーボードで辿る人のための線を太くする** ── */
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
button:focus-visible,
a:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* 入力欄は、触れているあいだ緑の輪をまとう */
input[type='text'],
input[type='password'],
input[type='number'],
input[type='date'],
input[type='month'],
input[type='search'],
select,
textarea {
  transition:
    border-color var(--dur-1) var(--ease),
    box-shadow var(--dur-1) var(--ease),
    background var(--dur-1) var(--ease);
}

input:focus,
select:focus,
textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 16%, transparent);
}

/* ── 上の帯の見張り。**高さを持たせない** ── */
.scroll-sentinel {
  height: 1px;
  margin-bottom: -1px;
  pointer-events: none;
}

/* ══════════════════════════ 読み込み中 ══════════════════════════
 *
 * **真っ白のまま数秒待たせない。** 中身が来る前に、来る場所の形だけ先に出す。
 * 「止まっている」と「読み込んでいる」を見分けられるようにする。 */

.booting {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 16px 12px;
}

.booting .bar,
.booting .block {
  background: var(--surface-variant);
  animation: skeleton 1.4s var(--ease) infinite;
}

.booting .bar {
  height: 14px;
  border-radius: 7px;
  margin-bottom: 12px;
}

.booting .block {
  height: 92px;
  border-radius: var(--r-card);
  margin-bottom: 12px;
}

.booting .bar.w60 { width: 60%; }
.booting .bar.w40 { width: 40%; }
.booting .block.tall { height: 148px; }

.booting .block:nth-of-type(2) { animation-delay: 0.12s; }
.booting .block:nth-of-type(3) { animation-delay: 0.24s; }
.booting .block:nth-of-type(4) { animation-delay: 0.36s; }

@keyframes skeleton {
  0%,
  100% {
    opacity: 0.5;
  }
  50% {
    opacity: 0.95;
  }
}

/* 読み込みの文字。**見えない人にも伝わるよう、文字そのものは残す** */
.booting .say {
  text-align: center;
  color: var(--on-surface-variant);
  font-size: 13px;
  margin-top: 20px;
}

/* ══════════════════════════ PC で少し持ち上げる ══════════════════════════
 *
 * **タッチ端末では :hover が張り付く**（一度触れた要素が、離れても浮いたまま）。
 * だからマウスがある端末でだけ効かせる。 */

@media (hover: hover) and (pointer: fine) {
  .card:hover {
    box-shadow: var(--shadow-2);
    border-color: color-mix(in srgb, var(--primary) 22%, var(--outline));
  }

  .menu button:hover {
    border-color: color-mix(in srgb, var(--primary) 30%, var(--outline));
    box-shadow: var(--shadow-1);
    transform: translateY(-1px);
  }

  .btn.primary:hover {
    box-shadow: var(--shadow-2);
    filter: brightness(1.06);
  }

  .btn.outline:hover,
  .btn.quick:hover {
    border-color: var(--primary);
    color: var(--primary);
  }

  .chip:hover {
    border-color: var(--primary);
  }

  .nav button:hover .dot {
    background: color-mix(in srgb, var(--primary) 12%, transparent);
  }
}

/* ── 実支払金額を、横に余裕があれば 2 列に ─────────────────
 *
 * **人数ぶん縦に並ぶところ。** 4 人いるとそれだけで画面 1 つぶんになり、
 * 「登録する」まで指を送り続けることになる。
 * **分岐は上の 768px と同じ。** 新しい分岐は作らない。 */
@media (min-width: 768px) {
  .paid-rows {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 14px;
  }
}

/* ── いま登録した 1 件 ─────────────────────────────────
 *
 * **一覧は日付順なので、足したものが先頭に来るとは限らない。**
 * 「登録しました」だけだと、どれが増えたのかを目で探すことになる。
 * ひと呼吸だけ光らせて、そこへ視線を運ぶ。
 *
 * **色だけに頼らない。** 枠も一緒に動かすので、色が見えなくても場所は分かる。
 * 印は app.js が描いたその場で消すので、次の描き直しでは光らない。 */
@keyframes just-saved {
  0% {
    background: var(--primary-container);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 34%, transparent);
  }
  70% {
    background: var(--primary-container);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent);
  }
  100% {
    background: var(--surface);
    box-shadow: none;
  }
}

/* **`both` を付けない。** 付けると終わったあとも最後の枠に居座り、
   精算の行（下地が別）まで白く塗り替えてしまう。
   何も残さなければ、終わった瞬間にその行本来の見た目へ戻る。 */
.entry.is-new {
  animation: just-saved 1.6s var(--ease-out);
}
