/*
 * 画面を組み立てるパーツ。application.css のトークンを前提にしている。
 *
 * 色の使い分けはひとつだけ覚えればよい。
 *   グラデーション … ブランド・操作・進行中のもの
 *   ゴールド       … 達成したものだけ
 */

/* ===== ゾーン ===================================================
   ダッシュボードは「あなた」と「みんな」の2階層でできている。
   帯で塗ると記録ボタンと形がぶつかるので、見出しはアイコンと文字で立てる。 */
.zone { display: grid; gap: var(--s4); }

.zone__head { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; }
.zone__icon {
  flex: none;
  width: 40px; height: 40px; border-radius: 12px;
  display: grid; place-items: center;
  background: var(--gradient); color: #fff;
  box-shadow: var(--glow), inset 0 1px 0 rgba(255, 255, 255, 0.32);
}
.zone__icon svg { width: 22px; height: 22px; }
.zone__title { font-size: 26px; font-weight: 800; letter-spacing: -0.03em; }
.zone__meta {
  margin-left: auto;
  font-size: 12.5px; font-weight: 700; color: var(--ink-3);
}

/* 「みんな」側は3つの集計をひとつの箱に閉じ込め、罫線で区切る。 */
.zone__body {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s5);
  box-shadow: var(--shadow-sm);
}
.zone__body > .section + .section { margin-top: var(--s7); }
@media (max-width: 520px) { .zone__body { padding: var(--s4); border-radius: var(--r-md); } }

/* セクション見出し。飾り枠や地の色は置かず、
   アイコンの小さなタイルと大きめの文字だけで見出しらしさを作る。 */
.section-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: var(--s4);
}
.section-head__icon {
  flex: none;
  width: 34px; height: 34px; border-radius: 10px;
  display: grid; place-items: center;
  background: var(--brand-tint); color: var(--brand);
}
.section-head__icon svg { width: 19px; height: 19px; }

.section-head__title,
.card__title {
  font-size: 23px; font-weight: 800; letter-spacing: -0.03em;
  color: var(--ink);
}
/* 対応ブラウザだけ文字をグラデーションで塗る。
   非対応環境では上の color がそのまま効くので、消えることはない。 */
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .section-head__title,
  .card__title {
    background: var(--gradient-text);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}
.section-head__meta {
  margin-left: auto;
  font-size: 12px; font-weight: 700; color: var(--ink-3); white-space: nowrap;
}

/* ===== カード =================================================== */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s5);
  box-shadow: var(--shadow-sm);
}
.card__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); margin-bottom: var(--s4);
  flex-wrap: wrap;
}
@media (max-width: 520px) { .card { padding: var(--s4); border-radius: var(--r-md); } }

.divider { height: 1px; background: var(--line); border: 0; margin: 0; }

/* ===== ルームのメタ情報（見出しの中に畳んである） ===============
   知りたい順に上から。誰がいるか → 期間のどこにいるか → 何をやるか。 */
.overview__people { font-size: 12.5px; font-weight: 700; color: var(--ink-3); }

/* 期間のどこにいるか。数字より先に体感で分かる。 */
.overview__bar {
  height: 8px; border-radius: var(--r-pill);
  background: var(--paper-sunk); overflow: hidden;
}
.overview__bar > i {
  display: block; height: 100%; width: var(--pct, 0%);
  border-radius: inherit; background: var(--gradient);
  transition: width .6s cubic-bezier(.2, .8, .2, 1);
}
.overview__dates {
  display: flex; align-items: baseline; gap: var(--s2);
  font-size: 11.5px; font-weight: 700; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.overview__dates > :last-child { margin-left: auto; }
/* 「から」「まで」は日付そのものより一段落として、数字を読みやすく保つ。 */
.overview__edge { font-weight: 700; color: var(--ink-3); opacity: .8; }

.overview__plan { display: grid; gap: 5px; margin-top: 4px; }
.overview__group { display: flex; align-items: baseline; gap: var(--s2); }
.overview__tag {
  flex: none;
  padding: 2px 8px; border-radius: var(--r-pill);
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.06em;
  color: var(--ink-3); background: var(--paper-sunk);
}
.overview__tag--must { color: var(--brand); background: var(--brand-tint); }
.overview__task {
  font-size: 13.5px; color: var(--ink-2); line-height: 1.6;
}
.overview__task b { font-weight: 800; color: var(--ink); }

.empty {
  display: grid; gap: var(--s2); justify-items: center; text-align: center;
  padding: var(--s6) var(--s4); color: var(--ink-3);
}
.empty__mark {
  width: 46px; height: 46px; border-radius: 50%;
  border: 2px dashed var(--line-strong);
}

/* ===== 小物 ===================================================== */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: var(--r-pill);
  background: var(--paper-sunk); border: 1px solid var(--line);
  font-size: 12px; font-weight: 700; color: var(--ink-2);
  white-space: nowrap;
}
.chip--brand { background: var(--brand-tint); border-color: var(--brand-tint-2); color: var(--brand); }
/* 必須の種目につく札。行の地と同じ系統で、そこだけ濃く出す。 */
.chip--must {
  background: color-mix(in srgb, var(--violet) 16%, var(--card));
  border-color: color-mix(in srgb, var(--violet) 40%, transparent);
  color: color-mix(in srgb, var(--violet) 78%, var(--ink));
}
.chip--gold  { background: var(--gold-tint); border-color: var(--gold-tint-2); color: var(--gold); }

.avatar {
  flex: none;
  display: grid; place-items: center;
  width: 38px; height: 38px; border-radius: 12px;
  font-size: 15px; font-weight: 800;
  color: hsl(var(--hue) 58% 34%);
  background: hsl(var(--hue) 70% 93%);
  box-shadow: inset 0 0 0 1px hsl(var(--hue) 55% 82%);
}
.avatar--sm { width: 28px; height: 28px; border-radius: 9px; font-size: 12px; }
@media (prefers-color-scheme: dark) {
  .avatar { color: hsl(var(--hue) 75% 82%); background: hsl(var(--hue) 42% 24%);
            box-shadow: inset 0 0 0 1px hsl(var(--hue) 40% 38%); }
}

/* 数値ひとかたまり */
.stat { display: grid; gap: 1px; }
.stat__value {
  font-size: 24px; font-weight: 800; line-height: 1.15; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.stat__value small { font-size: 13px; font-weight: 700; color: var(--ink-3); margin-left: 2px; }
.stat__label { font-size: 11.5px; font-weight: 700; color: var(--ink-3); letter-spacing: 0.04em; }
.stat-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s3); }
.stat-row > * + * { border-left: 1px solid var(--line); padding-left: var(--s3); }

/* ===== 今日のカード ============================================= */
.today {
  position: relative;
  background:
    radial-gradient(130% 100% at 50% -25%, var(--brand-tint), transparent 62%),
    var(--card-raised);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  padding: var(--s5);
  box-shadow: var(--shadow-md);
  display: grid; gap: var(--s5);
  overflow: hidden;
}
.today__date {
  font-size: 12.5px; font-weight: 700; letter-spacing: 0.04em; color: var(--ink-3);
}

