/* hidden 属性は、display を書いたクラスに負ける。[hidden] の display:none は
   ブラウザ既定の規則なので、.share-btn{display:flex} のほうが強い。
   そのせいで、アプリ版では出ないはずの「ランキングを見る」が出ていた
   （imai 2026-10-05 TestFlight の実機で発覚）。
   #rank-row[hidden] だけ個別に書いてあったのは、同じ罠を一度踏んでいた跡。
   個別に塞ぐと必ずまた漏れるので、ここで全部まとめて塞ぐ */
[hidden]{ display: none !important; }

:root{
  color-scheme: dark;
}
*{
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}
html, body{
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  background: #0b0c10;
  overflow: hidden;
  overscroll-behavior: none;
  /* ゲーム中にページが揺れたり引っぱられたりしないように、全部止める。
     ただしこれは配下のスクロールまで殺す——touch-action は祖先の値と
     突き合わせて決まるので、ここで none にすると中の箱も指で動かなくなる。
     だから「中で縦に動かしたい箱」だけ、下で pan-y に戻している */
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  font-family: -apple-system, "Hiragino Sans", "Hiragino Kaku Gothic ProN", sans-serif;
}

/* 指で縦に動かせる箱。body の touch-action: none を、ここだけ解く。
   これを書かないとスクロールバーは出るのに指では1pxも動かない——
   マウスでは動くので、実機で触るまで気づけない類の不具合（imai 2026-09-26 報告）。
   overscroll-behavior: contain は、端まで来たときに後ろのページを
   引っぱらないため。ゲームの画面が揺れると、それだけで壊れて見える */
#rank-list,
#shop-panel,
#codex-body,
#debug-panel{
  touch-action: pan-y;
  overscroll-behavior: contain;
}


/* 盤面の横幅の上限。ここを変えるのが唯一のつまみ（imai 2026-09-26）。
   上限が無いと、PC やタブレットで盤面が広がりすぎて操作にならない。
   しかも横幅は走りの中身に効く——球の横速度は 320px/秒の固定で、画面幅に
   比例しない。端から端まで渡る時間が幅にそのまま比例する：
     390px（スマホ）1.2秒 ／ 1400px（PC）4.4秒 ＝ 3.7倍
   登れなくはならない（連なりの床は前の床から 78〜148px の固定間隔）が、
   ボーナス床は画面いっぱいに散るので、広い画面ほど横に長く動くことになる。
   タイムを競う順位表がある以上、ここは揃えないと公平にならない。
   操作バーも同じ幅に収まる（#app ごと絞るので）——バーの端から端が
   盤面の端から端に対応する関係も保たれる */
:root{ --play-max: 440px; }
#app{
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: var(--play-max);
  margin: 0 auto;
  height: 100dvh;
}

/* --- game area --- */
#game-area{
  flex: 1;
  position: relative;
  overflow: hidden;
  background: radial-gradient(120% 90% at 50% 20%, #14161d 0%, #0b0c10 70%);
  /* #bg-lift の screen が、この中だけで混ざるようにする。
     これが無いと、ページ全体の背景まで巻き込んで混ざる */
  isolation: isolate;
}
#game-canvas{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
/* 背景だけの画布。ゲームの画布は毎フレーム clearRect で透明にしているので、
   ここが透けて見える。伸ばしと鮮やかさは style.filter で当てる——
   毎フレーム JS から設定するのではなく、値が変わったときだけ書き替わる */
#bg-canvas{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
/* 底上げ。filter のあとに screen で重ねる。調整画面と同じ順序 */
#bg-lift{
  position: absolute;
  inset: 0;
  mix-blend-mode: screen;
  pointer-events: none;
}
/* --- HUD: life bar, then skills, then the height readout, top to bottom --- */
#hud{
  position: absolute;
  top: max(12px, env(safe-area-inset-top));
  left: 0;
  right: 0;
  pointer-events: none;
}
/* 計器の一行。体力・コンボ・SHOP の体力が、同じ寸法と同じ位置を共有する。
   名前が左、帯が真ん中、数字が右——どれも同じ形なので読み替えがいらない */
.gauge-row{
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 16px;
}
.gauge-name{
  flex: 0 0 auto;
  font-size: 11px;
  letter-spacing: 0.28em;
  margin-right: -0.28em;
  color: #f4f2ec;
  opacity: 0.5;
  text-shadow: 0 0 6px #0b0c10;
}
.gauge-track{
  flex: 1;
  height: 5px;
  border-radius: 999px;
  background: rgba(244,242,236,0.12);
  overflow: hidden;
}
.gauge-fill{
  display: block;
  height: 100%;
  width: 100%;
  border-radius: 999px;
  background: #8fc7a6;
  transition: width 0.25s ease-out, background 0.25s ease-out;
}
#hp-fill.low, #shop-hp-fill.low{ background: #d8785e; }
.gauge-val{
  min-width: 3.6em;
  text-align: right;
  color: #f4f2ec;
  font-size: 11px;
  opacity: 0.5;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 6px #0b0c10;
  white-space: nowrap;
}

/* equipped skills: icons with their level under them, swiped sideways when they overflow */
/* コンボ。持っていない間は見えないだけで、場所は空けておく——出たり消えたりすると
   下のアイテム段が上下にずれる（imai 2026-09-10）。発動すると色が変わって脈打つ */
#combo-meter{ margin-top: 6px; }
#combo-meter.idle{ visibility: hidden; }
#combo-fill{ width: 0%; background: rgba(240,192,96,0.45); }
#combo-meter.on #combo-fill{ background: #f0c060; }
#combo-meter.on .gauge-name,
#combo-meter.on .gauge-val{ color: #f0c060; opacity: 0.95; }
#combo-meter.on .gauge-track{ background: rgba(240,192,96,0.18); }
#combo-meter.on{ animation: combo-pulse 0.75s ease-in-out infinite; }
@keyframes combo-pulse{ 0%,100%{ opacity: 1 } 50%{ opacity: 0.62 } }
@media (prefers-reduced-motion: reduce){ #combo-meter.on{ animation: none } }

#buff-wrap{
  position: relative;
  margin-top: 10px;
  pointer-events: auto;
}
#buff-row{
  display: flex;
  gap: 10px;
  padding: 0 16px 2px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
#buff-row::-webkit-scrollbar{ display: none; }
#buff-row:empty + #buff-fade{ display: none; }
#buff-fade{
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 28px;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(11,12,16,0), #0b0c10);
}
.buff{
  flex: 0 0 auto;
  width: 34px;
  text-align: center;
  background: none;
  border: 0;
  padding: 0;
  font-family: inherit;
}
.buff svg{ display: block; margin: 0 auto; }
.buff .lv{
  display: block;
  margin-top: 1px;
  font-size: 9px;
  color: #f4f2ec;
  opacity: 0.55;
  text-shadow: 0 0 6px #0b0c10;
}
.buff[data-max] .lv{ opacity: 0.95; }
.buff[data-open]{ opacity: 1; }

/* the panel a skill icon opens */
#skill-info{
  position: absolute;
  top: calc(max(12px, env(safe-area-inset-top)) + 74px);
  left: 16px;
  right: 16px;
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 14px;
  border-radius: 12px;
  background: rgba(11,12,16,0.9);
  border: 1px solid rgba(244,242,236,0.12);
  z-index: 6;
}
#skill-info[hidden]{ display: none; }
#skill-info-name{
  font-size: 14px;
  margin-bottom: 4px;
}
#skill-info-name .lv{ font-size: 11px; opacity: 0.5; margin-left: 5px; }
#skill-info-desc{
  font-size: 11px;
  line-height: 1.65;
  color: #f4f2ec;
  opacity: 0.62;
}

/* floating pickup readout, e.g. "ジャンプ +0.1" */
#pickup-pop{
  position: absolute;
  top: 32%;
  left: 50%;
  transform: translateX(-50%);
  font-size: 17px;
  font-weight: 600;
  opacity: 0;
  pointer-events: none;
  text-shadow: 0 0 10px #0b0c10, 0 0 3px #0b0c10;
}
#pickup-pop.show{
  animation: pickup-fade 0.9s ease-out forwards;
}
@keyframes pickup-fade{
  0%   { opacity: 0; transform: translate(-50%, 4px); }
  20%  { opacity: 1; transform: translate(-50%, 0); }
  100% { opacity: 0; transform: translate(-50%, -14px); }
}

