*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  /* --- デザイントークン: doc/design_handoff_10min_work/README.md 準拠 --- */
  --color-bg: #F4F1EC;          /* ホーム背景クリーム */
  --color-bg-quiz: #FFF7EE;     /* 問題画面背景クリーム */
  --color-surface: #fff;
  /* 復習・ウォームアップ問題の手がかりは**上辺ラベルだけ**（2026-08-11）。
     カード地色を薄青（旧 --color-surface-review: #EAF1F9）へ振る案は撤回した。 */
  --color-review-accent: #5A86B5;   /* 復習ラベル文字色 */
  --color-text: #2E3A45;        /* インク */
  --color-text-rgb: 46, 58, 69;
  --color-text-sub: #8A857C;
  --color-text-mute: #C5C0B8;
  --color-primary: #46B48A;     /* ミント */
  --color-primary-dark: #2F8E6B;
  --color-primary-hover: #3da37c;
  --color-primary-soft: #E6F4EE;
  --color-coral: #FF8A65;
  --color-coral-dark: #E2673F;
  --color-coral-hover: #f47a55;
  --color-coral-soft: #FFE3D6;
  --color-sunny: #FFD166;
  --color-correct: #46B48A;
  --color-correct-bg: rgba(70, 180, 138, .94);
  --color-incorrect: #FF8A65;
  --color-incorrect-bg: rgba(255, 247, 238, .97);
  --color-warn: #9A6A00;
  --color-warn-bg: #FFF6E2;
  --color-border: #EDE7DC;
  --color-grid-line: #E4F0EA;
  --color-grid-bg: #FBFEFC;
  --color-ink-line: #2E6FB0;    /* 手書き線 */
  --key-shadow: #E7DECF;
  --radius: 20px;
  --radius-card: 26px;
  --radius-sm: 12px;
  --max-width-child: 480px;
  --max-width-parent: 720px;
  /* journey-card の左右インセット。ホーム側は .app-container(16px)
     （.parent-home の左右 padding は 0。かつては 2px あり合計 18px だったが、
     ≥720px で max-width 頭打ち時にホームだけ 4px 細る差を消すため揃えた）。
     旧T3（finale → ホーム）はこのカードを**そのまま**運ぶので、finale 側の
     .session-portrait-feed-active がここと違う値だと、ゴーストが飛行中に幅を
     補間する羽目になり（規約1の例外を1つ増やす）、カード内の CTA・ヘッダーが
     毎フレーム横へ reflow する。片側だけ変えないこと。 */
  --journey-card-inset-x: 16px;
  /* journey-card の操作行（.journey-action）の箱の高さ。ホームは CTA 1つ分、
     finale は2列ボタンで実ボタンは低いが、**箱は同じ高さ**にする。
     カード高さの差はこの1箇所だけから出る（header / progress / mascot は一致済み）。
     ここがずれると 旧T3 のゴーストが飛行中に高さを補間する羽目になる。 */
  --journey-action-h: 74px;
  /* CTA（`.journey-cta`）の字サイズ。interlude の「つぎにすすむ」と着地のホーム CTA が
     同じ値を読む。文言も字も揃っていれば、interlude → finale で入れ替わっても
     字送りが動かない。body 直下のゴーストでも効くよう :root に置き、計算値の
     焼き付けはしない（規約 3.1）。 */
  --journey-cta-font-size: 25px;
  /* `.journey-cta` の実効幅。`.merged-home-dock` の左右 inset（下の 2 段）と
     `.journey-card` の padding 22px×2 で決まる値を、そのまま式で持つ。

     interlude の「つぎにすすむ」も**この幅**にする。T2 の morph はそのボタンを
     ホーム CTA へ運ぶので、幅が違うと飛行中に横幅を補間する羽目になる
     （DC の BTN_E.pad 18 → BTN_HOME.pad 22 は、この一致のために外す）。
     `--journey-card-inset-x` の注記と同じ理由で、**片側だけ変えないこと**。 */
  --journey-cta-width: calc(
    min(
      100vw
        - max(var(--journey-card-inset-x), env(safe-area-inset-left))
        - max(var(--journey-card-inset-x), env(safe-area-inset-right)),
      var(--max-width-parent)
    ) - 44px
  );
  --control-width-sm: 340px;
  --control-width-md: 360px;
  --control-width-lg: 380px;
  --st: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: system-ui, -apple-system, "Hiragino Kaku Gothic ProN", "Noto Sans JP", sans-serif;
  background: var(--color-bg);
  color: var(--color-text);
  line-height: 1.6;
  min-height: 100dvh;
}

html:has(body.question-page-locks),
body.question-page-locks {
  width: 100%;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

/* 回答中は Safari chrome / overscroll のフォールバックをクイズクリームに揃える
   （通常 body はホーム用 --color-bg）。 */
body.question-page-locks {
  background: var(--color-bg-quiz);
}

/* --- マスコット & アニメーション --- */
.mascot { display: block; }
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
@keyframes pop { 0% { transform: scale(.4); } 70% { transform: scale(1.12); } 100% { transform: scale(1); } }
@keyframes wig { 0%,100% { transform: rotate(-6deg); } 50% { transform: rotate(6deg); } }
@keyframes blink { 0%,100% { opacity: 1; } 50% { opacity: .15; } }
@keyframes rise { from { opacity: 0; transform: translateY(40px); } to { opacity: 1; transform: translateY(0); } }
@keyframes sheet-rise { from { transform: translateY(100%); } to { transform: translateY(0); } }
@keyframes portrait-feed-advance {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(0, calc(-1 * var(--portrait-feed-shift, 28vh)), 0); }
}