/* 今日のカードの見出し。カードの中でいちばん目に入る行。 */
.today__status { display: flex; align-items: center; gap: 10px; margin-top: 3px; }
.today__status-icon {
  flex: none;
  width: 32px; height: 32px; border-radius: 10px;
  display: grid; place-items: center;
  background: var(--gradient); color: #fff;
  box-shadow: var(--glow), inset 0 1px 0 rgba(255, 255, 255, 0.3);
}
.today__status-icon svg { width: 19px; height: 19px; }
.today__status-text {
  font-size: clamp(23px, 5.2vw, 30px);
  font-weight: 800; letter-spacing: -0.035em; line-height: 1.15;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
/* 対応ブラウザだけ文字をグラデーションで塗る。
   非対応環境では上の color がそのまま効くので、消えることはない。 */
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .today__status-text {
    background: var(--gradient-text);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}
.today__logtitle {
  font-size: 12.5px; font-weight: 800; color: var(--ink-3); letter-spacing: 0.04em;
  padding-bottom: 2px;
}
.today__top { display: flex; align-items: center; gap: var(--s5); }
.today__ring { flex: none; position: relative; width: 132px; height: 132px; }
/* 回すのはリングの円だけ。中央に置く印まで回ってしまわないよう直下に限る。 */
.today__ring > svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.today__ring-track { fill: none; stroke: var(--paper-sunk); stroke-width: 12; }
.today__ring-fill  { fill: none; stroke-width: 12; stroke-linecap: round; }
.today__ring-fill.is-done { filter: drop-shadow(0 0 7px var(--gold-tint-2)); }
.today__ring-label {
  position: absolute; inset: 0; display: grid; place-content: center; text-align: center; gap: 0;
}
.today__ring-num {
  font-size: 36px; font-weight: 800; line-height: 1; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.today__ring-goal { font-size: 12px; font-weight: 700; color: var(--ink-3); }

/* リングの右上に貼りつく、仲間からの応援の数。
   地の色で縁を回して、リングの線の上に乗っても数が読めるようにする。 */
.ringbadge {
  position: absolute; top: -4px; right: -8px;
  width: 50px; aspect-ratio: 1; border-radius: 50%;
  display: grid; place-content: center; justify-items: center; gap: 1px;
  background: var(--gradient); color: #fff;
  box-shadow: 0 0 0 3px var(--card), 0 4px 10px -4px rgba(21, 26, 46, 0.45);
  /* 弾けたときに広がる輪の色。満タンなら金に替える。 */
  --pop-ink: var(--brand);
}
/* もらった印はじっとしていないほうが嬉しい。ゆっくり上下に漂わせる。
   1種目のときはリングの右上、複数種目のときは見出しの右端に付くので、
   どちらでも同じ動きになるよう .ringbadge そのものに掛ける。 */
.ringbadge { animation: ringbadge-float 2.9s ease-in-out infinite; }
@keyframes ringbadge-float {
  0%, 100% { translate: 0 0;     rotate: -5deg;   scale: 1; }
  30%      { translate: 0 -7px;  rotate: 3deg;    scale: 1.04; }
  60%      { translate: 0 -10px; rotate: 6deg;    scale: 1.02; }
}
@media (prefers-reduced-motion: reduce) {
  .ringbadge { animation: none; }
}

.ringbadge__num {
  font-size: 18px; font-weight: 800; line-height: 1; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.ringbadge__label {
  font-size: 8.5px; font-weight: 800; line-height: 1;
  letter-spacing: 0.02em; opacity: .92;
}
/* リングが無い画面では、見出しの並びにそのまま置く。
   relative にしてあるのは、広がる輪（::after）の基準を自分にするため。 */
.ringbadge--inline { position: relative; flex: none; margin-left: auto; margin-right: 4px; }

/* 済んだ印と応援の数を右端にまとめる。寄せるのは個々ではなく、この入れ物。 */
.today__marks {
  margin-left: auto; margin-right: 4px;
  display: flex; align-items: center; gap: var(--s3);
}
.today__marks .ringbadge--inline { margin-left: 0; margin-right: 0; }

/* 今日ぶんが済んだ印。達成の印（celebrate）と同じ金の語彙で、丸く小さくしたもの。
   応援の数と並ぶので、地を塗らず枠で見せて、押せるものではないことも伝える。 */
.donebadge {
  flex: none;
  width: 50px; aspect-ratio: 1; border-radius: 50%;
  display: grid; place-content: center;
  color: var(--gold);
  background: color-mix(in srgb, var(--card-raised) 86%, transparent);
  border: 2.5px solid currentColor;
  box-shadow: inset 0 0 0 2px currentColor,
              0 0 0 3px var(--card),
              0 4px 10px -4px rgba(21, 26, 46, .4);
  font-size: 14px; font-weight: 800; letter-spacing: .06em;
  animation: donebadge-in .42s cubic-bezier(.2, .9, .25, 1.5) both;
}
@keyframes donebadge-in {
  from { opacity: 0; transform: scale(.55) rotate(-14deg); }
  to   { opacity: 1; transform: scale(1) rotate(-8deg); }
}
/* 1種目のときは、リングを挟んで応援の反対側（左上）に掛ける。 */
.today__ring .donebadge { position: absolute; top: -4px; left: -8px; }

@media (prefers-reduced-motion: reduce) {
  .donebadge { animation: none; rotate: -8deg; }
}

/* ロゴの雨が降り出した合図で一度だけ弾ける。
   ふよふよ（float）は translate / rotate / scale の個別プロパティで書いてあるので、
   弾けるほうを transform で書けば、2本を並べても打ち消し合わない。 */
.ringbadge.is-popping {
  animation: ringbadge-float 2.9s ease-in-out infinite,
             ringbadge-pop .52s cubic-bezier(.2, .9, .22, 1.7);
}
@keyframes ringbadge-pop {
  0%   { transform: scale(1); }
  20%  { transform: scale(1.42); }
  48%  { transform: scale(.93); }
  100% { transform: scale(1); }
}

/* 外へ広がる輪。色は var() で持つが、動かすのは transform と opacity だけにする。
   var() を挟んだ値はキーフレームの途中が補間されず、飛び飛びに見えるため。 */
.ringbadge::after {
  content: ""; position: absolute; inset: -3px;
  border-radius: 50%; border: 2.5px solid var(--pop-ink);
  opacity: 0; pointer-events: none;
}
.ringbadge.is-popping::after {
  animation: ringbadge-halo .62s cubic-bezier(.16, .84, .34, 1) forwards;
}
@keyframes ringbadge-halo {
  0%   { opacity: .95; transform: scale(.86); }
  100% { opacity: 0;   transform: scale(1.95); }
}

.ringbadge.is-popping .ringbadge__num {
  animation: ringbadge-num .52s cubic-bezier(.2, .9, .22, 1.7);
}
@keyframes ringbadge-num {
  0%   { transform: translateY(0) scale(1); }
  24%  { transform: translateY(-3px) scale(1.22); }
  100% { transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .ringbadge.is-popping,
  .ringbadge.is-popping::after,
  .ringbadge.is-popping .ringbadge__num { animation: none; }
}

.ringbadge.is-full {
  background: var(--gold-gradient);
  box-shadow: 0 0 0 3px var(--card),
              0 0 12px color-mix(in srgb, var(--gold-fill) 75%, transparent);
  --pop-ink: var(--gold-fill);
}
.today__side { display: grid; gap: var(--s2); min-width: 0; }

/* 見るだけの人への誘い。達成した日のカードと同じ姿を、そのまま見せる。
   これから起きることの見本なので、控えめにはせず、いちばん良い状態を出す。 */
.today--invite .donebadge { animation-delay: .9s; }

/* 誘いのボタン。記録ボタンと同じ形で、押した先が違うだけ。 */
.tap--invite { text-decoration: none; }
.tap--invite:hover { text-decoration: none; }
@media (max-width: 560px) {
  .today__top { flex-direction: column; text-align: center; gap: var(--s4); }
  .today__side { justify-items: center; }
}

/* 記録ボタン。親指で確実に届くサイズ。 */
.tap {
  position: relative;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 66px;
  border: 0; border-radius: var(--r-pill);
  background: var(--gradient);
  color: #fff;
  font-size: 20px; font-weight: 800; letter-spacing: 0.01em;
  cursor: pointer;
  box-shadow: var(--glow), inset 0 1px 0 rgba(255, 255, 255, 0.32);
  transition: transform .1s cubic-bezier(.2,.9,.3,1.2), box-shadow .1s ease, filter .12s ease;
  -webkit-tap-highlight-color: transparent;
  overflow: hidden;
}
.tap:hover  { filter: brightness(1.06); }
.tap:active { transform: translateY(2px) scale(.985); box-shadow: 0 4px 12px -6px var(--brand-tint-2); }
.tap__num  { font-size: 27px; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
/* スタンプの「OK」。数字ではないので字間は詰めず、少しだけ小さくして収まりを合わせる。 */
.tap__num--text { font-size: 24px; letter-spacing: 0.01em; }
/* 「OK」と「を押す」はひと続きの言葉なので、ボタンの隙間ぶんだけ寄せる。 */
.tap__num--text + .tap__unit { margin-left: -6px; }
.tap__unit { font-size: 15px; opacity: .9; }
.tap[disabled] { background: var(--paper-sunk); color: var(--ink-3); box-shadow: none; cursor: default; }
/* スタンプを押したあと。押せないことと、済んでいることを同じ見た目で伝える。 */
.tap--pressed[disabled] {
  background: var(--gold-tint);
  color: var(--gold);
  border: 1.5px solid var(--gold-tint-2);
}
.tap--pressed[disabled] .tap__unit { opacity: 1; }
/* 押した瞬間に光が広がる */
.tap::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(circle at center, rgba(255,255,255,.6), transparent 62%);
  opacity: 0; transform: scale(.2);
}
.tap:active::after { animation: tap-ripple .45s ease-out; }
@keyframes tap-ripple {
  from { opacity: .85; transform: scale(.2); }
  to   { opacity: 0;   transform: scale(1.6); }
}

.today__more {
  display: flex; align-items: center; justify-content: center; gap: var(--s4);
  flex-wrap: wrap;
}
/* ボタンらしくしすぎると記録ボタンと張り合うので、
   破線の下線を引いた「リンク寄りの操作」として置く。 */
.today__custom {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 3px;
  border: 0; border-bottom: 1.5px dashed var(--line-strong);
  border-radius: 0; background: none; cursor: pointer;
  font-size: 13.5px; font-weight: 700; color: var(--ink-2);
  transition: color .12s ease, border-color .12s ease;
}
.today__custom svg { width: 16px; height: 16px; }
.today__custom:hover { color: var(--brand); border-bottom-color: var(--brand); }

/* 今日の記録の明細 */
.log { display: grid; gap: 2px; }
.log__item {
  display: flex; align-items: center; gap: var(--s3);
  padding: 7px 0; border-top: 1px dashed var(--line);
  font-size: 13.5px;
}
.log__time { color: var(--ink-3); font-variant-numeric: tabular-nums; width: 46px; flex: none; }
.log__reps { font-weight: 800; font-variant-numeric: tabular-nums; }

/* お祝い。達成した瞬間だけ金の印が落ちてくる。
   画面の真ん中はロゴが通り過ぎる場所なので、その少し下に置いて重ならないようにする。 */
.celebrate {
  position: fixed; inset: 0;
  display: grid; place-items: center;
  /* 画面の高さに応じて下げる。狭い画面で下がりすぎないよう上限を決めておく。 */
  padding-top: min(22vh, 150px);
  pointer-events: none;
  /* 迫ってくるロゴ（85）より上。お知らせ（90）より下。 */
  z-index: 86;
}
.celebrate__seal {
  width: 152px; height: 152px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--gold);
  border: 5px solid currentColor;
  box-shadow: inset 0 0 0 3px currentColor, 0 0 32px -6px var(--gold-tint-2);
  font-size: 40px; font-weight: 800; letter-spacing: .1em;
  background: color-mix(in srgb, var(--card-raised) 82%, transparent);
  animation: seal-drop 1.5s cubic-bezier(.2,1.1,.3,1) forwards;
}
@keyframes seal-drop {
  0%   { opacity: 0; transform: scale(2.1) rotate(-24deg); }
  22%  { opacity: 1; transform: scale(.94) rotate(-9deg); }
  32%  { transform: scale(1.02) rotate(-11deg); }
  /* ひと呼吸置いてから、回して消す。 */
  70%  { opacity: 1; transform: scale(1) rotate(-10deg);
         animation-timing-function: cubic-bezier(.4, 0, .6, 1); }
  /* 回す前に逆へ少し戻す。ためを作らないと、ただ滑り出したように見える。 */
  77%  { opacity: 1; transform: scale(.96) rotate(-34deg);
         animation-timing-function: cubic-bezier(.5, 0, .75, 1); }
  /* 2回転ぶん。回りながら小さくなって、吸い込まれるように消える。 */
  100% { opacity: 0; transform: scale(.42) rotate(716deg); }
}

/* ===== スタンプ台紙 ============================================= */
/* 1画面に1ヶ月ぶん。月の送りは上の矢印かスワイプ。
   期間が2ヶ月でも半年でも、マスの大きさも台紙の高さも変わらない。 */
/* 台紙は白いカードではなく、うっすら曇ったガラス板。
   色は乗せず、背後のページの光をぼかして通すだけにする（中身が主役なので）。 */
/* 台紙と日ごとのグラフの地に、キービジュアルをうっすら敷く。
   中身はその上に描かれるので、日付・印・棒の読みやすさは変わらない。 */
.sheet::before,
.chart::before {
  content: "";
  position: absolute; inset: 0; z-index: 0;
  background: url("/key-visual-bg.png") no-repeat right bottom / min(360px, 82%) auto;
  opacity: .08;
  border-radius: inherit;
  pointer-events: none;
}
@media (prefers-color-scheme: dark) {
  .sheet::before,
  .chart::before { opacity: .12; }
}
.sheet > *,
.chart > * { position: relative; z-index: 1; }

/* 台紙の入れ物。すりガラスを掛けない側で、明細のダイアログを受け持つ。
   ガラス（backdrop-filter）の中に置いたダイアログは、画面ではなくガラスを基準に置かれる。 */
.sheetbox { min-width: 0; }

.sheet {
  position: relative;
  /* 中身（月ページ）は親いっぱいの幅を要求して縮まない。その要求が外へ伝わると
     台紙ごとページを押し広げるので、幅の話をこの中で完結させる。 */
  contain: inline-size;
  min-width: 0;
  display: grid; gap: var(--s4);
  padding: var(--s5) var(--s4);
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  border: 1px solid var(--glass-border);
  box-shadow: var(--shadow-md), inset 0 1px 0 var(--glass-highlight);
  overflow: hidden;
  isolation: isolate;
}
@media (max-width: 520px) {
  /* 画面の端まで広げてマスを大きく取る。スタンプの「達成」が潰れないため。 */
  .sheet {
    margin-inline: calc(-1 * var(--s4));
    padding: var(--s4) 10px;
    border-radius: 0; border-inline: 0;
  }
  .sheet__weekdays,
  .sheet__grid { gap: 2px; }
}

/* 月送りの見出しとページ送り。台紙とグラフで共通に使う。 */
.monthnav {
  display: flex; align-items: center; justify-content: center; gap: var(--s4);
}
.monthnav__btn {
  flex: none;
  width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center;
  /* グラデーションは残しつつ、彩度を落として地に馴染ませる。
     矢印だけブランド色にして操作できることを示す。 */
  border: 1px solid color-mix(in srgb, var(--brand) 20%, transparent);
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--aqua) 24%, var(--card)) 0%,
    color-mix(in srgb, var(--violet) 20%, var(--card)) 100%);
  color: var(--brand);
  font-size: 18px; line-height: 1; cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: filter .12s ease, transform .12s ease;
}
.monthnav__btn:hover:not([disabled]) { filter: brightness(1.04) saturate(1.15); }
.monthnav__btn:active:not([disabled]) { transform: translateY(1px) scale(.96); }
/* 端の月では消す。場所は空けたままにして、見出しの位置が飛ばないようにする。 */
.monthnav__btn[disabled] { visibility: hidden; }
.monthnav__title {
  min-width: 5.5em; text-align: center;
  font-size: 18px; font-weight: 800; letter-spacing: -0.01em;
}

.monthpages {
  display: flex; gap: var(--s4);
  /* overflow-x を指定すると縦もクリップされる。1行目のマスから
     上にはみ出す応援の印が切れないよう、内側に逃げ場を作っておく。 */
  padding-top: 6px; margin-top: -6px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  /* 月ページは親いっぱいの幅を要求する（flex: 0 0 100%）。そのままだと
     「ページ数ぶんの合計幅」が外へ伝わって、台紙やグラフごと親を押し広げる。
     横スクロールはこの中で完結する話なので、ここで断ち切る。 */
  contain: inline-size;
  min-width: 0;
}
.monthpages::-webkit-scrollbar { display: none; }
.monthpage {
  flex: 0 0 100%;
  scroll-snap-align: start;
  min-width: 0;
}
.sheet__month { display: grid; gap: 5px; align-content: start; }

/* マスの間はできるだけ詰める。離れているとカレンダーに見えない。

   1fr ではなく minmax(0, 1fr) にしているのが肝。1fr の下限は auto
   （＝中身の min-content）なので、「達成」のスタンプが列幅より広くなると
   マス側のトラックだけが押し広げられ、曜日ヘッダと列がズレる。
   下限を 0 にして、トラック幅を中身に左右されないようにしている。 */
.sheet__weekdays,
.sheet__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 3px;
}
/* ヘッダの升目はマスと同じ箱にしておく（中央がずれる余地をなくす） */
.sheet__weekdays > span {
  min-width: 0;
  display: grid; place-items: center;
  padding: 0 2px 4px;
  font-size: 12px; font-weight: 800; color: var(--ink-2);
}
.sheet__weekdays > span:nth-child(6) { color: var(--aqua); }   /* 土 */
.sheet__weekdays > span:nth-child(7) { color: var(--violet); } /* 日 */