/* floating damage readout, shown briefly on a punishing fall */
#damage-pop{
  position: absolute;
  top: calc(max(14px, env(safe-area-inset-top)) + 16px);
  right: 16px;
  color: #d8785e;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
  opacity: 0;
  pointer-events: none;
  text-shadow: 0 0 8px #0b0c10;
}
#damage-pop.show{
  animation: damage-fade 1s ease-out forwards;
}
@keyframes damage-fade{
  0%   { opacity: 0; transform: translateY(-2px); }
  15%  { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(10px); }
}

/* red wash over the whole field whenever life is lost */
#hurt-flash{
  position: absolute;
  inset: 0;
  background: #d8785e;
  opacity: 0;
  pointer-events: none;
}
#hurt-flash.show{
  animation: hurt-fade 0.35s ease-out forwards;
}
@keyframes hurt-fade{
  0%   { opacity: 0.34; }
  100% { opacity: 0; }
}

/* stage line announcement, e.g. "1000メートル突破" */
#milestone{
  position: absolute;
  top: 40%;
  left: 0;
  right: 0;
  text-align: center;
  color: #f4f2ec;
  font-size: 26px;
  letter-spacing: 0.16em;
  opacity: 0;
  pointer-events: none;
  text-shadow: 0 0 14px #0b0c10, 0 0 4px #0b0c10;
}
#milestone.show{
  animation: milestone-fade 2.2s ease-out forwards;
}
/* the 15000m line is the front side finished, so it gets its own weight — still a telop
   over the running game, never a screen that stops the climb */
#milestone.clear{
  color: #ffd98a;
  font-size: 34px;
  text-shadow: 0 0 22px rgba(255,200,110,0.55), 0 0 14px #0b0c10, 0 0 4px #0b0c10;
}
#milestone.clear.show{
  animation: milestone-fade 3.4s ease-out forwards;
}
@keyframes milestone-fade{
  0%   { opacity: 0; transform: scale(0.9); }
  12%  { opacity: 1; transform: scale(1); }
  70%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(-14px); }
}

/* active-ability recast badges, tucked into the bottom corners of the play field */
.ability{
  position: absolute;
  bottom: 12px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: rgba(20,22,28,0.55);
  border: 1.5px solid rgba(244,242,236,0.18);
  transition: opacity 0.15s ease-out;
}
.ability[hidden]{ display: none; }
#ability-dj{ left: 12px; }
#ability-block{ right: 12px; }
/* The recast is a line that DRAWS its way around the badge; when the circle closes, the
   ability is ready. A filled sweep read as a pie chart and hid the icon behind it. */
.ability svg.ring{
  position: absolute;
  inset: -1.5px;
  width: calc(100% + 3px);
  height: calc(100% + 3px);
  transform: rotate(-90deg);
}
.ability .glyph{
  position: relative;
  display: block;
  opacity: 0.4;
  transition: opacity 0.2s ease-out;
}
.ability.ready .glyph{ opacity: 1; }
.ability.ready{ border-color: transparent; }

/* debug-only: jump straight back to the debug panel mid-run */
/* Clear of the HUD: at the old top-right it covered the right end of the life bar AND the
   number beside it, which read as "the life gauge is missing in debug". */
#dbg-return{
  position: absolute;
  top: calc(max(12px, env(safe-area-inset-top)) + 74px);
  right: 16px;
  padding: 6px 12px;
  border: 1px solid rgba(244,242,236,0.3);
  border-radius: 999px;
  background: rgba(11,12,16,0.6);
  color: #f4f2ec;
  font-size: 11px;
  font-family: inherit;
  letter-spacing: 0.06em;
  /* 計測の窓（z-index 6）より上。どちらもデバッグ専用で同時に出るので、
     ボタンのほうが必ず勝つようにしておく */
  z-index: 7;
}
#dbg-return[hidden]{ display: none; }
/* 走っている最中の、タイトルへの出口。デバッグの逃げ道と同じ場所・同じ格好。
   どちらも出るモードは無い（あちらはデバッグ専用、こちらはデバッグ以外）ので、
   場所を取り合うことはない */
#quit-run{
  position: absolute;
  top: calc(max(12px, env(safe-area-inset-top)) + 74px);
  right: 16px;
  padding: 6px 12px;
  border: 1px solid rgba(244,242,236,0.3);
  border-radius: 999px;
  background: rgba(11,12,16,0.6);
  color: #f4f2ec;
  font-size: 11px;
  font-family: inherit;
  letter-spacing: 0.06em;
  z-index: 5;
}
#quit-run[hidden]{ display: none; }
/* 左上のロゴも同じところへ連れていく。HUD は pointer-events: none なので、
   ここだけ拾えるように戻す。見た目は変えない——触れると分かる人だけの道で、
   分からない人には右上のボタンがある */
#hud-title.tappable{
  pointer-events: auto;
  cursor: pointer;
  padding: 2px 6px;
  margin: -2px 0 -2px -6px;
}
/* 押し間違いで30分が消えるので、必ず一度聞く。場を隠しきる——後ろで床が
   流れていると「まだ動いている＝まだ戻っていない」に見えて、二度押しを招く */
#quit-ask{
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  /* 完全に不透明。透かすと床と HUD が文字の裏で動いていて、聞かれている
     内容から目が離れる。SHOP の幕と同じ考え方 */
  background: #0b0c10;
  z-index: 30;
}
#quit-ask[hidden]{ display: none; }
#quit-panel{
  width: 100%;
  max-width: 300px;
  text-align: center;
  color: #f4f2ec;
}
/* 幅を px ではなく字数で決める。300px のままだと「タイト／ル画面」と語の
   途中で折れた。日本語は一文目（17字）がそのまま入る幅にすると「。」で折れる。
   字送りが 0.04em あるので 17 字 = 17.7em、切り上げて 18em。
   文言を変えるときは、一文目の字数 ×1.04 を下回らないこと */
#quit-msg{
  max-width: 18em;
  margin: 0 auto 24px;
  font-size: 14px;
  line-height: 1.9;
  letter-spacing: 0.04em;
}
#quit-panel button{
  display: block;
  width: 100%;
  padding: 12px;
  margin-top: 10px;
  border-radius: 999px;
  font-family: inherit;
  font-size: 13px;
  letter-spacing: 0.08em;
}
/* 戻るほうが危ないので、続けるほうを実体のあるボタンにする */
#quit-retry,
#quit-yes{
  border: 1px solid rgba(244,242,236,0.32);
  background: transparent;
  color: #f4f2ec;
}
#quit-no{
  border: 1px solid #f4f2ec;
  background: #f4f2ec;
  color: #0b0c10;
}
/* デバッグだけの計測窓。読むためのものなので、触れない・場を隠さない */
#dbg-perf{
  position: absolute;
  top: max(96px, calc(env(safe-area-inset-top) + 84px));
  left: 16px;
  font-size: 10.5px;
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  color: rgba(244,242,236,0.62);
  background: rgba(11,12,16,0.5);
  padding: 2px 7px;
  border-radius: 999px;
  /* ふだんは指を通す（盤の邪魔をしない）。★出荷前に外すこと★
     計測を出しているときだけ押せるようにして、押すと自動計測が走る
     ——走行中に設定は開けないので、切り分けの入口をここにした */
  pointer-events: none;
  z-index: 6;
  /* 右端を「デバッグへ戻る」まで伸ばさない。伸びると、押せる状態（tappable）の
     ときにこちらが上（z-index 6 > 5）なので、ボタンへの指を食ってしまう。
     imai 2026-10-08「計測の表示とデバッグへ戻るボタンの表示が干渉して操作できない」 */
  max-width: min(58%, 230px);
  overflow-wrap: anywhere;
}
#dbg-perf.tappable{
  pointer-events: auto;
  text-decoration: underline;
  text-decoration-color: rgba(244,242,236,0.3);
  text-underline-offset: 2px;
}
#dbg-perf[hidden]{ display: none; }

/* --- run result --- */
/* ゲームオーバーの幕。ボールのいる場所を中心に、周りから丸く閉じていく。
   閉じきってから結果が出るので、死んだ瞬間と結果画面のあいだに一拍が入る */