@keyframes portrait-feed-edge-fade-out {
  0%, 30% { opacity: var(--portrait-feed-edge-opacity, 1); }
  100% { opacity: 0; }
}

@keyframes portrait-feed-above-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
/* リザルトフェーズ：結果ボタンのフェードイン */
@keyframes finale-btns-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
@keyframes twk { 0%,100% { transform: scale(.6); } 50% { transform: scale(1.1); } }
@keyframes tw { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .55; transform: scale(.82); } }
@keyframes idlesway { 0%,84%,100% { transform: rotate(0) translateY(0); } 88% { transform: rotate(-6deg) translateY(-1px); } 92% { transform: rotate(5deg); } 96% { transform: rotate(-2deg); } }
@keyframes headshake { 0%,100% { transform: translateX(0) rotate(0); } 18% { transform: translateX(-4px) rotate(-6deg); } 38% { transform: translateX(4px) rotate(6deg); } 58% { transform: translateX(-3px) rotate(-4deg); } 78% { transform: translateX(2px) rotate(2deg); } }
@keyframes catch { 0% { transform: scaleY(.82) scaleX(1.16); } 50% { transform: scaleY(1.13) scaleX(.9); } 100% { transform: scaleY(1) scaleX(1); } }
@keyframes burst { 0% { opacity: 0; transform: rotate(var(--a)) translateX(2px) scale(.4); } 30% { opacity: 1; } 100% { opacity: 0; transform: rotate(var(--a)) translateX(24px) scale(.7); } }
@keyframes flypos { 0% { transform: translate(0, 0) rotate(0); } 100% { transform: translate(var(--dx), var(--dy)) rotate(45deg); } }
/* 正解演出の湧き出し（星が生まれてマスコットに当たるまで）。設計: 正解演出_検証.dc.html */
@keyframes orbspin { from { transform: translate(-50%, -50%) rotate(0deg); } to { transform: translate(-50%, -50%) rotate(360deg); } }
@keyframes orbpop { 0% { transform: scale(.25); } 60% { transform: scale(1.32); } 100% { transform: scale(1); } }
@keyframes flashring { 0% { opacity: .95; transform: translate(-50%, -50%) scale(.2); } 100% { opacity: 0; transform: translate(-50%, -50%) scale(2.8); } }
@keyframes cellglowfx { 0% { opacity: 0; } 22% { opacity: 1; } 100% { opacity: 0; } }
/* 粒子: pout が射出（進行方向の逆へ）、plinger が寿命（浮き上がり→落下フェード） */
@keyframes pout { 0% { transform: rotate(var(--a)) translateX(0) scale(.35); } 12% { transform: rotate(var(--a)) translateX(calc(var(--d) * .22)) scale(1.15); } 100% { transform: rotate(var(--a)) translateX(var(--d)) scale(1); } }
@keyframes plinger { 0% { opacity: 0; transform: translateY(0) scale(1); } 8% { opacity: 1; } 34% { opacity: .92; } 100% { opacity: 0; transform: translateY(var(--fall)) scale(.42); } }
@keyframes zzz { 0% { transform: translateY(2px); opacity: 0; } 50% { opacity: 1; } 100% { transform: translateY(-8px); opacity: 0; } }
/* レール1段降下の着地（落下→スカッシュ→小リバウンド→整う）。.mascot 内側要素に当たるので translateY(-50%) は含めない */
@keyframes zip {
  0%   { transform: scaleY(1.14) scaleX(0.90); }
  55%  { transform: scaleY(1) scaleX(1); }
  72%  { transform: scaleY(0.82) scaleX(1.16); }
  86%  { transform: scaleY(1.05) scaleX(0.97); }
  100% { transform: scaleY(1) scaleX(1); }
}
/* 最終問題フィナーレ（DC T2）: Y は easeInCubic（キーフレームで近似）、
   回転は線形 0→150°、不透明度は 980→1320ms（アニメ内 67.9%→100%）でフェード。
   timing-function は linear（Y の ease をキーフレームに焼き込むため）。 */
@keyframes finaldrop {
  0%    { transform: translate(-50%, -50%) translateY(0) rotate(0deg); opacity: 1; }
  25%   { transform: translate(-50%, -50%) translateY(calc(var(--drop, 120vh) * 0.015625)) rotate(37.5deg); opacity: 1; }
  50%   { transform: translate(-50%, -50%) translateY(calc(var(--drop, 120vh) * 0.125)) rotate(75deg); opacity: 1; }
  67.9% { transform: translate(-50%, -50%) translateY(calc(var(--drop, 120vh) * 0.3129)) rotate(101.85deg); opacity: 1; }
  75%   { transform: translate(-50%, -50%) translateY(calc(var(--drop, 120vh) * 0.421875)) rotate(112.5deg); opacity: 0.779; }
  87.5% { transform: translate(-50%, -50%) translateY(calc(var(--drop, 120vh) * 0.6699)) rotate(131.25deg); opacity: 0.39; }
  100%  { transform: translate(-50%, -50%) translateY(var(--drop, 120vh)) rotate(150deg); opacity: 0; }
}
.anim-bob { animation: bob 1.6s ease-in-out infinite; }