/* 幅は台紙いっぱいに使う。ただし正方形のままだと画面が広いときに
   縦に伸びすぎるので、高さだけ頭打ちにして横長のマスに寝かせる。

   中身は2段。上＝日付、下＝スタンプ。
   下の段だけ 1fr にしてあるので、マスが小さいときはスタンプだけが縮み、
   日付は潰れない。日付は常に上段なのでカレンダーとして読める。 */
.day {
  min-width: 0;
  /* 応援の印を少しだけ外へ出したいので切らない。
     中身が膨らまない歯止めは min-width: 0 と印側の max-width で足りている。 */
  overflow: visible;
  /* width を明示するのが肝。aspect-ratio と max-height を併せると、
     高さが頭打ちになったときに幅まで縮んで justify-self: stretch が効かなくなり、
     マスが列の左端に寄る（＝曜日ヘッダだけ右にずれて見える）。
     幅を 100% で固定して、頭打ちになるのは高さだけにする。 */
  width: 100%;
  aspect-ratio: 1;
  max-height: 120px;
  border-radius: 12px;
  position: relative;   /* 右上に応援の印を重ねる */
  display: grid;
  grid-template-rows: min-content 1fr;
  justify-items: center;
  align-items: center;
  gap: 0;
  padding: 2px;
  /* ガラス板の上に置く半透明のタイル。奥の色玉がうっすら透ける。 */
  background: var(--glass-tile);
  border: 1px solid var(--glass-tile-border);
  box-shadow: 0 1px 2px rgba(21, 26, 46, 0.06);
}
/* 記録のある日は押せる。押せることを触感（沈み）とカーソルで示す。 */
button.day {
  font: inherit; color: inherit; text-align: inherit;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: transform .1s ease, box-shadow .1s ease;
}
button.day:hover { box-shadow: 0 3px 10px -3px color-mix(in srgb, var(--brand) 45%, transparent); }
button.day:active { transform: scale(.94); }

/* もらった応援の数。マスの右上に小さなピルで出す。
   地の色と同じ縁を回して、下の日付と溶け合わないようにする。 */
.day__yaruyan {
  position: absolute; top: -4px; right: 0; z-index: 1;
  /* 幅だけ決めて高さは aspect-ratio に任せる。数が何桁でも真円のまま。 */
  width: clamp(17px, 3.6vw, 23px); aspect-ratio: 1;
  padding: 0; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--gradient); color: #fff;
  font-weight: 800; line-height: 1;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 1.5px var(--card);
}
/* 円の大きさは変えず、桁が増えたぶんだけ文字を締める。 */
.day__yaruyan--d1 { font-size: clamp(10px, 2.1vw, 13px); }
.day__yaruyan--d2 { font-size: clamp(8.5px, 1.8vw, 11px);  letter-spacing: -.02em; }
.day__yaruyan--d3 { font-size: clamp(7px, 1.45vw, 9px);    letter-spacing: -.05em; }
.day__yaruyan.is-full {
  background: var(--gold-gradient);
  box-shadow: 0 0 0 1.5px var(--card),
              0 0 7px color-mix(in srgb, var(--gold-fill) 85%, transparent);
}

.day--blank  { background: transparent; border-color: transparent; box-shadow: none; }
.day--future {
  background: transparent; border: 1px dashed var(--glass-tile-border);
  box-shadow: none; opacity: .8;
}
.day--today  { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); }
.day--today .day__date { color: var(--brand); }