#iris{
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
#iris[hidden]{ display: none; }
#iris i{
  position: absolute;
  left: var(--ix, 50%);
  top: var(--iy, 50%);
  transform: translate(-50%, -50%);
  width: 3000px;
  height: 3000px;
  border-radius: 50%;
  /* ぼかした縁をつけた大きな影で、円の外側を塗りつぶす。円が縮むと画面が閉じる */
  box-shadow: 0 0 44px 3000px #0b0c10;
}
#iris.run i{
  animation: iris-close 0.95s cubic-bezier(0.5, 0, 0.88, 0.4) forwards;
}
@keyframes iris-close{
  0%   { width: 3000px; height: 3000px; }
  62%  { width: 460px;  height: 460px; }
  100% { width: 0;      height: 0; }
}

/* 15000m のゴール。走りを止めて出す唯一の画面。結果画面と同じカードを出すが、
   こちらは金の縁で少しだけ豪華にする。後ろのブラックホールが透ける暗さに留める */
#goal{
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: rgba(11,12,16,0.86);
  color: #f4f2ec;
  letter-spacing: 0.08em;
}
#goal[hidden]{ display: none; }
#goal-card{
  /* 札は 4:5 の縦長。幅で決めると縦にはみ出すので、高さを主にして幅で頭打ちにする */
  height: min(56vh, 400px);
  max-width: 76vw;
  object-fit: contain;
  border-radius: 20px;
  border: 2px solid rgba(255,217,138,0.75);
  box-shadow: 0 0 34px rgba(255,200,110,0.26);
}
#goal-unlock{
  margin-top: 2px;
  font-size: 12px;
  color: #a8d8c0;
  letter-spacing: 0.14em;
}
#goal-unlock[hidden]{ display: none; }
#goal-go, #goal-end{
  margin-top: 4px;
  padding: 11px 30px;
  border: 1px solid rgba(255,217,138,0.55);
  border-radius: 999px;
  background: transparent;
  color: #ffd98a;
  font-size: 14px;
  font-family: inherit;
  letter-spacing: 0.12em;
}
#goal-end{
  margin-top: 0;
  border-color: rgba(244,242,236,0.3);
  color: #f4f2ec;
  opacity: 0.75;
  font-size: 12px;
  padding: 8px 22px;
}
/* クリアの結果画面も同じ金の縁にする */
#result.clear #result-card{
  border-color: rgba(255,217,138,0.75);
  box-shadow: 0 0 34px rgba(255,200,110,0.26);
}

#result{
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  background: rgba(11,12,16,0.82);
  color: #f4f2ec;
  letter-spacing: 0.08em;
}
#result[hidden]{ display: none; }
/* the card IS the share image: the same pixels the player sends are the ones they are
   looking at, so there is never a gap between the two */
#result-card{
  height: min(54vh, 420px);
  max-width: 80vw;
  object-fit: contain;
  border-radius: 20px;
  border: 1px solid rgba(244,242,236,0.14);
  display: none;
}
#result.carded #result-card{ display: block; }
#result.carded #result-title,
#result.carded #result-time,
#result.carded #result-best,
#result.carded #result-score{ display: none; }
#result.carded{ background: rgba(11,12,16,0.93); gap: 12px; }
/* 送る手段は2つだけ。左が端末に落とす、右が X へ出す。
   どちらも同じ角丸の四角で、押せる面をそろえてある */
#share-row{
  display: flex;
  flex-wrap: wrap;          /* 「ブラウザで開く」が出たときは、それが下の行に回る */
  justify-content: center;
  gap: 8px;
  margin-top: 6px;
  /* 札には左右の余白が無く、width:100% だと画面の端で切れる。ここで内側に
     収める。332 なら 1つ 105px で、保存・共有・X が一行に並ぶ */
  width: min(100%, 332px);
  margin-inline: auto;
}
/* ブラウザで開く だけは並びから外れて、下の行いっぱいに */
#share-x-web{ flex: 1 0 100%; }
/* 結果の一行。札の字より一段うしろに置く */
#share-note[hidden]{ display: none; }
#share-note{
  flex: 1 0 100%;
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: rgba(244,242,236,0.55);
  text-align: center;
}
#share-note.bad{ color: #f0918f; }
/* iOS で X アプリが入っていない人の出口。二つのボタンの下に、細く。
   アプリの有無をこちらで当てにいかず、両方の出口を並べて置く */
#share-x-web{
  flex-basis: 100%;
  text-align: center;
  text-decoration: none;
  font-size: 11px;
  letter-spacing: 0.08em;
  padding: 9px 0 1px;
  color: rgba(244,242,236,0.4);
}
#share-x-web[hidden]{ display: none; }
#share-row[hidden]{ display: none; }
.share-btn{
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  /* 3つ横に並ぶ（保存・共有・X）。375px の端末で、札の内側は 335px ほど。
     8px の間を2つ取ると1つ 106px になるので、最小幅はそれより下に置き、
     余りは flex で等分する——3つが同じ幅でないと「並んだもの」に見えない */
  flex: 1 1 0;
  min-width: 92px;
  min-height: 62px;
  padding: 12px 10px;
  border: 1px solid rgba(244,242,236,0.30);
  border-radius: 14px;
  background: transparent;
  color: #f4f2ec;
  font-size: 13px;
  font-family: inherit;
  letter-spacing: 0.12em;
  line-height: 1;
}
.share-btn:disabled{ opacity: 0.35; }
/* 3つは対等。前は保存だけ金色で「ここが一番やってほしいこと」の意味に
   なっていた——2つだったときの名残り。3つに分けた今は、どれを選ぶかは
   本人の話なので、見え方を揃える（imai 2026-10-06「なぜ黄色い？」） */
#share-card, #share-sheet{
  border-color: rgba(244,242,236,0.45);
}
/* a になっているので下線を消す。button ではなく a なのは、iOS が
   Universal Link を「指で押されたリンク」にしか適用しないため */
#share-x{
  border-color: rgba(244,242,236,0.45);
  text-decoration: none;
}
/* X のアイコン。24px で置く（用意する画像は 72×72 の透過 PNG） */
#x-icon{
  width: 24px;
  height: 24px;
  display: block;
  object-fit: contain;
}
#result-title{
  font-size: 20px;
  opacity: 0.9;
}
#result-score{
  font-size: 14px;
  opacity: 0.6;
  font-variant-numeric: tabular-nums;
}
#restart, #to-title{
  margin-top: 6px;
  padding: 11px 30px;
  border: 1px solid rgba(244,242,236,0.3);
  border-radius: 999px;
  background: transparent;
  color: #f4f2ec;
  font-size: 14px;
  font-family: inherit;
  letter-spacing: 0.12em;
}
#to-title{ margin-top: 2px; opacity: 0.7; font-size: 12px; padding: 8px 22px; }

/* --- SHOP: life is the currency, so every price is an HP figure --- */
#shop-screen{
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 上に貼りつけた体力の行のぶんだけ、中身が潜り込まないよう空ける */
  padding: calc(max(12px, env(safe-area-inset-top)) + 30px) 16px 16px;
  /* 完全に不透明。半透明にしていたあいだ、後ろの床が札のあいだから覗いて
     「余分なカードが挟まって重なっている」ように見えていた（imai の写真で特定。
     細長い角丸＝床、円＝球）。0.975 まで上げても直らなかったのは OLED のせいで、
     真っ黒はピクセル消灯なので、白い床の 2.5% でも隣に光る点として見える。
     半透明である限り再発する種類の不具合なので、透けるのをやめた */
  background: #0b0c10;
  z-index: 10;
}
#shop-screen[hidden]{ display: none; }
#shop-panel{
  width: 100%;
  max-width: 340px;
  max-height: 100%;
  overflow-y: auto;
  color: #f4f2ec;
  letter-spacing: 0.04em;
}
#shop-head{
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 20px;
  letter-spacing: 0.2em;
  color: #e8ce78;
  margin-bottom: 14px;
}
/* 走行中の HUD と同じ位置に貼りつける。SHOP の枠は上下中央に置いてあるので、
   中に入れると体力だけが画面の真ん中に浮いてしまう（imai 2026-09-12） */
#shop-hp{
  position: absolute;
  top: max(12px, env(safe-area-inset-top));
  left: 0;
  right: 0;
  margin: 0;
}
.shop-sub{
  margin: 18px 0 6px;
  font-size: 11px;
  opacity: 0.5;
}
/* 一覧行のSHOP（shop-row/rarity/name/lv/cost/btn）はカード式に置き換えたときに
   死んだ。2026-09-04 の総ざらいで削除 */