.app-container {
  min-height: 100dvh;
  padding: 16px;
  padding-top: calc(16px + env(safe-area-inset-top, 0px));
  padding-bottom: env(safe-area-inset-bottom, 16px);
  background-color: var(--color-bg);
  transition: background-color calc(500ms * var(--finale-scale, 1.4286)) ease;
}

.app-container:has(.question-page) {
  padding: 0;
  background-color: var(--color-bg-quiz);
}

/* finale の地は**ホームのクリーム**（`--color-bg`）。空は 84dvh で止まるので下の
   16dvh は地のままで、回答中の #FFF7EE を残すと静かな URL 置換（`.question-page`
   が外れる）フレームで地色が跳ぶ。切り替えは空の現像と同区間で送る
   （`lib/finaleTimeline.js` の BASE_MS.skyRevealStart 460 → skyRevealEnd 1240）。
   T1/T3 の退避（下のルール）が上書きできるよう、この位置に置く。 */
.app-container:has(.question-page-feed.is-result-phase) {
  background-color: var(--color-bg);
  transition: background-color calc(780ms * var(--finale-scale, 1.4286)) ease
    calc(460ms * var(--finale-scale, 1.4286));
}

/* T1: 空カーテンと重なる区間で地色を #FFF7EE へ（DC v2 t1: 150→750ms easeOutCubic）。
   .child-home ではなく .star-sky[data-departing] を見る — navigate 後も
   departing が残るので、ホーム unmount で transition が途切れない。 */
.app-container:has(.star-sky[data-departing="true"]) {
  background-color: var(--color-bg-quiz);
  transition: background-color calc(600ms * var(--finale-scale, 1.4286))
    cubic-bezier(0.215, 0.61, 0.355, 1)
    calc(150ms * var(--finale-scale, 1.4286));
}

/* --- Loading / Error --- */

.loading {
  text-align: center;
  padding: 80px 16px;
  color: var(--color-text-sub);
  font-size: 1rem;
}

.error-message {
  text-align: center;
  padding: 80px 16px;
  color: var(--color-incorrect);
}

.error-message .btn {
  margin-top: 16px;
}

.error-text {
  color: var(--color-incorrect);
  font-weight: 600;
  margin-bottom: 12px;
}

/* --- Buttons --- */

.btn {
  display: inline-block;
  padding: 14px 28px;
  border: none;
  border-radius: 18px;
  font-size: 1.125rem;
  font-weight: 800;
  cursor: pointer;
  text-align: center;
  transition: transform 0.08s, box-shadow 0.08s, background 0.15s;
  touch-action: manipulation;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--color-primary);
  color: var(--color-surface);
  width: 100%;
  max-width: var(--control-width-md);
  min-height: 64px;
  border-radius: 22px;
  font-size: 26px;
  box-shadow: 0 5px 0 var(--color-primary-dark);
}

.btn-primary:hover:not(:disabled) {
  background: var(--color-primary-hover);
}

.btn-primary:active:not(:disabled) {
  transform: translateY(3px);
  box-shadow: 0 2px 0 var(--color-primary-dark);
}

.btn-next {
  background: var(--color-coral);
  color: var(--color-surface);
  padding: 12px 36px;
  margin-top: 12px;
  box-shadow: 0 5px 0 var(--color-coral-dark);
}

.btn-next:active:not(:disabled) {
  transform: translateY(3px);
  box-shadow: 0 2px 0 var(--color-coral-dark);
}

.btn-text {
  background: none;
  color: var(--color-primary-dark);
  padding: 8px;
  font-weight: 700;
  font-size: 1rem;
}

.btn-secondary {
  background: var(--color-surface);
  color: var(--color-primary-dark);
  width: 100%;
  min-height: 56px;
  border-radius: 22px;
  font-size: 1.125rem;
  border: 2px solid var(--color-primary);
  box-shadow: none;
}

.btn-secondary:hover:not(:disabled) {
  background: var(--color-primary-soft);
}

.btn-secondary:active:not(:disabled) {
  transform: translateY(1px);
}

.section-label {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-primary);
  letter-spacing: 0.08em;
  margin-bottom: 8px;
}

/* --- Card --- */

.card {
  background: var(--color-surface);
  border: none;
  border-radius: var(--radius-card);
  padding: 22px;
  margin-bottom: 14px;
  box-shadow: 0 4px 16px rgba(var(--color-text-rgb), .06);
}

.card h2 {
  font-size: 0.875rem;
  color: var(--color-primary-dark);
  font-weight: 700;
  margin-bottom: 8px;
  letter-spacing: 0.02em;
}