.day__date {
  grid-row: 1;
  font-size: clamp(10.5px, 1.7vw, 14px);
  font-weight: 700; color: var(--ink-2); line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* 達成の印。枠は金のグラデーション。
   border は border-radius と一緒にグラデーションを扱えないので、
   padding-box に中身の地、border-box に金のグラデーションを敷いて枠に見せる。 */
.day--done {
  background: color-mix(in srgb, var(--gold-fill) 34%, var(--card));
  border-color: color-mix(in srgb, var(--gold) 45%, transparent);
  box-shadow: 0 1px 3px color-mix(in srgb, var(--gold) 22%, transparent);
}
.day--done .day__date { color: var(--gold); }
.day__seal {
  grid-row: 2;
  width: 72%; height: auto; aspect-ratio: 1;
  max-width: 100%; max-height: 100%;
  min-width: 0; overflow: hidden;
  border-radius: 50%;
  display: grid; place-items: center;
  border: clamp(2px, 0.45vw, 4px) solid transparent;
  background:
    linear-gradient(color-mix(in srgb, var(--gold-fill) 10%, var(--card)),
                    color-mix(in srgb, var(--gold-fill) 10%, var(--card))) padding-box,
    linear-gradient(135deg, #f0d78f 0%, #c99a30 45%, #a3781f 100%) border-box;
  box-shadow: 0 1px 4px -1px color-mix(in srgb, var(--gold) 55%, transparent);
  color: var(--gold);
  font-size: clamp(9.5px, 2.3vw, 23px);
  font-weight: 800; letter-spacing: -0.07em; line-height: 1;
  animation: seal-press .34s cubic-bezier(.2, 1.35, .4, 1) backwards;
}
@keyframes seal-press { from { opacity: 0; transform: scale(1.55); } }

/* 必須ではない種目に手を付けた印。金の「達成」と混ざらないよう、枠はブランドの青。 */
.day__seal--optional {
  background:
    linear-gradient(color-mix(in srgb, var(--blue) 9%, var(--card)),
                    color-mix(in srgb, var(--blue) 9%, var(--card))) padding-box,
    linear-gradient(135deg, #6fd3e8 0%, #3a63da 52%, #7b4bd4 100%) border-box;
  box-shadow: 0 1px 4px -1px color-mix(in srgb, var(--brand) 50%, transparent);
  /* はなまるは線画なので、枠と同じ濃さだと重い。地に溶ける手前まで薄くする。 */
  color: color-mix(in srgb, var(--brand) 58%, transparent);
}

/* はなまるは線画なので、枠に触れない大きさに収める。 */
.day__seal--optional svg { width: 74%; height: 74%; }

/* 目標には届かなかったが手は付けた日。3つの印のいちばん控えめな段。 */
.day__seal--tried {
  background:
    linear-gradient(color-mix(in srgb, var(--ink-3) 6%, var(--card)),
                    color-mix(in srgb, var(--ink-3) 6%, var(--card))) padding-box,
    linear-gradient(135deg,
      color-mix(in srgb, var(--ink-3) 55%, transparent),
      color-mix(in srgb, var(--ink-3) 30%, transparent)) border-box;
  box-shadow: none;
  color: color-mix(in srgb, var(--ink-3) 75%, transparent);
}
.day__seal--tried svg { width: 64%; height: 64%; }

.day--done.day--today {
  border-color: var(--brand);
  box-shadow: 0 0 0 1px var(--brand), 0 0 16px -4px var(--gold-tint-2);
}

/* 目標に届かなかった日。回数は出さないので、地の色だけで「やった」を示す。
   実際の回数はマスにカーソルを合わせれば出る。 */
.day--partial {
  background: color-mix(in srgb, var(--brand) 18%, var(--card));
  border-color: color-mix(in srgb, var(--brand) 42%, transparent);
}
.day--partial .day__date { color: var(--brand); }

/* ===== みんなの記録（帯） ======================================= */
.strips { display: grid; gap: var(--s3); }
.strip {
  display: grid;
  /* どの列も下限を切っておく。固定にすると、狭い画面で
     その幅ぶんだけ行が親からはみ出す。
     名前と日数を1行に並べるので、左は少し広く取る。 */
  grid-template-columns: minmax(0, 190px) minmax(0, 1fr) 26px;
  grid-template-areas: "who track toggle";
  align-items: center; gap: var(--s3);
}
.strip__who    { grid-area: who; }
.strip__track  { grid-area: track; }
.strip__toggle { grid-area: toggle; }
.strip__toggle {
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--ink-3); background: var(--paper-sunk);
  transition: transform .2s ease, background-color .15s ease, color .15s ease;
}
.strip__toggle svg { width: 15px; height: 15px; }
.strip-item > summary:hover .strip__toggle { color: var(--brand); }
.strip-item[open] .strip__toggle {
  transform: rotate(180deg);
  color: var(--brand); background: var(--brand-tint);
}
.strip__who { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* 名前と日数は1行。日数は右端に寄せて、行ごとに位置を揃える。 */
.strip__id {
  flex: 1; min-width: 0;
  display: flex; align-items: baseline; gap: var(--s3);
}
.strip__score {
  margin-left: auto; flex: none;
  font-size: 11px; font-weight: 700; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.strip__name {
  font-size: 13px; font-weight: 700; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
/* 今日ぶんを終えた人につく一言。金は「達成」だけに使う色。 */
.strip__today {
  flex: none;
  padding: 1px 7px; border-radius: var(--r-pill);
  background: var(--gold-tint);
  border: 1px solid color-mix(in srgb, var(--gold) 35%, transparent);
  color: var(--gold);
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.01em; line-height: 1.5;
  white-space: nowrap;
}
.strip__track {
  min-width: 0;
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  gap: 2px; align-items: stretch;
  /* 日数が多いと、マスの隙間だけで幅を要求してしまう。溢れたぶんは切る。 */
  overflow: hidden;
}
.strip__cell {
  min-width: 0; height: 26px; border-radius: 2px;
  background: var(--paper-sunk);
}
.strip__cell--done    { background: var(--gold-fill); }
.strip__cell--partial { background: var(--brand-tint-2); }
.strip__cell--future  { background: transparent; box-shadow: inset 0 0 0 1px var(--line); }
.strip__cell--today   { outline: 1.5px solid var(--brand); outline-offset: 1px; }
/* 携帯では横に3つ並べると名前も帯も潰れる。
   上段に「誰が・何日」、下段に帯を全幅で置いて、どちらも読めるようにする。 */
@media (max-width: 560px) {
  .strip {
    grid-template-columns: minmax(0, 1fr) 24px;
    grid-template-areas:
      "who   toggle"
      "track track";
    row-gap: 7px; column-gap: var(--s2);
  }
  .strip__toggle { align-self: center; width: 24px; height: 24px; }
  .strip__track  { gap: 1px; }
  .strip__cell   { height: 22px; border-radius: 1px; }

  .strip__name { font-size: 14px; }
  .strip__score { font-size: 12px; }
}

/* ===== 本日（みんなの今日ぶん） ================================= */
/* 1人1行。左に名前、右に種目ごとのリングを横に並べる。 */
/* 人ごとの区切り。カードで囲むより、線1本のほうが名簿らしく読める。 */
.todayboard { display: grid; }
.todayboard > .todayrow { padding: var(--s3) 0; border-top: 1px solid var(--line); }
.todayboard > .todayrow:first-child { border-top: 0; padding-top: 0; }
.todayboard > .todayrow:last-child { padding-bottom: 0; }
.todayrow {
  display: grid;
  /* 1段目に「誰が」と応援、2段目にリング、3段目にひとこと。
     リングが幅をまるごと使えるので、種目が多くても見える数が減らない。
     応援は行の右端に固定されるから、人ごとに狙う場所も変わらない。 */
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "who    yaruyan"
    "rings  rings"
    "bubble bubble";
  align-items: center; column-gap: var(--s3); row-gap: 6px;
}
.todayrow__who {
  grid-area: who;
  display: flex; align-items: center; gap: 7px; min-width: 0;
}
.todayrow > .yaruyan { grid-area: yaruyan; }
.todayrow > .hscroll-box { grid-area: rings; }
.todayrow > .bubble { grid-area: bubble; }
.todayrow__name {
  min-width: 0;
  font-size: 13px; font-weight: 700; line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.todayrow__who .strip__today { flex: none; }
/* 主催者の印。達成の金とは役目が違うので、色を分けて静かに置く。 */
.hostmark {
  flex: none;
  padding: 1px 7px; border-radius: var(--r-pill);
  background: var(--brand-tint);
  border: 1px solid color-mix(in srgb, var(--brand) 30%, transparent);
  color: var(--brand);
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.01em; line-height: 1.5;
  white-space: nowrap;
}
.todayrings { display: flex; gap: var(--s3); padding: 2px 0; align-items: start; }

/* リング1つぶん。下に種目名を添える。 */
.todaycell { flex: none; width: 74px; display: grid; gap: 3px; justify-items: center; }
/* 必須・任意の札。金は達成の色なので、必須＝クリアに関わる種目、と読める。 */
.todaytag {
  align-self: center;
  padding: 1px 7px; border-radius: var(--r-pill);
  background: var(--paper-sunk); border: 1px solid var(--line);
  font-size: 9.5px; font-weight: 800; letter-spacing: .04em; line-height: 1.5;
  color: var(--ink-3);
  white-space: nowrap;
}
.todaytag--must {
  background: var(--gold-tint);
  border-color: var(--gold-tint-2);
  color: var(--gold);
}

.todaycell__name {
  width: 100%;
  font-size: 10.5px; font-weight: 700; color: var(--ink-2); line-height: 1.3;
  text-align: center;
  /* 2行までは見せて、それ以上は切る。行の高さを揃えるため2行ぶん確保しておく。 */
  min-height: calc(1.3em * 2);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; overflow-wrap: anywhere;
}

.todayring { position: relative; display: block; width: 100%; aspect-ratio: 1; }
/* 押すとその日の明細が開くリング。ボタンらしさは出さず、指が乗ったときだけ応える。 */
button.todayring { padding: 0; border: 0; background: transparent; }
.todayring--open { cursor: pointer; }
.todayring--open:hover  { filter: brightness(1.04); }
.todayring--open:active { transform: scale(.96); }
.todayring--open:focus-visible { outline: none; box-shadow: var(--ring); border-radius: 50%; }
.todayring > svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.todayring__track { fill: none; stroke: var(--paper-sunk); stroke-width: 13; }
.todayring__fill {
  fill: none; stroke-width: 13; stroke-linecap: round;
  transform-box: fill-box; transform-origin: center;
}
.todayring__fill.is-done { filter: drop-shadow(0 0 5px var(--gold-tint-2)); }
.todayring .ring-shine { stroke-width: 13; }

/* 中央の数。1行に「12/30回」は詰まりすぎるので、2段に分ける。 */
.todayring__label {
  position: absolute; inset: 0;
  display: grid; place-content: center; justify-items: center; gap: 0;
  text-align: center;
}
.todayring__num {
  font-size: 19px; font-weight: 800; line-height: 1; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
/* スタンプの種目は、数ではなく押したかどうかを見せる。 */
.todayring__check, .today__ring-check {
  display: grid; place-items: center;
  color: var(--ink-3); opacity: .35;
}
.todayring__check.is-done, .today__ring-check.is-done { color: var(--gold); opacity: 1; }
.todayring__check svg { width: 24px; height: 24px; }
.today__ring-check svg { width: 46px; height: 46px; }

.todayring__goal {
  font-size: 10px; font-weight: 700; color: var(--ink-3); line-height: 1.3;
}
.todaycell:has(.is-done) .todayring__num { color: var(--gold); }

/* 種目が1つだけのときに添える、空のリング。
   本物の記録と見間違えないよう、色を持たせず破線にする。 */
.todaycell--hint { opacity: .8; }
.todayring--empty svg { transform: none; }
.todayring--empty circle {
  fill: none; stroke: var(--line-strong); stroke-width: 5;
  stroke-dasharray: 7 10; stroke-linecap: round;
}
.todaycell--hint .todaycell__name { color: var(--ink-3); }

@media (max-width: 560px) {
  .todaycell { width: 66px; }
  .todayring__num { font-size: 17px; }
  .todaycell__name { font-size: 10px; }
  .todayrow > .yaruyan .yaruyan__btn {
    padding: 0 10px; font-size: 12px; min-height: 30px; gap: 5px;
  }
}

/* ===== ランキング =============================================== */
.board { display: grid; }
.board__row {
  display: grid;
  grid-template-columns: 26px 38px minmax(0, 1fr) auto;
  align-items: center; gap: var(--s3);
  padding: var(--s3) 0;
  border-top: 1px solid var(--line);
}
.board__row:first-child { border-top: 0; }
.board__rank {
  text-align: center; font-size: 14px; font-weight: 800; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.board__row:nth-child(1) .board__rank { color: var(--gold); }
.board__main { min-width: 0; display: grid; gap: 5px; }
.board__name {
  font-size: 14.5px; font-weight: 700; display: flex; align-items: center; gap: 6px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.board__bar {
  height: 7px; border-radius: var(--r-pill); background: var(--paper-sunk); overflow: hidden;
}
.board__bar > i {
  display: block; height: 100%; width: var(--pct, 0%);
  border-radius: inherit;
  background: var(--gradient);
  transition: width .6s cubic-bezier(.2,.8,.2,1);
}
.board__total { text-align: right; white-space: nowrap; }
.board__total b {
  font-size: 20px; font-weight: 800; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.board__total small { font-size: 12px; font-weight: 700; color: var(--ink-3); margin-left: 2px; }
.board__total small.board__unit--apart { margin-left: 5px; }

/* ===== グラフ =================================================== */
.chart { position: relative; display: grid; gap: var(--s3); min-width: 0; contain: inline-size; }
.chart__canvas { width: 100%; height: auto; overflow: visible; }
/* 棒と凡例はアバターと同じ色相で塗るので、誰の棒かひと目で分かる */
.chart__bar    { fill: hsl(var(--hue, 220) 58% 55%); }
/* 1人に絞っているときの、ほかの人の棒。 */
.chart__bar.is-off { display: none; }
.chart__swatch { background: hsl(var(--hue, 220) 58% 55%); }
@media (prefers-color-scheme: dark) {
  .chart__bar    { fill: hsl(var(--hue, 220) 66% 66%); }
  .chart__swatch { background: hsl(var(--hue, 220) 66% 66%); }
}
/* 棒より前面に描くので、少し太くして白い縁を付け、棒の上でも読めるようにする */
.chart__goal {
  stroke: var(--gold); stroke-width: 1.5; stroke-dasharray: 5 3;
  paint-order: stroke;
}
/* 目標の札と日付。SVG の中に書くと表示幅に合わせて縮んでしまうので、
   位置だけ割合で受け取って、大きさは画面の文字と同じ尺で決める。 */
.chart__plot { position: relative; }
.chart__goal-tag {
  /* 右端に寄せる。左は月の初めの棒が伸びてくるので、重なって読みにくい。 */
  position: absolute; right: 0; top: var(--y); translate: 0 -100%;
  color: var(--gold); font-size: 11.5px; font-weight: 800; line-height: 1.5;
  white-space: nowrap; pointer-events: none;
}
/* 日ごとの当たり判定。棒は細いので、1日ぶんの帯で受ける。 */
.chart__hit { fill: transparent; cursor: pointer; }
.chart__hit.is-picked { fill: var(--ink); fill-opacity: .06; }

/* 押した日の記録。棒に重ならないよう、いちばん上に出す。 */
.chart__tip {
  position: absolute; top: 0; left: var(--x); translate: -50% 0;
  z-index: 2; pointer-events: none;
  display: grid; gap: 1px;
  padding: 6px 9px;
  border-radius: var(--r-sm);
  background: var(--card);
  border: 1px solid var(--line-strong);
  box-shadow: 0 8px 20px -10px rgba(0, 0, 0, .35);
  font-size: 11.5px; line-height: 1.45;
  white-space: nowrap;
}
/* 端の日は内側へ寄せる。はみ出すと読めなくなる。 */
.chart__tip.is-left  { left: 0;    translate: 0 0; }
.chart__tip.is-right { left: auto; right: 0; translate: 0 0; }
.chart__tip-date { font-weight: 800; color: var(--ink-2); }
.chart__tip-row {
  display: flex; justify-content: space-between; gap: 10px;
  color: var(--ink-2);
}
.chart__tip-row b { color: var(--ink); font-variant-numeric: tabular-nums; }
.chart__tip-row--none { color: var(--ink-3); }

.chart__days { position: relative; height: 1.5em; margin-top: 2px; }
.chart__day {
  position: absolute; left: var(--x); translate: -50% 0;
  font-size: 11px; font-weight: 700; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.chart__legend { display: flex; gap: var(--s2); flex-wrap: wrap; }
/* 凡例は押せる。その人だけの棒に絞るための入口なので、見た目もボタンに寄せる。 */
.chart__who {
  display: inline-flex; align-items: center;
  padding: 3px 9px 3px 7px; border-radius: var(--r-pill);
  border: 1px solid transparent; background: transparent;
  color: var(--ink-2); font: inherit; font-size: 12px; font-weight: 700;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.chart__who:hover { background: var(--paper-sunk); color: var(--ink); }
.chart__who.is-only {
  background: var(--brand-tint);
  border-color: color-mix(in srgb, var(--brand) 30%, transparent);
  color: var(--ink);
}
.chart__swatch { width: 11px; height: 11px; border-radius: 3px; display: inline-block; margin-right: 5px; }

/* ===== タブ ===================================================== */
.tabs {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  gap: 3px; padding: 4px;
  background: var(--paper-sunk); border-radius: var(--r-pill);
  border: 1px solid var(--line);
}
.tabs a, .tabs button {
  border: 0; background: transparent; cursor: pointer;
  padding: 9px 6px; border-radius: var(--r-pill);
  font-size: 13.5px; font-weight: 700; color: var(--ink-2); text-align: center;
  text-decoration: none; transition: background-color .15s ease, color .15s ease;
}
.tabs a:hover { text-decoration: none; }
.tabs [aria-selected="true"], .tabs .is-active {
  background: var(--card-raised); color: var(--brand); box-shadow: var(--shadow-sm);
}

/* 種目の切り替えタブ。セクションの上に置くので、少し引き締めて出す。 */
/* 達成度（種目をまたいだ日単位の話）と、その下の種目ごとの集計は
   意味合いが違う。ひとつ内側の枠に落として、話が変わったことを見せる。 */
.byexercise {
  margin-top: var(--s7);
  padding: var(--s5);
  border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--paper-sunk) 45%, var(--card));
  border: 1px solid var(--line);
  overflow-x: clip;
}
.byexercise > [data-tabs-target="panel"] > .section + .section { margin-top: var(--s7); }
@media (max-width: 520px) { .byexercise { padding: var(--s4); border-radius: var(--r-md); } }

/* 端のぼかし幅。型を宣言しておかないと滑らかに変わらない
   （登録していないカスタムプロパティは補間できず、いきなり切り替わる）。 */
@property --fade-start {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}
@property --fade-end {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

/* 横に流れる領域。タブと「本日」のリングで共通に使う。 */
.hscroll {
  overflow-x: auto;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
  /* 中身の合計幅が外へ伝わらないようにする。これが無いと、並んだものの
     合計がセクション → ゾーン → ページと押し上がって画面全体がはみ出す。
     横に流すのはこの箱の中の話なので、ここで断ち切る。 */
  contain: inline-size;
  /* 端のフェードで「まだ続きがある」ことを見せる。
     幅は JS がスクロール位置に応じて出し入れする。 */
  --fade-start: 0px;
  --fade-end: 0px;
  -webkit-mask-image: linear-gradient(to right,
    transparent 0, #000 var(--fade-start),
    #000 calc(100% - var(--fade-end)), transparent 100%);
  mask-image: linear-gradient(to right,
    transparent 0, #000 var(--fade-start),
    #000 calc(100% - var(--fade-end)), transparent 100%);
  transition: --fade-start .15s linear, --fade-end .15s linear;
}
.hscroll::-webkit-scrollbar { display: none; }
.hscroll.has-before { --fade-start: 28px; }
.hscroll.has-after  { --fade-end: 28px; }

/* 流せる向きに出す矢印。流れる領域の外側に置く（中に入れると一緒に流れる）。 */
.hscroll-box { position: relative; }
.hscroll-arrow {
  position: absolute; top: 50%; right: auto; translate: 0 -50%;
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--brand); background: var(--card);
  box-shadow: 0 1px 4px -1px rgba(21, 26, 46, 0.25), 0 0 0 1px var(--line);
  opacity: 0; pointer-events: none;
  transition: opacity .15s ease;
}
.hscroll-arrow svg { width: 13px; height: 13px; }
.hscroll-arrow--before { left: 2px; }
.hscroll-arrow--after  { left: auto; right: 2px; }
.hscroll-box.has-before .hscroll-arrow--before { opacity: 1; }
.hscroll-box.has-after  .hscroll-arrow--after  { opacity: 1; }

.tabscroll { margin: 0 0 var(--s5); }

.exercise-tabs {
  margin: 0;
  /* 種目名は省略しない。全部が収まるうちは均等に割り、
     収まらなくなったら横に流す（minmax の下限が max-content なので、
     名前より狭くはならない）。 */
  grid-auto-columns: minmax(max-content, 1fr);
  background: var(--card);
}
.exercise-tabs.has-before { --fade-start: 30px; }
.exercise-tabs.has-after  { --fade-end: 30px; }

/* 「あなた」側の記録／カレンダーの切り替え。
   2つしかないので、横幅いっぱいを半分ずつ分ける。見せ方は累計のタブと揃える。 */
.metabs { background: var(--card); }



.exercise-tabs button,
.metabs button {
  white-space: nowrap;
  transition: background .18s ease, color .18s ease, box-shadow .18s ease;
}
/* 選択中はブランドのグラデーションで塗りつぶす。
   白地に白の浮きカードだと、どれを見ているのか分からなかった。 */
.exercise-tabs [aria-selected="true"],
.exercise-tabs .is-active,
.metabs [aria-selected="true"],
.metabs .is-active {
  background: var(--gradient);
  color: #fff;
  box-shadow: var(--glow), inset 0 1px 0 rgba(255, 255, 255, 0.3);
}
.exercise-tabs button:not(.is-active):hover,
.metabs button:not(.is-active):hover { background: var(--paper-sunk); color: var(--ink); }

/* タブを押したとき、押した向きから滑り込ませる。
   どこへ移ったのかが動きで分かる。 */
[data-tabs-target="panel"].is-in-right { animation: panel-in-right .26s cubic-bezier(.2, .8, .2, 1); }
[data-tabs-target="panel"].is-in-left  { animation: panel-in-left  .26s cubic-bezier(.2, .8, .2, 1); }
@keyframes panel-in-right {
  from { opacity: 0; transform: translateX(18px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes panel-in-left {
  from { opacity: 0; transform: translateX(-18px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* ===== 今日のカード：種目が複数のとき =========================== */
/* 左に「日付・見出し・連続日数」、右端に応援の印。
   中身の高さが違うので、上揃えではなく中央で合わせる。 */
.today__head { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; }

/* 1種目のときの「種目名 → 記録ボタン」。カードの他の要素より間を詰める。 */
.tapblock { display: grid; gap: var(--s2); }
.tapname { display: flex; align-items: baseline; gap: var(--s3); }
.tapname__name { font-size: 15px; font-weight: 800; letter-spacing: -0.01em; }
.tapname__goal {
  margin-left: auto; flex: none;
  font-size: 12.5px; font-weight: 700; color: var(--ink-3);
}

.exlist { display: grid; gap: var(--s3); }

/* 種目1つぶん。左にリング、真ん中に名前と目標、右に記録ボタン。 */
.ex {
  display: grid;
  /* 上の行は種目名で使い切る（省略すると何の種目か分からなくなるため）。
     下の行はリングと記録ボタン。左の列がリングぶんの固定幅なので、
     ボタンの幅は種目名の長さに関係なく全種目で揃う。 */
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "head head"
    "ring btn";
  align-items: center;
  column-gap: var(--s3); row-gap: var(--s2);
  padding: var(--s3) var(--s4);
  border-radius: var(--r-md);
  background: var(--card);
  border: 1px solid var(--line);
}
.ex--done { background: color-mix(in srgb, var(--gold-fill) 14%, var(--card));
            border-color: color-mix(in srgb, var(--gold) 32%, transparent); }
/* 金はその日のクリアの印。任意の種目は満ちても、ブランドの色のままにする。 */
.ex--done.ex--optional {
  background: color-mix(in srgb, var(--brand) 8%, var(--card));
  border-color: color-mix(in srgb, var(--brand) 26%, transparent);
}
.ex--done.ex--optional .exring__num,
.ex--done.ex--optional .ex__amount { color: var(--brand); }
.ex--optional .ex__check { background: var(--gradient); }

.ex--optional { border-style: dashed; }

/* 1種目のときの大きなリングと同じ作り。太さだけ小さい円に合わせてある。 */
.exring { grid-area: ring; position: relative; width: 62px; aspect-ratio: 1; }
.exring > svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.exring__track { fill: none; stroke: var(--paper-sunk); stroke-width: 14; }
.exring__fill { fill: none; stroke-width: 14; stroke-linecap: round; }
.exring__fill.is-done { filter: drop-shadow(0 0 5px var(--gold-tint-2)); }
.exring__num {
  position: absolute; inset: 0;
  display: grid; place-content: center;
  font-size: 18px; font-weight: 800; letter-spacing: -0.03em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.ex--done .exring__num { color: var(--gold); }
/* スタンプの種目。中央は数ではなく印。 */
.exring__check {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  color: var(--ink-3); opacity: .35;
}
.exring__check.is-done { color: var(--gold); opacity: 1; }
.exring__check svg { width: 26px; height: 26px; }

.ex__head {
  grid-area: head;
  display: flex; align-items: center; flex-wrap: wrap; gap: 7px; min-width: 0;
}
/* 省略しない。長ければ折り返して2行になってよい。 */
.ex__name { font-size: 15px; font-weight: 800; letter-spacing: -0.01em; }
.ex__check {
  flex: none; width: 18px; height: 18px; border-radius: 50%;
  display: grid; place-items: center;
  color: #fff; background: var(--gold-gradient);
}
.ex__check svg { width: 11px; height: 11px; }
.ex__amount {
  margin-left: auto; flex: none;
  font-size: 12.5px; font-weight: 700; color: var(--ink-3);
}
.ex--done .ex__amount { color: var(--gold); }

.ex .tap-slot { grid-area: btn; }

/* 記録ボタンは最後まで残る主役なので、与えられた幅をめいっぱい使う。 */
.tap-slot--inline,
.tap-slot--inline form { width: 100%; }
.tap-slot--inline .tap--sm {
  min-height: 54px; font-size: 17px; gap: 8px;
  box-shadow: 0 8px 18px -9px var(--brand-tint-2), inset 0 1px 0 rgba(255,255,255,.28);
}
.tap-slot--inline .tap--sm .tap__num { font-size: 24px; }
.tap-slot--inline .tap--sm .tap__unit { font-size: 14px; }

/* 今日の記録の明細に種目名を添える */
.log__ex {
  font-size: 11.5px; font-weight: 700; color: var(--ink-3);
  margin-right: 6px;
}

/* 日別ダイアログの種目まとめ */
.daylog { display: grid; gap: 2px; }
.daylog + .daylog { margin-top: var(--s3); }
.daylog__head { display: flex; align-items: baseline; gap: var(--s2); }
.daylog__name { font-size: 13.5px; font-weight: 800; }
.daylog__total {
  margin-left: auto; font-size: 12px; font-weight: 700; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.daylog__total.is-done { color: var(--gold); }

/* 設定画面の種目1件ぶん。削除は編集フォームの外に出す必要があるので、
   見出し行を作ってそこに置く。 */
.exrow {
  display: grid; gap: var(--s3);
  padding: var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--paper-sunk) 35%, var(--card));
}
/* 必須の種目は行ごと色を変える。並べたときに、どれがクリア判定に効くのかが
   ラベルを読まなくても分かる。 */
.exrow--must {
  background: color-mix(in srgb, var(--violet) 9%, var(--card));
  border-color: color-mix(in srgb, var(--violet) 28%, transparent);
}

.exrow__head { display: flex; align-items: center; gap: var(--s2); }
.exrow__title {
  font-size: 15px; font-weight: 800; letter-spacing: -0.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.exrow__delete { margin-left: auto; }

/* 追加の欄。並んでいる種目と同じ見た目だと、どこからが記入欄なのか分からない。
   枠を破線にして地をブランド寄りに振り、「これから書くところ」だと示す。 */
.exadd {
  margin-top: var(--s5);
  padding: var(--s4);
  border: 1px dashed var(--brand-tint-2);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--brand-tint) 60%, var(--card));
}
.exadd__head { display: flex; align-items: center; gap: var(--s2); margin-bottom: 2px; }
.exadd__icon {
  flex: none;
  width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center;
  color: #fff; background: var(--gradient);
}
.exadd__icon svg { width: 14px; height: 14px; }
.exadd__title { font-size: 15px; font-weight: 800; letter-spacing: -0.01em; color: var(--brand-deep); }

/* ===== 取り返しのつかない操作 =================================== */
/* 押し間違いを避けたいので、畳んでおく。開くまでボタンは見えない。 */
.danger {
  border: 1px solid color-mix(in srgb, var(--warn) 35%, transparent);
  border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--warn) 5%, var(--card));
}
@media (max-width: 520px) { .danger { border-radius: var(--r-md); } }
.danger__head {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s4);
}
.danger__head::-webkit-details-marker { display: none; }
.danger__icon {
  flex: none; width: 22px; height: 22px; color: var(--warn);
}
.danger__icon svg { width: 100%; height: 100%; }
.danger__title { font-size: 15px; font-weight: 800; color: var(--warn); }
.danger__toggle {
  margin-left: auto; flex: none;
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--warn); background: var(--warn-tint);
  transition: transform .2s ease;
}
.danger__toggle svg { width: 15px; height: 15px; }
.danger[open] .danger__toggle { transform: rotate(180deg); }
.danger__body {
  display: grid; gap: var(--s4);
  padding: 0 var(--s4) var(--s4);
}

/* 消すためのボタンだけは塗りつぶす。取り消しがきかないと分かるように。 */
.btn--danger-solid {
  background: var(--warn); color: #fff; border-color: transparent;
  box-shadow: 0 6px 16px -8px color-mix(in srgb, var(--warn) 70%, transparent);
}
.btn--danger-solid:hover { filter: brightness(1.05); }

/* ===== リスト（設定画面） ======================================= */
.list { display: grid; }
.list__item {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) 0; border-top: 1px solid var(--line);
  flex-wrap: wrap;
}
.list__item:first-child { border-top: 0; }
.list__main { flex: 1 1 200px; min-width: 0; display: grid; gap: 2px; }
.list__actions { display: flex; gap: var(--s2); flex-wrap: wrap; }

.token {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 12.5px; word-break: break-all; color: var(--ink-2);
  background: var(--paper-sunk); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 7px 10px;
}
.token--secret {
  font-size: 20px; font-weight: 700; letter-spacing: .12em; color: var(--ink);
  text-align: center; padding: 12px;
}

/* ===== ダイアログ =============================================== */
dialog.sheet-dialog {
  /* いま見えている画面の真ん中に出す。
     ブラウザ既定に任せると、端末によってはページの上のほうに置かれてしまい、
     暗くなっただけで中身が見えない（そこまでスクロールしないと出てこない）。 */
  position: fixed; inset: 0; margin: auto;
  border: 0; padding: 0; background: transparent;
  max-width: 420px; width: calc(100% - 32px);
  /* 画面より高くなったら、ダイアログの中だけを送る。 */
  max-height: calc(100dvh - 32px); overflow: auto;
  overscroll-behavior: contain;
  color: var(--ink);
}
dialog.sheet-dialog::backdrop {
  background: rgba(10, 13, 26, .5);
  backdrop-filter: blur(3px);
}
.dialog__panel {
  background: var(--card-raised);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  padding: var(--s5);
  display: grid; gap: var(--s4);
  box-shadow: var(--shadow-lg);
  animation: dialog-in .22s cubic-bezier(.2,.9,.3,1.1);
}
@keyframes dialog-in { from { opacity: 0; transform: translateY(14px) scale(.97); } }
.dialog__title { font-size: 18px; font-weight: 800; }
/* 他の人の台紙を開いたときに、誰のものかを日付の下に添える。 */
.dialog__who {
  display: block; margin-top: 2px;
  font-size: 12.5px; font-weight: 700; color: var(--ink-3);
}
.dialog__actions { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s3); }

/* 見出しの右に置く閉じるボタン。取り消しのきかない操作の隣に
   並べたくないときに使う。 */
.dialog__close {
  flex: none;
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  padding: 0; border: 0; background: transparent; color: var(--ink-3);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color .12s ease, color .12s ease;
}
.dialog__close:hover { background: var(--paper-sunk); color: var(--ink); }
.dialog__close svg { width: 15px; height: 15px; }

/* ===== ランディング ============================================= */
.lp { display: grid; gap: var(--s8); }
@media (max-width: 640px) { .lp { gap: var(--s7); } }

/* --- ヒーロー ---
   キービジュアルを最上段に大きく置き、その下に見出しと導線を中央揃えで積む。
   名前も雰囲気も絵が伝えるので、文字は言うべきことだけに絞る。 */
.lp-hero {
  position: relative;
  display: grid; gap: var(--s4); justify-items: center; text-align: center;
  padding: var(--s5) 0 var(--s6);
}
.lp-hero__kv {
  width: min(100%, 620px); height: auto;
  margin-bottom: calc(-1 * var(--s4));   /* 絵の余白ぶん、見出しを寄せる */
}
@media (max-width: 520px) { .lp-hero__kv { width: min(112%, 480px); } }

/* 背後の光。地のグラデーションを一段強めて、上部に視線を集める。 */
.lp-hero__glow {
  position: absolute; z-index: -1; pointer-events: none;
  inset: -10% -14% auto -14%; height: 70%;
  background:
    radial-gradient(closest-side, color-mix(in srgb, var(--aqua) 34%, transparent), transparent) -6% 0 / 62% 100% no-repeat,
    radial-gradient(closest-side, color-mix(in srgb, var(--violet) 30%, transparent), transparent) 104% 22% / 58% 100% no-repeat;
  filter: blur(38px);
}

.lp-hero__copy { display: grid; gap: var(--s4); justify-items: center; }
.lp-hero__title {
  font-size: clamp(34px, 7.4vw, 60px);
  font-weight: 800; line-height: 1.16; letter-spacing: -0.045em;
  color: var(--ink);
}
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .lp-hero__title {
    background: var(--gradient-text);
    -webkit-background-clip: text; background-clip: text;
    color: transparent; -webkit-text-fill-color: transparent;
  }
}
.lp-hero__lede { font-size: 15.5px; color: var(--ink-2); line-height: 1.9; max-width: 44ch; }
.lp-hero__actions { display: grid; gap: 10px; justify-items: center; margin-top: 4px; }
.lp-hero__note { font-size: 12.5px; color: var(--ink-3); }
.btn--lg { min-height: 56px; padding: 0 30px; font-size: 16.5px; }

/* --- 台紙のプレビュー --- */
.lp-preview {
  display: grid; gap: 11px;
  padding: var(--s5);
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  border: 1px solid var(--glass-border);
  box-shadow: var(--shadow-lg), inset 0 1px 0 var(--glass-highlight);
}
.lp-preview__head { display: flex; align-items: baseline; gap: var(--s3); }
.lp-preview__month { font-size: 18px; font-weight: 800; letter-spacing: -0.02em; }
.lp-preview__score {
  margin-left: auto; font-size: 12px; font-weight: 700; color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.lp-preview__week,
.lp-preview__grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.lp-preview__week > span {
  text-align: center; font-size: 10.5px; font-weight: 800; color: var(--ink-3);
}
.lp-preview__cell {
  aspect-ratio: 1; border-radius: 8px;
  background: var(--glass-tile);
  border: 1px solid var(--glass-tile-border);
  animation: preview-pop .45s cubic-bezier(.2, 1.3, .4, 1) backwards;
  animation-delay: var(--delay, 0ms);
}
.lp-preview__cell--blank { background: transparent; border-color: transparent; animation: none; }
.lp-preview__cell--future { background: transparent; border: 1px dashed var(--glass-tile-border); }
.lp-preview__cell--partial { background: color-mix(in srgb, var(--brand) 22%, var(--card)); border-color: transparent; }
.lp-preview__cell--missed { background: color-mix(in srgb, var(--glass-tile) 55%, transparent); }
/* 達成した日。金で埋まっていく様子がこのページの主張そのもの。 */
.lp-preview__cell--done {
  background: var(--gold-gradient);
  border-color: transparent;
  box-shadow: 0 2px 6px -2px color-mix(in srgb, var(--gold) 55%, transparent);
}
@keyframes preview-pop { from { opacity: 0; transform: scale(.6); } }

/* --- 実物を見せる節 --- */
.lp-showcase {
  display: grid; gap: var(--s6);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
}
@media (max-width: 820px) { .lp-showcase { grid-template-columns: 1fr; gap: var(--s5); } }
.lp-showcase__copy { display: grid; gap: var(--s3); }
.lp-showcase__text { font-size: 14.5px; color: var(--ink-2); line-height: 1.9; }

/* URL を貼って入る欄。横に置けるうちは並べ、狭くなったら縦に積む。 */
.enter-form { display: flex; gap: var(--s3); align-items: stretch; }
.enter-form .input { min-width: 0; }
.enter-form .btn { flex: none; }
@media (max-width: 520px) { .enter-form { flex-direction: column; } }

/* --- 特長 --- */
/* 枚数が変わっても等幅に並ぶようにしておく */
.lp-features {
  display: grid; gap: var(--s4);
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}
.lp-feature {
  display: grid; gap: 10px; align-content: start;
  padding: var(--s5);
  border-radius: var(--r-lg);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
}
.lp-feature__icon {
  width: 40px; height: 40px; border-radius: 12px;
  display: grid; place-items: center;
  background: var(--gradient); color: #fff;
  box-shadow: var(--glow), inset 0 1px 0 rgba(255, 255, 255, 0.3);
}
.lp-feature__icon svg { width: 21px; height: 21px; }
.lp-feature__title {
  font-size: clamp(20px, 3.4vw, 25px);
  font-weight: 800; letter-spacing: -0.03em; line-height: 1.25;
  color: var(--ink);
}
.lp-feature__text { font-size: 13.5px; color: var(--ink-2); line-height: 1.85; }

/* --- 節と手順 --- */
.lp-section { display: grid; gap: var(--s4); }
/* 節の見出し。飾りを足すより、文字そのものを大きくして色を乗せる。 */
.lp-section__title {
  font-size: clamp(26px, 5vw, 34px);
  font-weight: 800; letter-spacing: -0.035em; line-height: 1.25;
  color: var(--ink);
}

.lp-steps { display: grid; gap: var(--s4); grid-template-columns: repeat(3, 1fr); }
@media (max-width: 820px) { .lp-steps { grid-template-columns: 1fr; } }
.lp-step {
  display: grid; gap: 6px; align-content: start;
  padding-top: var(--s3);
  border-top: 2px solid var(--line);
}
.lp-step__no {
  font-size: 13px; font-weight: 800; color: var(--brand);
  font-variant-numeric: tabular-nums; letter-spacing: 0.08em;
}
.lp-step__title { font-size: 16px; font-weight: 800; letter-spacing: -0.01em; }
.lp-step__text { font-size: 13.5px; color: var(--ink-2); line-height: 1.8; }

/* --- 締めの案内 --- */
@supports (background-clip: text) or (-webkit-background-clip: text) {
  .lp-section__title,
  .lp-feature__title {
    background: var(--gradient-text);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}

.lp-cta {
  border-radius: var(--r-lg);
  background: linear-gradient(135deg, #23345f 0%, #35306b 55%, #452c68 100%);
  color: #fff;
  padding: var(--s7) var(--s5);
  box-shadow: var(--shadow-lg);
}
.lp-cta__inner { display: grid; gap: var(--s3); justify-items: center; text-align: center; max-width: 46ch; margin-inline: auto; }
/* 濃紺の帯の上なので、ここだけは白のまま大きくする
   （文字用のグラデーションは白地向けに暗く落としてあり、この上では読めない） */
.lp-cta__title { font-size: clamp(24px, 4.6vw, 32px); font-weight: 800; letter-spacing: -0.035em; }
.lp-cta__text { font-size: 13.5px; line-height: 1.9; color: rgba(255, 255, 255, 0.82); }
.lp-cta__btn {
  margin-top: var(--s2);
  background: #fff; color: #23345f; border-color: transparent;
}
.lp-cta__btn:hover { background: #fff; filter: brightness(.96); }

.room-card {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s4); border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--card); color: inherit; text-decoration: none;
  transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.room-card:hover {
  text-decoration: none; transform: translateY(-1px);
  box-shadow: var(--shadow-md); border-color: var(--brand-tint-2);
}
.room-card__arrow { color: var(--ink-3); font-size: 18px; }

/* 切り替えのダイアログに並べるときは、一覧として詰めて出す。 */
.room-card--sm { padding: var(--s3); gap: var(--s2); }
.room-card--sm .seal-mark { width: 32px; height: 32px; }
.room-card--sm .subtitle { font-size: 14px; }
.room-card--sm.is-here { border-color: var(--brand); background: var(--brand-tint); }

/* いまログイン状態が残っているルームの目印。期間表示のあとに小さく添える。 */
.room-card__open {
  display: inline-block; margin-left: 6px; padding: 1px 7px;
  border-radius: 999px; background: var(--brand-soft); color: var(--brand-deep);
  font-size: 11px; font-weight: 700; letter-spacing: .02em; vertical-align: 1px;
}

/* ===== 帯の開閉（メンバーごとの台紙） =========================== */
/* ===== 進捗リングの動き ========================================= */
/* 描く動きと、きらめきの走行は ring コントローラの担当。
   量が要素ごとに違うので、CSS の keyframes では補間できない。
   ここでは動きの土台（回転の中心）と、光の見た目だけを決める。 */
.today__ring-fill,
.exring__fill { transform-box: fill-box; transform-origin: center; }

/* 溜まっているぶんの上を、ときどき光がひと息で走る。
   走らせるのは ring コントローラ（CSS の keyframes に var() を挟むと
   補間が効かず、始点と終点で光っただけに見えてしまうため）。
   ここでは見た目だけを決める。 */
.ring-shine {
  fill: none; stroke: #fff; stroke-linecap: round;
  opacity: 0; pointer-events: none;
  /* 短すぎると軌跡が追えないので、円周の6%ぶんくらいの長さにする。 */
  stroke-dasharray: 22 calc(var(--dash) - 22);
  filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.9));
}
.today__ring .ring-shine { stroke-width: 12; }
.exring .ring-shine { stroke-width: 14; }

/* ===== ヤルヤン（仲間への応援） ================================= */
/* 見た目は他のボタンと同じ .btn。ゲージと弾けるエフェクトだけを足す。 */
.yaruyan { position: relative; min-width: 0; display: inline-flex; }
.yaruyan form { display: inline; margin: 0; }
.yaruyan__btn { position: relative; overflow: hidden; }
.yaruyan__label, .yaruyan__count { position: relative; }
.yaruyan__count {
  font-variant-numeric: tabular-nums; min-width: 1.4em; text-align: right;
  display: inline-block; opacity: .85;
}

/* 押してから次に押せるまでを、左から満ちるゲージで見せる。
   時間は Yaruyan::COOLDOWN を JS 経由で受け取る（--yaruyan-cooldown）。 */
.yaruyan__fill {
  position: absolute; inset: 0;
  transform: scaleX(0); transform-origin: left center;
  background: rgba(255, 255, 255, 0.34);
  pointer-events: none;
}
.yaruyan__btn.is-cooling .yaruyan__fill {
  animation: yaruyan-fill var(--yaruyan-cooldown, 3s) linear forwards;
}
@keyframes yaruyan-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* 待っている間。押せないことは触れないことで示し、
   何が起きているかは読めるだけの濃さを残す。 */
.yaruyan__btn.is-cooling {
  pointer-events: none; cursor: default;
  filter: saturate(.7); opacity: .85;
}

.yaruyan__btn.is-full {
  background: var(--gold-gradient); color: #fff;
  border-color: transparent; box-shadow: none;
}
.yaruyan__btn.is-full[disabled] { opacity: .92; }

/* --- 押した瞬間の手応え。リングが弾け、ボタンと数字が一度だけ跳ねる。 --- */
.yaruyan__burst {
  position: absolute; inset: 0;
  border-radius: var(--r-pill);
  pointer-events: none; opacity: 0;
}
.yaruyan.is-bursting .yaruyan__burst {
  animation: yaruyan-burst .5s cubic-bezier(.16, .84, .34, 1) forwards;
}
@keyframes yaruyan-burst {
  0%   { opacity: .9;  transform: scale(.96);
         box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand) 65%, transparent); }
  60%  { opacity: .4; }
  100% { opacity: 0;   transform: scale(1.34);
         box-shadow: 0 0 0 18px color-mix(in srgb, var(--brand) 0%, transparent); }
}

.yaruyan.is-bursting .yaruyan__btn {
  animation: yaruyan-pop .38s cubic-bezier(.2, .9, .25, 1.6);
}
@keyframes yaruyan-pop {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.1); }
  100% { transform: scale(1); }
}

.yaruyan.is-bursting .yaruyan__count {
  animation: yaruyan-bump .42s cubic-bezier(.2, .9, .25, 1.6);
}
@keyframes yaruyan-bump {
  0%   { transform: translateY(0) scale(1); }
  30%  { transform: translateY(-4px) scale(1.3); }
  100% { transform: translateY(0) scale(1); }
}

/* 送ったぶんが飛んでいく「+1」。 */
.yaruyan__plus {
  position: absolute; left: 50%; top: 2px;
  transform: translate(-50%, 0); opacity: 0;
  font-size: 12px; font-weight: 800; color: var(--brand);
  pointer-events: none; white-space: nowrap;
  text-shadow: 0 1px 0 var(--card);
}
.yaruyan.is-bursting .yaruyan__plus {
  animation: yaruyan-plus .72s cubic-bezier(.2, .8, .3, 1) forwards;
}
@keyframes yaruyan-plus {
  0%   { opacity: 0; transform: translate(-50%, 2px)   scale(.7); }
  22%  { opacity: 1; transform: translate(-50%, -13px) scale(1.15); }
  100% { opacity: 0; transform: translate(-50%, -30px) scale(1); }
}

/* 動きを抑える設定のときは、跳ねさせずに薄さだけで「待ち」を示す。 */
@media (prefers-reduced-motion: reduce) {
  .yaruyan__btn.is-cooling .yaruyan__fill { animation: none; transform: scaleX(1); }
  .yaruyan.is-bursting .yaruyan__burst,
  .yaruyan.is-bursting .yaruyan__btn,
  .yaruyan.is-bursting .yaruyan__count,
  .yaruyan.is-bursting .yaruyan__plus { animation: none; }
}

@media (max-width: 560px) {
  .yaruyan { min-width: 96px; }
  .yaruyan__btn { min-height: 32px; padding: 0 11px; font-size: 12px; }
}

/* ===== 通知の入り切り ============================================ */
/* ヘッダーのすぐ下。普段は静かに、押せる状態のときだけ色を持たせる。 */
.pushbar { display: flex; justify-content: flex-end; margin-bottom: var(--s3); }
.pushbar__btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--line-strong); border-radius: var(--r-pill);
  background: var(--card); color: var(--ink-2);
  font: inherit; font-size: 12.5px; font-weight: 700;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.pushbar__btn:hover:not(:disabled) { border-color: var(--brand); color: var(--brand); }
.pushbar__btn:disabled { cursor: default; opacity: .6; }
.pushbar__icon { display: grid; place-items: center; width: 15px; height: 15px; flex: none; }
.pushbar__icon svg { width: 100%; height: 100%; }

.pushbar[hidden] { display: none; }

/* 通知の設定（ヘッダーのベルから開く） */
.pushset { display: grid; gap: var(--s3); }
.pushset__row { display: flex; align-items: center; gap: var(--s3); }
.pushset__name { font-size: 14.5px; font-weight: 800; letter-spacing: -0.01em; }

/* ===== 選ぶ欄（取り組む種目） =================================== */
/* 素のチェックボックスだと的が小さいので、行ごと押せる札にする。 */
.pickers { display: grid; gap: 6px; }
.picker {
  display: flex; align-items: center; gap: var(--s3);
  padding: 10px var(--s3);
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--card);
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}
.picker:hover { border-color: var(--brand-tint-2); }
/* 素のチェックは隠す。押されたかどうかは右の丸で見せる。 */
.picker input { position: absolute; opacity: 0; width: 0; height: 0; }
.picker__body { display: grid; gap: 1px; min-width: 0; flex: 1; }
.picker__name { font-size: 14px; font-weight: 800; letter-spacing: -0.01em; }
.picker__meta { font-size: 11.5px; font-weight: 700; color: var(--ink-3); }
.picker__mark {
  flex: none;
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  border: 1.5px solid var(--line-strong);
  color: transparent; background: var(--card);
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.picker__mark svg { width: 12px; height: 12px; }

/* 選ばれている行。地を薄く染めて、右の丸に印を入れる。 */
.picker:has(input:checked) {
  background: var(--brand-tint);
  border-color: var(--brand-tint-2);
}
.picker:has(input:checked) .picker__mark {
  background: var(--gradient); border-color: transparent; color: #fff;
}
.picker:has(input:focus-visible) { box-shadow: var(--ring); }

/* 2択を横に並べるとき（数え方など）。 */
.pickers--row { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
.picker--sm { padding: 8px 10px; gap: var(--s2); }
.picker--sm .picker__name { font-size: 13px; }
.picker--sm .picker__meta { font-size: 10.5px; }
.picker--sm .picker__mark { width: 19px; height: 19px; }
.picker--sm .picker__mark svg { width: 10px; height: 10px; }
@media (max-width: 420px) { .pickers--row { grid-auto-flow: row; } }

/* 名前を並べて選ぶ欄。人数ぶん横に並べたいので、札は小さく。 */
.chippicks { display: flex; flex-wrap: wrap; gap: 6px; }
.chippick {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 11px 5px 8px;
  border: 1px solid var(--line-strong); border-radius: var(--r-pill);
  background: var(--card); color: var(--ink-2);
  font-size: 12.5px; font-weight: 700;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.chippick:hover { border-color: var(--brand-tint-2); }
.chippick input { position: absolute; opacity: 0; width: 0; height: 0; }
.chippick__mark {
  flex: none;
  width: 16px; height: 16px; border-radius: 50%;
  display: grid; place-items: center;
  border: 1.5px solid var(--line-strong);
  color: transparent; background: var(--card);
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.chippick__mark svg { width: 9px; height: 9px; }
.chippick:has(input:checked) {
  background: var(--brand-tint); border-color: var(--brand-tint-2); color: var(--brand-deep);
}
.chippick:has(input:checked) .chippick__mark {
  background: var(--gradient); border-color: transparent; color: #fff;
}
.chippick:has(input:focus-visible) { box-shadow: var(--ring); }

/* ===== 今日のひとこと ============================================ */
.mood { display: grid; gap: 5px; margin-bottom: var(--s4); min-width: 0; }
.mood__label {
  display: flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 800; color: var(--ink-3); letter-spacing: .02em;
}
.mood__icon { flex: none; width: 15px; height: 15px; color: var(--brand); }
.mood__icon svg { width: 100%; height: 100%; }
.mood__field { position: relative; min-width: 0; }
.mood__input {
  /* input は中身に応じた固有の幅を持つ。min-width を切っておかないと、
     親の grid がその幅まで広がってページを押し出すことがある。 */
  width: 100%; max-width: 100%; min-width: 0; min-height: 46px;
  padding: 10px 40px 10px 13px;
  background: var(--card-raised);
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  /* 16px を下回らせない。iOS は小さい文字の入力欄にふれると勝手に拡大し、
     離れても戻らないので、ページが画面幅からはみ出したままになる。 */
  color: var(--ink); font: inherit; font-size: 16px;
}
.mood__input::placeholder { color: var(--ink-3); }
.mood__input:focus { outline: none; box-shadow: var(--ring); border-color: var(--brand); }
.is-failed .mood__input { border-color: var(--warn); }

/* 書けたことの合図。出しっぱなしにせず、すっと出てすっと消える。 */
.mood__mark {
  position: absolute; top: 50%; right: 12px; translate: 0 -50%;
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center;
  color: #fff; background: var(--gradient);
  opacity: 0; scale: .6;
  transition: opacity .18s ease, scale .18s cubic-bezier(.2, .9, .3, 1.5);
  pointer-events: none;
}
.mood__mark.is-shown { opacity: 1; scale: 1; }
.mood__mark svg { width: 11px; height: 11px; }
.mood__error { font-size: 12px; font-weight: 700; color: var(--warn); }
.mood__error:empty { display: none; }

/* 帯の下に置く、その人のひとこと。 */
.bubble {
  position: relative;
  /* 行の幅いっぱいに置く。左だけ空けると、リングの列と縁が揃わず落ち着かない。 */
  margin: 2px 0;
  padding: 7px 11px;
  border-radius: var(--r-md);
  background: var(--paper-sunk);
  color: var(--ink-2);
  font-size: 13px; line-height: 1.55;
  overflow-wrap: anywhere;
}
/* 上に小さな三角。誰の言葉かを、真上のアバターに結びつける。 */
.bubble::before {
  content: ""; position: absolute; top: -5px; left: 16px;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 6px solid var(--paper-sunk);
}


.strip-item { padding: 3px 0; min-width: 0; }
.strip-item > summary {
  list-style: none; cursor: pointer; border-radius: var(--r-sm);
  /* 左右の負マージンは親より外に出るぶん、そのままページのはみ出しになる。
     上下だけ広げて、横は親の幅に収める。 */
  padding: 4px; margin: -4px 0;
}
.strip-item > summary::-webkit-details-marker { display: none; }
.strip-item > summary:hover { background: var(--paper-sunk); }
.strip-item[open] > summary .strip__name { color: var(--brand); }
.strip__detail { padding: var(--s4) 0 var(--s3); min-width: 0; }

/* ===== 新しく入れてもらった種目 ================================== */
/* 自分のメニューを開いたときに一度だけ出る知らせ。 */
.newex {
  display: grid; gap: 7px;
  padding: 12px 14px; border-radius: var(--r-md);
  background: var(--brand-tint);
  border: 1px solid color-mix(in srgb, var(--brand) 26%, transparent);
}
.newex__title { font-size: 14.5px; font-weight: 800; color: var(--brand-deep); }
.newex__list { display: grid; gap: 4px; }
.newex__list li {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 7px;
}
.newex__name { font-size: 13.5px; font-weight: 800; }
.newex__meta { font-size: 12px; font-weight: 700; color: var(--ink-3); }
.newex__hint { font-size: 12px; color: var(--ink-2); }

/* 変えられない値を、欄と同じ場所に据え置きで見せる。 */
.fixedval { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }

/* ===== 種目ごとの決めごと（自分のメニュー） ====================== */
.modes { display: grid; gap: 7px; }
.mode {
  display: grid; gap: 6px;
  padding: 9px 11px; border-radius: var(--r-md);
  background: var(--paper-sunk); border: 1px solid var(--line);
}
.mode__head { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.mode__name { font-size: 13.5px; font-weight: 800; overflow-wrap: anywhere; }
.mode__meta { margin-left: auto; flex: none; font-size: 11.5px; font-weight: 700; color: var(--ink-3); }

/* 必須 / 任意 / やらない。3つでひと続きの切り替えにする。 */
.mode__picks {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px;
  padding: 3px; border-radius: var(--r-pill);
  background: var(--card); border: 1px solid var(--line);
}
.mode__pick {
  position: relative;
  display: grid; place-items: center;
  padding: 6px 4px; border-radius: var(--r-pill);
  font-size: 12px; font-weight: 800; color: var(--ink-3);
  cursor: pointer;
  transition: background .14s ease, color .14s ease;
}
.mode__pick input { position: absolute; opacity: 0; pointer-events: none; }
.mode__pick:hover { background: var(--paper-sunk); color: var(--ink); }
/* 選んだものだけ塗る。必須は達成の金、任意と「やらない」は静かに。 */
.mode__pick:has(input:checked) { background: var(--paper-sunk); color: var(--ink); }
.mode__pick--required:has(input:checked) {
  background: var(--gold-tint); color: var(--gold);
  box-shadow: inset 0 0 0 1px var(--gold-tint-2);
}
.mode__pick--skip:has(input:checked) { color: var(--ink-3); }
.mode__pick:has(input:focus-visible) { box-shadow: var(--ring); }

/* ===== 種目のお願い ============================================== */
/* メンバー側。自分のメニューの中なので、普段は畳んで1行に収める。 */
.askex {
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--paper-sunk);
}
.askex__head {
  display: flex; align-items: center; gap: var(--s2);
  padding: 10px 12px; cursor: pointer;
  list-style: none;
}
.askex__head::-webkit-details-marker { display: none; }
.askex__title { font-size: 13px; font-weight: 800; color: var(--ink-2); }
.askex__toggle {
  margin-left: auto; flex: none; width: 18px; height: 18px; color: var(--ink-3);
  transition: rotate .18s ease;
}
.askex__toggle svg { width: 100%; height: 100%; }
.askex[open] .askex__toggle { rotate: 180deg; }
.askex__body {
  display: grid; gap: var(--s3);
  padding: 0 12px 12px;
}
.askex__list { display: grid; gap: 6px; }
.askex__item {
  display: flex; align-items: center; gap: var(--s2);
  padding: 7px 10px; border-radius: var(--r-sm);
  background: var(--card-raised); border: 1px solid var(--line);
}
.askex__name { display: block; font-size: 13px; font-weight: 800; }
.askex__note { display: block; font-size: 11.5px; color: var(--ink-3); }

/* 主催者側。設定画面に届いたぶんを並べる。 */
.askrow {
  display: flex; align-items: center; gap: var(--s3);
  padding: 11px 13px; border-radius: var(--r-md);
  background: var(--brand-tint);
  border: 1px solid color-mix(in srgb, var(--brand) 24%, transparent);
}
.askrow__name {
  display: flex; align-items: center; flex-wrap: wrap; gap: 7px;
  font-size: 14.5px; font-weight: 800;
}
.askrow__spec { font-size: 12px; font-weight: 700; color: var(--ink-3); }
.askrow__actions { flex: none; display: flex; align-items: center; gap: 6px; }
/* 狭い画面では、名前とボタンを上下に分ける（横に並べると名前が潰れる）。 */
@media (max-width: 480px) {
  .askrow { flex-wrap: wrap; }
  .askrow__actions { width: 100%; justify-content: flex-end; }
}
.askrow__note { font-size: 12.5px; color: var(--ink-2); }

/* ===== はじめての人への案内 ====================================== */
/* ヘッダーの右上（自分のボタン）を指す吹き出し。
   読んでもらうまでは、そこと吹き出し以外を暗くして手を止める。 */
.guide {
  position: fixed; inset: 0;
  /* ヘッダー（案内中は 51）より下に敷く。ヘッダーはヘッダー自身で暗くする。 */
  z-index: 45;
  pointer-events: none;
}
/* 本文にかぶせる暗幕。押しても閉じない（読まずに進ませないため）。 */
.guide__shade {
  position: absolute; inset: 0;
  background: rgba(8, 10, 22, .58);
  pointer-events: auto;
  animation: guide-shade .22s ease both;
}
@keyframes guide-shade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ヘッダーは暗幕より上にいるので、自分で同じ濃さの影を敷く。 */
body.is-guiding .appbar { z-index: 51; pointer-events: none; }
body.is-guiding .appbar::after {
  content: ""; position: absolute; inset: 0;
  background: rgba(8, 10, 22, .58);
  pointer-events: none;
}
/* 指している先だけを、その影より上に出して押せるようにする。
   地を敷くのは、囲むだけだと中が暗いままで、隣に出ている名前が沈んでしまうため。
   （狭い画面では名前が畳まれるので、そのときは丸い印だけが浮かぶ） */
body.is-guiding .appbar__self {
  position: relative; z-index: 1;
  pointer-events: auto;
  border-radius: var(--r-pill);
  background: var(--card-raised);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 55%, transparent),
              0 10px 26px -12px rgba(8, 10, 22, .75);
}
body.is-guiding .appbar__me { color: var(--ink); }

.guide__balloon {
  position: absolute;
  top: calc(env(safe-area-inset-top) + var(--header-h) + 8px);
  right: max(12px, calc(50vw - var(--page-max) / 2 + 12px));
  width: min(300px, calc(100vw - 24px));
  pointer-events: auto;
  padding: 13px 15px;
  border-radius: var(--r-md);
  background: var(--card-raised);
  border: 1px solid var(--line-strong);
  box-shadow: 0 14px 34px -14px rgba(21, 26, 46, .5);
  animation: guide-in .34s cubic-bezier(.2, .9, .3, 1.3) both;
}
/* 上向きの尻尾。指している先をはっきりさせる。 */
.guide__balloon::before {
  content: ""; position: absolute; top: -7px; right: 26px;
  width: 12px; height: 12px;
  background: var(--card-raised);
  border-left: 1px solid var(--line-strong);
  border-top: 1px solid var(--line-strong);
  rotate: 45deg;
}
@keyframes guide-in {
  from { opacity: 0; transform: translateY(-8px) scale(.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.guide__title {
  font-size: 14.5px; font-weight: 800; letter-spacing: -.01em;
  margin-bottom: 3px;
}
.guide__body { font-size: 12.5px; line-height: 1.6; color: var(--ink-2); }
.guide__body + .guide__body { margin-top: 7px; }
.guide__actions { display: flex; gap: var(--s2); margin-top: 11px; }

@media (prefers-reduced-motion: reduce) {
  .guide__balloon, .guide__shade { animation: none; }
}

/* ===== 記録できた手応え ========================================== */
/* 画面の奥からロゴが迫ってきて、通り過ぎていく。一瞬で終わらせる。 */
.rush {
  position: fixed; inset: 0;
  display: grid; place-items: center;
  pointer-events: none;
  /* 降るロゴより上、お知らせより下。 */
  z-index: 85;
}
.rush__mark {
  width: min(92vw, 860px); height: auto;
  opacity: 0;
  filter: drop-shadow(0 12px 34px rgba(21, 26, 46, .3));
  animation: rush-in .62s cubic-bezier(.32, 0, .2, 1) forwards;
}
@keyframes rush-in {
  /* 奥の一点から。出はじめは見せず、迫ってくるところから目に入れる。 */
  0%   { opacity: 0; transform: scale(.08); }
  14%  { opacity: 1; }
  /* 画面いっぱいで一度だけ張る。ここが手応えの頂点。 */
  58%  { opacity: 1; transform: scale(1); }
  70%  { opacity: 1; transform: scale(1.05); }
  /* そのまま手前へ抜けていく。 */
  100% { opacity: 0; transform: scale(1.6); }
}
@media (prefers-reduced-motion: reduce) {
  .rush__mark { animation: none; }
}

/* ===== ヤルヤンが降る ============================================ */
/* 留守のあいだに届いたぶんを、開いた瞬間にまとめて知らせる。
   見るだけのものなので、下の操作を邪魔しない。 */
.rain {
  position: fixed; inset: 0;
  overflow: hidden;
  pointer-events: none;
  /* ヘッダーより上、お知らせより下。 */
  z-index: 80;
}
.rain__sheet {
  position: absolute; top: 0; left: 0;
  height: auto;
  filter: drop-shadow(0 4px 10px rgba(21, 26, 46, .18));
  will-change: transform, opacity;
}

/* 見るだけの人のページは、自分のことと集計がひと続きに並ぶ。
   ゾーンの見出しが直前のカードにくっつくので、あいだを空けておく。 */
#dashboard + .stack { margin-top: var(--s7); }

/* ===== ページを渡るときの流れ ==================================== */
/* 「自分」と「みんな」は並んだページなので、渡るときも横に流す。
   ヘッダーと下の帯は動かさない（居場所が変わらないもの、と分かるように）。 */
.appbar  { view-transition-name: appbar; }
.pagenav { view-transition-name: pagenav; }

/* 選んでいる側の塗り。両方のページで同じ名前を付けておくと、
   ブラウザが「同じもの」と見て、前のページの位置から新しい位置まで滑らせてくれる。 */
.pagenav__pages .pagenav__item.is-active { view-transition-name: pagepill; }
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-group(pagepill) {
    animation-duration: .26s;
    animation-timing-function: cubic-bezier(.3, .85, .25, 1);
  }
  /* 中身（アイコンと文字）は入れ替えず、そのまま出しておく。 */
  ::view-transition-old(pagepill),
  ::view-transition-new(pagepill) { animation: none; mix-blend-mode: normal; }
}

@media (prefers-reduced-motion: no-preference) {
  /* 向きの指定が無いときは、これまでどおり（ブラウザ既定の淡い入れ替え）。 */
  html[data-slide]::view-transition-old(root),
  html[data-slide]::view-transition-new(root) {
    animation-duration: .26s;
    animation-timing-function: cubic-bezier(.3, .8, .3, 1);
    animation-fill-mode: both;
  }
  html[data-slide="forward"]::view-transition-old(root) { animation-name: page-leave-left; }
  html[data-slide="forward"]::view-transition-new(root) { animation-name: page-enter-right; }
  html[data-slide="back"]::view-transition-old(root)    { animation-name: page-leave-right; }
  html[data-slide="back"]::view-transition-new(root)    { animation-name: page-enter-left; }
}
@keyframes page-leave-left  { to   { opacity: 0; transform: translateX(-16%); } }
@keyframes page-enter-right { from { opacity: 0; transform: translateX(16%); } }
@keyframes page-leave-right { to   { opacity: 0; transform: translateX(16%); } }
@keyframes page-enter-left  { from { opacity: 0; transform: translateX(-16%); } }

/* ===== 自分 / みんな の切り替え ================================== */
/* 画面の下に固定する。行き来が多いので、親指の届くところに置いておく。 */
.pagenav {
  position: fixed; z-index: 45;
  left: 0; right: 0; bottom: 0;
  padding: 8px var(--s4) calc(env(safe-area-inset-bottom) + 8px);
  /* 夜の色。ブランドの水色〜紫を、そのまま暗いほうへ寄せた並びにしてある。 */
  --bar-ink:   #e8eeff;                   /* 文字とアイコン */
  --bar-ink-2: #a8b7dd;                   /* 選んでいないほう */
  --bar-lift:  rgba(255, 255, 255, .10);  /* 指が乗ったときの明かり */
  background: linear-gradient(104deg, #0c1326 0%, #16204a 46%, #2a2059 100%);
  backdrop-filter: saturate(150%) blur(14px);
  -webkit-backdrop-filter: saturate(150%) blur(14px);
  border-top: 1px solid rgba(255, 255, 255, .10);
  color: var(--bar-ink);
}
/* 上辺にブランドの色を一本。境目をはっきりさせつつ、線そのものを見せ場にする。 */
.pagenav::before {
  content: ""; position: absolute; left: 0; right: 0; top: -1px;
  height: 1.5px; pointer-events: none;
  background: var(--gradient);
  opacity: .8;
}
.pagenav__inner {
  max-width: 460px; margin-inline: auto;
  display: flex; align-items: center; gap: var(--s2);
}
/* 行き来する2つで幅を分け合い、ルームの切り替えは右端に添える。
   2つはひと続きの切り替えなので、間を空けずに1枚の台へ載せる
   （記録／カレンダーのタブと同じ組み方にして、扱いを揃える）。 */
.pagenav__pages {
  flex: 1 1 auto; min-width: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 0;
  padding: 3px;
  /* 台は地より少しだけ明るく。選んでいないほうが沈んで見えない程度に留める。 */
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: var(--r-pill);
  box-shadow: 0 1px 3px -1px rgba(0, 0, 0, .45), 0 1px 0 rgba(255, 255, 255, .07) inset;
}
.pagenav__pages .pagenav__item { min-height: 36px; }
.pagenav .switcher { flex: none; }
.pagenav .appbar__switch { color: var(--bar-ink-2); }
.pagenav .appbar__switch:hover { background: var(--bar-lift); color: var(--bar-ink); }
/* 入っているルームの数。地が暗いので、黒い丸のままだと沈んで読めない。
   明るい地に暗い文字へ入れ替えて、まわりのフチも地とおなじ暗さにする。 */
.pagenav .appbar__switch-count {
  background: var(--bar-ink);
  color: #16204a;
  box-shadow: 0 0 0 2px #16204a;
}

/* 見るだけの人の目次。行き来ではないが、ひと続きの帯という扱いは同じにする。
   いま見ている見出しの下を、印がすべって追いかける。 */
.pagenav__jump {
  position: relative;
  flex: 1 1 auto; min-width: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 0;
  padding: 3px;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: var(--r-pill);
  box-shadow: 0 1px 3px -1px rgba(0, 0, 0, .45), 0 1px 0 rgba(255, 255, 255, .07) inset;
}
.pagenav__item--jump { position: relative; min-height: 36px; font-size: 13px; }
.pagenav__item--jump.is-here { color: #fff; }

/* いまの項目に重なる印。位置と幅は JS が px で渡す。
   台の内側に収めたいので、上下左右は縁の厚みぶん空ける。 */
.pagenav__slider {
  position: absolute; top: 3px; bottom: 3px; left: 3px;
  width: 0;
  border-radius: var(--r-pill);
  background: var(--gradient);
  box-shadow: var(--glow), inset 0 1px 0 rgba(255, 255, 255, .3);
  transition: transform .24s cubic-bezier(.2, .9, .25, 1.2), width .24s ease;
}
/* 置いた最初の1回は動かさない（端から滑ってくると押したように見える）。 */
.pagenav__jump:not(.is-ready) .pagenav__slider { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .pagenav__slider { transition: none; }
}
.pagenav__item {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 42px; padding: 0 12px;
  border-radius: var(--r-pill);
  color: var(--bar-ink-2); font-size: 13.5px; font-weight: 800;
  text-decoration: none;
  transition: background .14s ease, color .14s ease;
}
.pagenav__item:hover { background: var(--bar-lift); color: var(--bar-ink); text-decoration: none; }
.pagenav__item.is-active {
  background: var(--gradient); color: #fff;
  box-shadow: var(--glow), inset 0 1px 0 rgba(255, 255, 255, .3);
}
.pagenav__icon { flex: none; width: 18px; height: 18px; }
.pagenav__icon svg { width: 100%; height: 100%; }

/* 下に敷いたぶん、本文の終わりが隠れないようにする。 */
body.has-pagenav .page { padding-bottom: calc(env(safe-area-inset-bottom) + 82px); }
/* お知らせも、切り替えの上に浮かせる。 */
body.has-pagenav .flash-region { bottom: calc(env(safe-area-inset-bottom) + 82px); }

/* ===== お知らせ（トースト） ===================================== */
/* 本文を押し下げないよう、画面下に浮かせる。
   記録ボタンを押した直後に目が行く位置で、かつ台紙を隠さない高さ。 */
.flash-region {
  position: fixed; z-index: 90;
  left: 50%; bottom: calc(env(safe-area-inset-bottom) + 20px);
  transform: translateX(-50%);
  width: min(420px, calc(100% - 32px));
  display: grid; gap: var(--s2);
  pointer-events: none;
}

.issued {
  display: grid; gap: var(--s2);
  border-color: var(--gold-tint-2);
  background: color-mix(in srgb, var(--gold-fill) 10%, var(--card));
}