.shop-empty{ font-size: 11px; opacity: 0.4; padding: 8px 0; }
#shop-leave{
  display: block;
  width: 100%;
  margin-top: 20px;
  padding: 13px 0;
  border: 1px solid rgba(244,242,236,0.32);
  border-radius: 999px;
  background: transparent;
  color: #f4f2ec;
  font-size: 14px;
  font-family: inherit;
  letter-spacing: 0.12em;
}

/* --- title / mode select --- */
#title{
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  background: radial-gradient(120% 90% at 50% 30%, #14161d 0%, #0b0c10 75%);
  color: #f4f2ec;
}
#title[hidden]{ display: none; }
#title-logo{
  font-size: 52px;
  letter-spacing: 0.3em;
  margin-bottom: 24px;
  margin-right: -0.3em;
  opacity: 0.95;
}
.mode-btn{
  width: 260px;
  padding: 14px 0;
  border: 1px solid rgba(244,242,236,0.28);
  border-radius: 999px;
  background: transparent;
  color: #f4f2ec;
  font-size: 15px;
  font-family: inherit;
  letter-spacing: 0.1em;
}
.mode-btn[data-mode="debug"]{ opacity: 0.6; font-size: 13px; }

/* --- debug panel --- */
#debug-panel{
  position: absolute;
  inset: 0;
  overflow-y: auto;
  padding: 18px 16px calc(18px + env(safe-area-inset-bottom));
  background: rgba(11,12,16,0.94);
  color: #f4f2ec;
  font-size: 13px;
  letter-spacing: 0.04em;
}
#debug-panel[hidden]{ display: none; }
#debug-panel h3{
  margin: 14px 0 8px;
  font-size: 13px;
  opacity: 0.6;
  font-weight: 600;
}
#debug-panel h3:first-child{ margin-top: 0; }
.dbg-note{ font-weight: 400; opacity: 0.7; margin-left: 4px; }
.dbg-row{
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 6px 0;
}
.dbg-row label{ flex: 0 0 92px; }
.dbg-row input[type=range]{ flex: 1; }
.dbg-row .val{ flex: 0 0 44px; text-align: right; font-variant-numeric: tabular-nums; opacity: 0.8; }
.dbg-kinds{ display: flex; flex-wrap: wrap; gap: 8px 14px; margin: 4px 0; }
.dbg-actions-inline{ display: flex; gap: 8px; margin: 2px 0 6px; }
.dbg-actions-inline button{
  padding: 5px 12px;
  border: 1px solid rgba(244,242,236,0.25);
  border-radius: 999px;
  background: transparent;
  color: #f4f2ec;
  font-size: 11px;
  font-family: inherit;
}
.dbg-kind{ display: flex; align-items: center; gap: 5px; font-size: 12px; opacity: 0.9; }
#debug-panel .dbg-actions{
  display: flex;
  gap: 10px;
  margin-top: 18px;
  position: sticky;
  bottom: 0;
  padding: 10px 0;
  background: rgba(11,12,16,0.94);
}
#debug-panel .dbg-actions button{
  flex: 1;
  padding: 12px 0;
  border: 1px solid rgba(244,242,236,0.3);
  border-radius: 999px;
  background: transparent;
  color: #f4f2ec;
  font-size: 14px;
  font-family: inherit;
}

#score-display{
  margin-top: 12px;
  text-align: center;
  color: #f4f2ec;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  text-shadow: 0 0 8px #0b0c10, 0 0 3px #0b0c10; /* stays legible over passing platforms */
}
#score-current{
  font-size: 22px;
  opacity: 0.85;
}
#score-max{
  margin-top: 3px;
  font-size: 12px;
  opacity: 0.45;
}
/* the clock. In challenge it is the thing being played for, so it is brighter there. */
#score-time{
  margin-top: 2px;
  font-size: 12px;
  opacity: 0.4;
  letter-spacing: 0.1em;
}
#score-display.attack #score-time{
  font-size: 17px;
  opacity: 0.9;
  margin-top: 4px;
  color: #ffd23f;
}
#result-time{
  font-size: 22px;
  letter-spacing: 0.1em;
  color: #ffd23f;
  font-variant-numeric: tabular-nums;
}
#result-time[hidden]{ display: none; }
#result-best{
  font-size: 12px;
  opacity: 0.55;
  font-variant-numeric: tabular-nums;
  margin-top: -6px;
}
#result-best[hidden]{ display: none; }

/* --- bottom control bar (joystick-style slider) --- */
#control-bar{
  position: relative;
  display: flex;
  align-items: stretch;
  /* 高さに安全領域を「足す」。前は 104px の内側に取っていたので、ホームバーの
     ある端末では 104-10-(14+34)=46px しか残らず、操作板が半分の太さになっていた。
     Safari は下に URL バーがあって安全領域が 0 なので 80px のまま——
     だから web では正しく見え、殻でだけ細かった（imai 2026-10-05 実機の並べ比べ） */
  height: calc(104px + env(safe-area-inset-bottom));
  padding: 10px 16px calc(14px + env(safe-area-inset-bottom));
  background: #101218;
  border-top: 1px solid rgba(255,255,255,0.06);
}
#bar-track{
  position: relative;
  flex: 1;
  border-radius: 999px;
  background: #1a1d26;
  border: 1px solid rgba(255,255,255,0.08);
  touch-action: none;
}
#bar-guides{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
#bar-indicator{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 34px;
  height: 34px;
  margin-top: -17px;
  margin-left: -17px;
  pointer-events: none;
}
#bar-indicator svg{ display: block; width: 100%; height: 100%; }
#bar-indicator.releasing{
  transition: left 0.15s ease-out;
}

/* --- 図鑑 ------------------------------------------------------------------ */
/* 図鑑ボタンの見た目は .sub-btn（設定と同じ）。ここで上書きすると、
   隣に並んだ二つの背丈が揃わなくなる */
#codex-screen[hidden]{ display: none; }
#codex-screen{
  position: absolute;
  inset: 0;
  background: rgba(11,12,16,0.96);
  display: flex;
  flex-direction: column;
  z-index: 40;
}
#codex-panel{
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* 板と同じ穴が空いていた。上に env() を足す */
  padding: calc(14px + env(safe-area-inset-top)) 12px calc(12px + env(safe-area-inset-bottom));
}
#codex-head{
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
#codex-tabs{ display: flex; gap: 6px; }
.codex-tab{
  background: transparent;
  border: 1px solid rgba(244,242,236,0.16);
  color: rgba(244,242,236,0.6);
  border-radius: 999px;
  padding: 7px 18px;
  font: inherit;
  font-size: 13px;
}
.codex-tab.on{
  background: rgba(244,242,236,0.9);
  border-color: rgba(244,242,236,0.9);
  color: #0b0c10;
  font-weight: 700;
}
#codex-count{
  font-size: 12px;
  color: rgba(244,242,236,0.45);
  font-variant-numeric: tabular-nums;
}
#codex-body{
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  min-height: 0;
}
.codex-row{
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 4px;
  border-bottom: 1px solid rgba(244,242,236,0.07);
}
.codex-fig{
  flex: 0 0 92px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(244,242,236,0.04);
  border-radius: 8px;
}
/* アイテムの紋。SHOPの札と同じ、丸のない紋だけ */
.codex-mark{
  display: flex;
  align-items: center;
  justify-content: center;
}
.codex-row.locked .codex-fig{
  color: rgba(244,242,236,0.22);
  font-size: 17px;
}
.codex-txt{ flex: 1; min-width: 0; }
.codex-name{
  font-size: 14px;
  color: #f4f2ec;
  margin-bottom: 2px;
}
.codex-no{
  color: rgba(244,242,236,0.3);
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  margin-right: 7px;
}
.codex-row.locked .codex-no{ color: rgba(244,242,236,0.2); }
.codex-desc{
  font-size: 12px;
  line-height: 1.5;
  color: rgba(244,242,236,0.55);
}
.codex-row.locked .codex-name,
.codex-row.locked .codex-desc{ color: rgba(244,242,236,0.28); }
.codex-rar{
  font-size: 10px;
  padding: 1px 7px;
  border-radius: 999px;
  margin-left: 6px;
  vertical-align: 1px;
}
/* 等級5段。白 → 青 → 紫 → 金 → 赤。だんだん熱くなる並びにしてある */
.r-common{ background: rgba(244,242,236,0.12); color: rgba(244,242,236,0.6); }
.r-rare{ background: rgba(122,180,230,0.18); color: #9ecbf0; }
.r-superrare{ background: rgba(178,136,232,0.20); color: #c8a0e8; }
.r-epic{ background: rgba(232,176,96,0.20); color: #efc27a; }
.r-legend{ background: rgba(232,90,90,0.18); color: #f0918f; }
#codex-close{
  margin-top: 10px;
  width: 100%;
  padding: 13px;
  background: rgba(244,242,236,0.9);
  color: #0b0c10;
  border: none;
  border-radius: 999px;
  font: inherit;
  font-weight: 700;
}

/* Status effects get their own strip, deliberately NOT in the skill row: gear you chose and
   a state you were handed are different things, and mixing them made both harder to scan.
   It sits between the two ability badges, which own the bottom corners. */
#status-chip[hidden]{ display: none; }
#status-chip{
  position: absolute;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  border-radius: 999px;
  background: rgba(20,22,28,0.72);
  border: 1.5px solid var(--status-color, rgba(244,242,236,0.3));
  font-size: 12px;
  color: #f4f2ec;
  pointer-events: none;
  white-space: nowrap;
}
#status-chip .dot{
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--status-color, #f4f2ec);
  flex: 0 0 auto;
}
#status-chip .left{
  color: rgba(244,242,236,0.6);
  font-variant-numeric: tabular-nums;
}
/* 倍率が整数をまたいだ瞬間だけ、一度強く光る。場所も大きさも変わらないので、
   跳んでいる最中に視界を塞がない——黙って重くならないためだけの合図 */
#status-chip.warn{
  animation: status-warn 0.9s ease-out 2;
}
@keyframes status-warn{
  0%   { transform: translateX(-50%) scale(1);    box-shadow: 0 0 0 0 var(--status-color); }
  18%  { transform: translateX(-50%) scale(1.14); box-shadow: 0 0 18px 2px var(--status-color); }
  100% { transform: translateX(-50%) scale(1);    box-shadow: 0 0 0 0 rgba(0,0,0,0); }
}

/* SHOP の入口: 入店 / リタイア / 通り過ぎる。リタイアを SHOP に置いたのは、そこが唯一
   立ち止まれる場所だから — 走りながら決めさせない。 */
#shop-gate{ display: flex; flex-direction: column; gap: 8px; width: 100%; }
.shop-gate-btn{
  padding: 13px; border: 1px solid rgba(244,242,236,0.3); border-radius: 10px;
  background: transparent; color: #f4f2ec; font-family: inherit; font-size: 14px;
  letter-spacing: 0.06em;
}
.shop-gate-btn:active{ background: rgba(244,242,236,0.1); }
#shop-retire{ border-color: rgba(255,217,138,0.5); color: #ffd98a; }

/* リタイア: 上の棚から選んで、下のポケットへ入れる。棚の札は売る札と、
   ポケットの枠はフリックの枠と、同じ寸法で作ってある。店のなかで一度
   覚えた形をそのまま持ってくると、初めて見る画面でも押し方が分かる。
   札と枠の背丈は必ず揃える（--carry-h）。上下で数ピクセル違うと、同じ
   ものが上と下に居るのではなく、別の二種類に見える（imai 2026-09-13） */
#shop-panel{ --carry-h: 140px; }
/* 二行の説明は続けて読ませたいので、あいだの余白を畳む */
#shop-retire-note{ margin-bottom: 2px; opacity: 0.62; line-height: 1.6; }
#shop-retire-note + #shop-retire-sub{ margin-top: 0; }
.card-slot.carry-slot{ flex: 0 0 86px; }
.carry-card{
  width: 100%; height: var(--carry-h);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  padding: 10px 7px 35px;            /* 下は「？」の帯（28px）のぶん */
  border-radius: 11px; font-family: inherit; letter-spacing: 0.04em;
  background: rgba(244,242,236,0.05); border: 1px solid rgba(244,242,236,0.14);
}
.carry-card:active{ background: rgba(244,242,236,0.12); }
/* 入れたものは棚から消さずに、金で囲う。消すと棚が詰めて動き、指が置いた
   場所に別の札が来る——押した直後にいちばん動いてほしくない場所 */
.carry-card[data-on="1"]{
  border-color: rgba(255,217,138,0.6); background: rgba(255,217,138,0.13);
}
/* 枠が埋まっているあいだ、入らないものは沈める。「？」も一緒に沈めるが、
   押せなくはしない——入れられないものの説明は、いま読みたいものだから */
.carry-card[disabled]{ opacity: 0.32; }
.carry-card[disabled] + .card-info{ opacity: 0.4; }
.carry-card .cc-rr{ font-size: 8.5px; letter-spacing: 0.14em; opacity: 0.75; }
/* 背丈を決め打ちにしたので、長い名前は二行で止める。三行目が出ると
   「？」の帯に潜り込む */
.carry-card .cc-nm{
  font-size: 11.5px; font-weight: 600; color: #f4f2ec;
  text-align: center; line-height: 1.25;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
.carry-card .cc-lv{
  font-size: 9.5px; color: rgba(244,242,236,0.55); font-variant-numeric: tabular-nums;
}
/* 枠は開いているぶんだけ並ぶ（1000 / 3000 / 9000m で1つずつ）。空き枠を
   見せるのがこの画面の仕事——あと何個入るかは、数字ではなく穴の数で分かる */
#shop-carry-slots{ display: flex; gap: 8px; align-items: stretch; width: 100%; }
#shop-carry-slots[hidden]{ display: none; }
.pocket-face{
  flex: 1; min-width: 0; height: var(--carry-h);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  padding: 10px 7px; border-radius: 11px;
  font-family: inherit; letter-spacing: 0.04em;
  background: rgba(255,217,138,0.10); border: 1px solid rgba(255,217,138,0.5);
}
.pocket-face:active{ background: rgba(255,217,138,0.2); }
/* 空き枠は札一枚ぶんの背丈になったので、破線を少し濃くする。面が広がると
   同じ濃さでも薄く見えて、枠があること自体が読めなくなる */
.pocket-face.empty{
  color: rgba(244,242,236,0.4); background: transparent;
  border-style: dashed; border-color: rgba(244,242,236,0.28);
}
.pocket-face .pf-rr{ font-size: 8.5px; letter-spacing: 0.14em; opacity: 0.75; }
.pocket-face .pf-nm{
  font-size: 11.5px; font-weight: 600; color: #f4f2ec;
  text-align: center; line-height: 1.25;
}
.pocket-face.empty .pf-nm{ font-weight: 400; color: rgba(244,242,236,0.4); }
.pocket-face .pf-lv{
  font-size: 9.5px; color: rgba(244,242,236,0.55); font-variant-numeric: tabular-nums;
}
/* ポケットがまだ1つも開いていないとき。枠を0個にすると下が消えて、
   選べないのか壊れているのかが分からない */
.pocket-none{
  width: 100%; height: var(--carry-h); border-radius: 11px;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 8px; border: 1px dashed rgba(244,242,236,0.16);
  font-size: 11px; color: rgba(244,242,236,0.4);
}
#shop-retire-go{
  margin-top: 4px; padding: 11px 30px; border: 1px solid rgba(255,217,138,0.55);
  border-radius: 999px; background: transparent; color: #ffd98a;
  font-family: inherit; font-size: 14px;
}
#shop-retire-go[disabled]{ opacity: 0.35; }

/* ID セレクタの display は UA の [hidden]{display:none} に勝つ。図鑑で一度これを踏んで
   いるので、display を持つものには必ず [hidden] を書く（V56 の再発）。 */
#shop-gate[hidden]{ display: none; }
#shop-retire-go[hidden]{ display: none; }
#suspend-go[hidden], #resume-go[hidden]{ display: none; }
#shop-suspend[hidden]{ display: none; }
#shop-leave[hidden]{ display: none; }
#shop-skip[hidden], #shop-reroll[hidden]{ display: none; }
#shop-offers[hidden], #shop-sells[hidden], #shop-rewards[hidden]{ display: none; }
.shop-sub[hidden]{ display: none; }

/* 通常モードは「続きから」か「新規」か。セーブがある時だけ出す。 */
#resume-pick{ display: flex; flex-direction: column; gap: 8px; align-items: center; width: 100%; }
#resume-pick[hidden]{ display: none; }

/* 図鑑と設定。遊ぶものではないので、モードのボタンとは別の格好で横に並べる */
/* はみ出すと押せないボタンが出るので、折り返して中央に寄せる。いまは
   ランキング・図鑑・設定の3つで 375px に収まるが、増えたときの保険 */
#title-sub{ display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 8px; }
/* 遊ぶボタンより一回り小さく（imai 2026-09-29）。モードのボタンと同じ
   寸法で並ぶと、画面が賑やかになる。輪郭も少し薄くして後ろへ下げる */
.sub-btn{
  background: transparent; border: 1px solid rgba(244,242,236,0.15);
  color: rgba(244,242,236,0.68); border-radius: 999px;
  padding: 8px 18px; font: inherit; font-size: 12.5px; letter-spacing: 0.08em;
}
.sub-btn:active{ background: rgba(244,242,236,0.08); }

/* App Store への導線。遊ぶものではないので、モードの並びからは離して置く。
   バッジは Apple の公式素材で、作り直し・色替え・比率の変更が禁じられている。
   width/height は元の 108.85:40 をそのまま拡大したもの——数字を片方だけ
   いじると比率が崩れる */
#app-out{
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  margin-top: 26px; text-decoration: none;
}
/* この一行だけ少し前に出す（imai 2026-09-29）。球の黄 #f0c63c をそのまま
   置くと画面の中で浮くので、白に寄せて彩度を落とした薄い黄にしてある */
#app-out span{
  font-size: 12px; letter-spacing: 0.06em; color: #e6d4a1;
}
/* 幅だけ決めて高さは成り行きにする。width/height の属性を両方書くと、
   整数に丸めたぶんだけ比率がずれる（120:44 は元の 108.85:40 と 0.2% 違う）。
   属性のほうは、読み込み前に場所を取っておくためのもの */
#app-out img{ display: block; width: 120px; height: auto; }
#app-out:active{ opacity: 0.65; }

/* いちばん下に、いちばん小さく（imai 2026-09-29）。丸ボタンの並びから
   外したのは、ランキングや設定と同じ重さに見せたくないから。
   ただし薄墨だけだと沈みすぎたので、白い座布団を敷いた——字の大きさは
   そのままに、面で見つけられるようにする */
#open-credits{
  background: rgba(244,242,236,0.9); border: 0; border-radius: 999px;
  /* 白い面は、同じ寸法の輪郭線より大きく見える。座布団を敷いたぶん
     余白を詰めた（imai「デカすぎ」2026-09-29） */
  padding: 7px 13px; margin-top: 18px;
  font: inherit; font-size: 10px; letter-spacing: 0.1em;
  color: #0b0c10;
}
#open-credits:active{ background: rgba(244,242,236,0.7); }

/* --- 設定 ------------------------------------------------------------------ */
#settings-screen{
  position: absolute; inset: 0; z-index: 40;
  background: rgba(11,12,16,0.96);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
#settings-screen[hidden]{ display: none; }
#settings-panel{ width: 100%; max-width: 340px; color: #f4f2ec; letter-spacing: 0.04em; }
#settings-head{
  font-size: 20px; letter-spacing: 0.2em; color: #e8ce78; margin-bottom: 20px;
}
.set-row{ margin-bottom: 20px; }
.set-label{ font-size: 11px; opacity: 0.5; margin-bottom: 7px; }
/* 二択。押されているほうだけが明るい。オンとオフを両方見せるのは、
   いまどちらなのかが一目で分かるようにするため——トグルだと「これから
   どうなるのか」と「いまどうなのか」が見分けられない */
/* 音量のつまみ。入/切と同じ列に置いて、切ってあるときは触れなくする */
.vol{ display: flex; align-items: center; gap: 12px; margin-top: 13px; }
.vol input[type="range"]{
  flex: 1; min-width: 0; -webkit-appearance: none; appearance: none;
  height: 3px; border-radius: 2px; background: rgba(244,242,236,0.18);
}
.vol input[type="range"]::-webkit-slider-thumb{
  -webkit-appearance: none; width: 21px; height: 21px; border-radius: 50%;
  background: #f4f2ec; border: 0;
}
.vol input[type="range"]::-moz-range-thumb{
  width: 21px; height: 21px; border: 0; border-radius: 50%; background: #f4f2ec;
}
.vol-val{ font-size: 11px; opacity: 0.5; width: 36px; text-align: right;
  font-variant-numeric: tabular-nums; }
.set-row.muted .vol{ opacity: 0.28; pointer-events: none; }
.seg{ display: flex; gap: 6px; }
.seg-btn{
  flex: 1; padding: 11px 8px;
  border: 1px solid rgba(244,242,236,0.18); border-radius: 999px;
  background: transparent; color: #f4f2ec; opacity: 0.4;
  font-family: inherit; font-size: 13px; letter-spacing: 0.06em;
}
.seg-btn[aria-pressed="true"]{
  opacity: 1; border-color: rgba(232,206,120,0.55); color: #e8ce78;
}
.seg-btn:active{ background: rgba(244,242,236,0.08); }
#shell-probe[hidden]{ display: none; }
#shell-probe{
  margin: 10px 0 0;
  font-size: 10px;
  line-height: 1.6;
  letter-spacing: 0.04em;
  color: rgba(244,242,236,0.4);
  text-align: left;
  word-break: break-all;
}
#settings-close{
  margin-top: 10px; width: 100%; padding: 13px;
  background: rgba(244,242,236,0.9); color: #0b0c10;
  border: none; border-radius: 999px; font: inherit; font-weight: 700;
}
#resume-note{ font-size: 12px; opacity: 0.7; letter-spacing: 0.06em; text-align: center; }
#resume-go, #suspend-go, #fresh-go, #resume-back{
  padding: 12px 26px; border: 1px solid rgba(244,242,236,0.3); border-radius: 999px;
  background: transparent; color: #f4f2ec; font-family: inherit; font-size: 14px;
  letter-spacing: 0.08em; min-width: 220px;
}
#resume-go, #suspend-go{ border-color: rgba(255,217,138,0.55); color: #ffd98a; }
#resume-back{ opacity: 0.6; font-size: 13px; }
#shop-retire-back{
  margin-top: 2px; padding: 9px 24px; border: 1px solid rgba(244,242,236,0.25);
  border-radius: 999px; background: transparent; color: #f4f2ec;
  font-family: inherit; font-size: 13px; opacity: 0.75;
}
#shop-retire-back[hidden]{ display: none; }

/* 報酬の3択は縦カード。カード全体が押せる＝親指で狙いやすく、3つが対等に見えるので
   「並んだものから選ぶ」画面だと一目で分かる。文字ではなく面で選ばせる。 */
#shop-rewards.cards{ display: flex; gap: 8px; width: 100%; }
#shop-rewards.cards[hidden]{ display: none; }
/* 札と「？」を重ねて置く器。button の入れ子は書けないので、並べて位置で重ねる */
/* 幅は必ず入れ物が持つ。中身（札）に flex-basis を書いて入れ物を auto に
   すると、入れ物の幅を「中身から見積もる」計算になり、Safari はここを
   0 と出すことがある。すると 78px の札が 8px 間隔で並び、70px ずつ
   重なって二重に見える——imai 報告の「カードが重なって２重」の正体。
   フリックの割り当てを入れたとき、この入れ物を1枚かぶせたのが始まり。
   見積もらせない＝入れ物に実寸を書く、で二度と起きない */
.card-slot{ position: relative; flex: 1; min-width: 0; display: flex; }
.card-slot.rail-slot{ flex: 0 0 92px; }
.card-slot.sell-slot{ flex: 0 0 78px; }
/* 「？」は札の下辺いっぱいの帯。前は角の 19px の点で、親指には小さすぎたし
   札の一部にしか見えなかった（imai 2026-09-05）。幅いっぱい・高さ 28px なら
   狙わなくても当たるし、仕切り線と地の色で「別のボタン」だと分かる */
.card-info{
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 28px; padding: 0;
  border: 0; border-top: 1px solid rgba(244,242,236,0.14);
  border-radius: 0 0 11px 11px;
  background: rgba(244,242,236,0.07); color: #f4f2ec; opacity: 0.75;
  font-family: inherit; font-size: 13px; line-height: 28px; letter-spacing: 0;
}
.card-info:active{ opacity: 1; background: rgba(244,242,236,0.2); }

.shop-card{
  width: 100%; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 12px 8px 37px;            /* 下は「？」の帯（28px）のぶん空ける */
  background: rgba(244,242,236,0.05);
  border: 1px solid rgba(244,242,236,0.14);
  border-radius: 12px;
  font-family: inherit;
  letter-spacing: 0.04em;
}
.shop-card:active{ background: rgba(244,242,236,0.12); }
.shop-card .sc-rr{ font-size: 9px; letter-spacing: 0.14em; opacity: 0.75; }
.shop-card .sc-nm{ font-size: 12px; font-weight: 600; color: #f4f2ec; line-height: 1.3; text-align: center; }
.shop-card .sc-lv{ font-size: 10px; opacity: 0.55; color: #f4f2ec; font-variant-numeric: tabular-nums; }
/* 空きスロット。アイコンの場所に＋を置いて、埋まっている札と背が揃うようにする */
.shop-card.empty{ color: rgba(244,242,236,0.5); border-style: dashed; }
.shop-card .sc-plus{ font-size: 26px; line-height: 34px; height: 34px; opacity: 0.5; }

/* 受け取らない: 3枚のカードと同格に見えると迷うので、明確に一段下げた見た目にする。
   棚を振り直す(目利き)も同じ格。ただし「使える回数がある」ものなので、
   受け取らないより少しだけ濃くして、押せることが分かるようにしてある。 */
#shop-skip, #shop-reroll{
  margin-top: 4px; padding: 9px 22px;
  border: 1px solid rgba(244,242,236,0.2); border-radius: 999px;
  background: transparent; color: #f4f2ec; opacity: 0.55;
  font-family: inherit; font-size: 12.5px; letter-spacing: 0.06em;
}
#shop-reroll{ opacity: 0.8; border-color: rgba(176,168,216,0.5); color: #cfc8e8; }
#shop-skip:active, #shop-reroll:active{ background: rgba(244,242,236,0.08); }

/* 売買は横に流す。手放し候補は最大16枚あるので、縦に積むと必ず画面をはみ出す。
   流せることが分からないと気づかれないので、両脇にバーと同じ形の山型を置く。 */
.rail-wrap{ display: flex; align-items: center; gap: 2px; width: 100%; }
.rail-wrap[hidden]{ display: none; }
.shop-rail{
  flex: 1; min-width: 0; display: flex; gap: 8px;
  overflow-x: auto; padding-bottom: 4px;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.shop-rail::-webkit-scrollbar{ display: none; }
.rail-arrow{
  flex: 0 0 20px; height: 74px; padding: 0;
  background: transparent; border: 0; color: #f4f2ec; opacity: 0.55;
}
.rail-arrow[disabled]{ opacity: 0.12; }
.rail-arrow::before{
  content: ''; display: block; width: 8px; height: 8px; margin: 0 auto;
  border-top: 2px solid currentColor; border-right: 2px solid currentColor;
}
.rail-arrow[data-dir="1"]::before{ transform: rotate(45deg); }
.rail-arrow[data-dir="-1"]::before{ transform: rotate(-135deg); }

/* 買う: 面のあるカード。売る: 輪郭だけ。お金の向きが逆なので形で分ける。 */
.trade-card{
  width: 100%; display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 10px 7px 35px;            /* 同上 */
  border-radius: 11px; font-family: inherit; letter-spacing: 0.04em;
  background: rgba(244,242,236,0.05); border: 1px solid rgba(244,242,236,0.14);
}
.trade-card.sellc{
  background: transparent; border-style: dashed;
  border-color: rgba(244,242,236,0.22);
}
.trade-card:active{ background: rgba(244,242,236,0.12); }
.trade-card[disabled]{ opacity: 0.4; }
.trade-card .tc-nm{ font-size: 11.5px; font-weight: 600; color: #f4f2ec; text-align: center; line-height: 1.25; }
.trade-card .tc-lv{ font-size: 9.5px; color: rgba(244,242,236,0.55); font-variant-numeric: tabular-nums; }
.trade-card .tc-px{ font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; margin-top: 1px; }
.trade-card.sellc .tc-px{ color: #8ad0b0; font-size: 11px; }
/* 買う棚には、たまにレジェンドが混じる。値札だけでは何が高いのか分からないので等級を出す。
   売る側には要らない——手放すものの等級は、持っている本人がもう知っている */
.trade-card .tc-rr{ font-size: 8.5px; letter-spacing: 0.14em; opacity: 0.75; }
.shop-empty{ font-size: 11px; color: rgba(244,242,236,0.4); padding: 12px 0; }

/* フリックの割り当て。上と下に何が入っているかを並べて、⇅ で入れ替える。
   走っている最中には触れない——指が覚えたものと違うものが出ると事故になる */
#shop-slots{ display: flex; gap: 8px; align-items: stretch; width: 100%; }
#shop-slots[hidden]{ display: none; }
.slot-face{
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 9px 6px 8px; border-radius: 11px;
  background: rgba(244,242,236,0.05); border: 1px solid rgba(244,242,236,0.14);
}
.slot-face.empty{ color: rgba(244,242,236,0.45); border-style: dashed; }
.slot-face .sf-fl{ font-size: 9px; letter-spacing: 0.12em; opacity: 0.7; }
.slot-face .sf-nm{ font-size: 11.5px; font-weight: 600; color: #f4f2ec; text-align: center; line-height: 1.25; }
.slot-face .sf-lv{ font-size: 9.5px; color: rgba(244,242,236,0.55); font-variant-numeric: tabular-nums; }
#shop-swap-slots{
  flex: 0 0 42px; border: 1px solid rgba(244,242,236,0.25); border-radius: 11px;
  background: transparent; color: #f4f2ec; opacity: 0.7;
  font-family: inherit; font-size: 18px; line-height: 1;
}
#shop-swap-slots:active{ background: rgba(244,242,236,0.1); opacity: 1; }

/* 「？」で開く説明。画面の中央に浮かせる（imai案 2026-09-05）。
   前はパネルの下に貼りつく帯だったが、棚から目を離さないと読めない位置で、
   しかも札と地続きに見えた。浮かせると「いま説明を読んでいる」が一目で分かる。
   どこを押しても閉じる——読むだけのものに、閉じ方を覚えさせない */
#shop-info{
  position: fixed; inset: 0; z-index: 20;
  display: flex; align-items: center; justify-content: center;
  padding: 24px; border: 0; background: rgba(11,12,16,0.72);
  font-family: inherit; letter-spacing: 0.04em;
}
#shop-info[hidden]{ display: none; }
#shop-info .si-card{
  width: 100%; max-width: 300px;
  display: flex; gap: 13px; align-items: flex-start; text-align: left;
  padding: 17px 19px; border-radius: 15px;
  background: #171a23; border: 1px solid rgba(244,242,236,0.16);
  box-shadow: 0 20px 48px rgba(0,0,0,0.66);
}
#shop-info .si-ic{ flex: 0 0 auto; line-height: 0; padding-top: 2px; }
#shop-info .si-rr{ font-size: 9.5px; letter-spacing: 0.14em; opacity: 0.8; }
#shop-info .si-nm{ font-size: 15px; font-weight: 600; margin: 2px 0 5px; color: #f4f2ec; }
#shop-info .si-de{ font-size: 12px; line-height: 1.7; color: #f4f2ec; opacity: 0.7; }

/* 蓄えを使い切ったあと。走りに一度きりなので、残っているように見せない */
.buff[data-spent]{ opacity: 0.34; }
.buff[data-spent] .lv{ text-decoration: line-through; }

/* ===== ランキング ==========================================================
   全画面の札。図鑑（codex）と同じ骨格で、中身だけが順位表になっている。
   rank.js を外したビルドでは、この画面は開く入り口ごと消える */
#rank-screen[hidden]{ display: none; }
#rank-screen{
  position: absolute;
  inset: 0;
  background: rgba(11,12,16,0.96);
  display: flex;
  flex-direction: column;
  z-index: 40;
}
#rank-panel{
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* 上に env() を足す。前は 14px しか無くて、ノッチのある端末では見出しが
     ステータスバーの下に潜って読めなかった（imai 2026-10-06） */
  padding: calc(14px + env(safe-area-inset-top)) 12px calc(12px + env(safe-area-inset-bottom));
}
/* 板の銘。中央に立てて、下に細い線で区切る。字間を開けた分だけ右に寄るので、
   text-indent で戻す——戻さないと中央から半字ずれる */
#rank-title{
  text-align: center;
  margin: 12px 0 14px;
  padding-bottom: 14px;
  border-bottom: 1px solid rgba(244,242,236,0.12);
}
#rank-mark{
  font-size: 30px;
  font-weight: 300;
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  line-height: 1;
  color: #f4f2ec;
}
#rank-head{
  margin-top: 11px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  color: #e8ce78;
}
#rank-sub{
  margin-top: 7px;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: rgba(244,242,236,0.42);
}
#rank-list{
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
/* 順位・名前・タイムの3列。数字は等幅にして、桁が上下で揃うようにする */
.rank-row{
  display: grid;
  grid-template-columns: 40px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 10px;
  font-size: 14px;
}
.rank-row + .rank-row{ margin-top: 2px; }
.rank-row .rk{
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: rgba(244,242,236,0.45);
  font-size: 12px;
}
.rank-row .nm{
  min-width: 0;
  font-family: ui-monospace, Menlo, monospace;
  letter-spacing: 0.14em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rank-row .tm{
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}
/* 上位3件だけ色を持たせる。4位以下は素のまま——全部に色を付けると順位が読めない */
.rank-row.t1{ background: rgba(255,217,138,0.14); }
.rank-row.t1 .rk, .rank-row.t1 .tm{ color: #ffd98a; }
.rank-row.t2{ background: rgba(244,242,236,0.08); }
.rank-row.t3{ background: rgba(232,176,96,0.07); }
/* 自分の札。背景ではなく左の線で示す。上位の色と喧嘩しない */
.rank-row.me{ box-shadow: inset 3px 0 0 #7ad8a0; }
.rank-row.me .nm::after{
  content: attr(data-me);
  font-size: 10px;
  color: #7ad8a0;
  margin-left: 7px;
}
#rank-note-empty{
  color: rgba(244,242,236,0.45);
  font-size: 13px;
  text-align: center;
  padding: 40px 0;
}
#rank-close{
  margin-top: 10px;
  width: 100%;
  padding: 13px;
  background: rgba(244,242,236,0.9);
  color: #0b0c10;
  border: none;
  border-radius: 999px;
  font: inherit;
  font-weight: 700;
}

/* --- リザルトの登録欄 --------------------------------------------------- */
#rank-row[hidden]{ display: none; }
#rank-row{
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}
#rank-note{
  font-size: 12px;
  color: rgba(244,242,236,0.55);
  min-height: 1.2em;
}
/* 名前を入れる欄は、リザルトからランキングの板へ引っ越した（imai 2026-09-26）。
   板の上に置いてあるので、入れた名前がそのまま下の並びに現れるのが見える。
   横並びだとマス6つ＋ボタンが 375px に収まらないので、縦に積む */
#rank-entry{
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin: 14px 0 18px;
  padding: 16px 12px;
  border: 1px solid rgba(122,216,160,0.28);
  border-radius: 14px;
  background: rgba(122,216,160,0.06);
}
#rank-entry[hidden]{ display: none; }
/* 記録しようとしているタイム。何を出そうとしているのかを手元に置いておく */
#rank-entry-time{
  font-family: ui-monospace, Menlo, monospace;
  font-size: 23px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: #7ad8a0;
  font-variant-numeric: tabular-nums;
}
#rank-entry-note{
  font-size: 12px;
  line-height: 1.6;
  color: rgba(244,242,236,0.62);
  min-height: 1.6em;
  text-align: center;
}
/* 6つのマス。見せるのはこの span で、打っているのは上に重ねた透明な input。
   別々の input を6個並べる作りにすると、スマホで1文字ごとに候補が出たり
   フォーカスが飛んだりする——1本の input に被せるのがいちばん素直 */
#rank-cells{
  position: relative;
  display: flex;
  gap: 6px;
}
#rank-cells > span{
  width: 30px;
  height: 44px;
  border: 1px solid rgba(244,242,236,0.25);
  border-radius: 8px;
  background: rgba(244,242,236,0.05);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: ui-monospace, Menlo, monospace;
  font-size: 21px;
  font-weight: 700;
  color: #f4f2ec;
}
/* いま打つところ。点滅させると昔の名前入れの顔になる */
#rank-cells.on > span.cur{
  border-color: rgba(122,216,160,0.9);
  animation: rankblink 1s steps(1, end) infinite;
}
@keyframes rankblink{ 50%{ border-color: rgba(122,216,160,0.15); } }
#rank-name{
  position: absolute;
  inset: 0;
  width: 100%;
  border: none;
  background: transparent;
  color: transparent;
  caret-color: transparent;
  /* caret-color を無視する端末がある（imai の実機で、中央に青い線が出た／
     2026-09-26）。opacity: 0 なら「この要素が描くもの」が全部消えるので、
     カーソルも確実に消える。焦点も打鍵も受け取れるし、キーボードも開く。
     見えているのは常に下の6つのマスで、いま打つところはそちらが点滅して示す */
  opacity: 0;
  font: inherit;
  text-align: center;
  /* iOS が拡大しないよう 16px は確保する */
  font-size: 16px;
}
#rank-name:focus{ outline: none; }
#rank-send{
  padding: 11px 22px;
  border: 1px solid rgba(122,216,160,0.55);
  border-radius: 12px;
  background: transparent;
  color: #7ad8a0;
  font: inherit;
  font-weight: 700;
}
#rank-send:disabled{ opacity: 0.35; }

/* 全画面の板。中身が背より高くなったとき、上下とも切れて どこへも動かせなく
   なるのを防ぐ。justify-content: center のままだと、はみ出したぶんが枠の外へ
   出てしまって掴めない——リザルトで実際に起きた（375×667 で 枠563 に対して
   中身647、上が19px切れていた／imai 2026-09-26 報告）。
   safe center は「収まるときは中央、あふれるときは先頭から」。対応していない
   端末は この行を読み飛ばして今までどおりになるので、悪くなることはない。
   SHOP・ランキング・図鑑は中に自前のスクロールを持っているので、ここには要らない */
#result,
#goal,
#title,
#settings-screen{
  overflow-y: auto;
  touch-action: pan-y;
  overscroll-behavior: contain;
}
/* 中央寄せを justify-content でやらない。あふれたときに、はみ出したぶんが
   枠の外へ出て掴めなくなるため（実測：中身647・枠563 で、先頭が -84 の位置に
   いて、いちばん上まで動かしても戻ってこない）。
   safe center という指定がこれを直すためにあるが、載っていない端末があり、
   その場合は黙って今までどおりに戻ってしまう。
   代わりに、見えない板を上下に1枚ずつ置いて余白を吸わせる。余りがあれば
   上下へ等分に入って中央寄せになり、あふれたら 0 になって先頭から掴める。
   これはどの端末でも同じように効く */
#result, #goal, #title{
  justify-content: flex-start;
}
#result::before, #result::after,
#goal::before,   #goal::after,
#title::before,  #title::after{
  content: '';
  margin: auto;
}

/* --- タイムアタックの合図 ------------------------------------------------- */
/* 押した瞬間から時計が動くと、構える間が無い。同じ合図で始まることそのものに
   意味がある（imai 2026-09-30）。盤面の上に重ねるだけで、指は通す */
#countdown{
  position: absolute; inset: 0; z-index: 35;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
  font-size: 88px; font-weight: 900; letter-spacing: 0.06em;
  color: #f4f2ec;
  /* 面は敷かない。円を敷くと盤面に穴が開いて、一瞬の合図にしては
     主張しすぎだった（imai 2026-09-30）。字の周りだけを沈ませる。
     影は三枚重ね——近くを濃く、遠くまでぼかす。床の白の上でも
     幹の黒の上でも輪郭が残る。値は imai が実物の上で決めたもの */
  text-shadow: 0 0 28px rgba(11,12,16,1.00),
               0 0 12px rgba(11,12,16,1.00),
               0 2px 8px rgba(11,12,16,1.00);
}
#countdown[hidden]{ display: none; }
/* 数字は出た瞬間がいちばん大きく、そこから落ち着く。GO だけ黄で、少し弾む */
#countdown{ animation: countPop 0.28s ease-out; }
#countdown.go{
  font-size: 64px; letter-spacing: 0.18em; color: #e6d4a1;
  animation: countGo 0.3s ease-out;
}
@keyframes countPop{
  from{ transform: scale(1.5); opacity: 0; }
  to  { transform: scale(1);   opacity: 1; }
}
@keyframes countGo{
  from{ transform: scale(0.7); opacity: 0; }
  to  { transform: scale(1);   opacity: 1; }
}
@media (prefers-reduced-motion: reduce){
  #countdown, #countdown.go{ animation: none; }
}
