/* ============================================================
   世界℃計 — Brand Site
   欧文 = SF（-apple-system）/ 和文 = ヒラギノ角ゴ。
   影を使わず、面の明度差と1pxの罫線と余白だけで組む。
   動きは「ゆっくり・静かに」。鏡面のきらめきは使わない。
   ============================================================ */

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

:root {
  /* 固定ヘッダーが占める高さ。各面の上余白はこれ以上を確保する。 */
  --head-guard: 88px;

  /* ── 地とインク ── */
  --bg:        #edeff2;
  --ink:       #1f232b;
  --text-2:    #565d6b;   /* 本文。#edeff2 に対して 5.74:1 / #f3f4f7 に対して 6.02:1 */
  /* 補助。#edeff2 に対して 4.65:1 / #f3f4f7 に対して 4.88:1。
     ★AA の「大きい文字」は 24px 以上（太字18.66px以上）。11〜13px でしか
     使っていないので本文と同じ 4.5:1 が要る。旧値 #7c8494 は 3.26:1 で未達だった。 */
  --text-3:    #646b78;
  --sep:       rgba(60, 66, 80, 0.10);

  /* ── 和文の保険（Windows / Android 用）──
     ★スタックの末尾に置く。macOS / iOS ではヒラギノが先に一致するので
     ここまで降りてこず、**ダウンロードも発生しない**（実測で確認）。
     Windows は先頭5つが全部外れるので、ここで受け止める。
     以前は sans-serif（游ゴシック等）に落ちていて、游ゴシックには
     ウェイト500が無いため見出しが 400 か 700 に丸められ、
     「見出し500・本文400」の3段の階層が2段に潰れていた。
     ページで実際に使う562字だけに絞り込み、縦組み用の異体字は除去。
     Noto Sans JP の派生版。SIL OFL 1.1（assets/font/OFL.txt 同梱）。 */
  /* ── 書体 ──
     ★℃(U+2103) について。このコメントは以前「和文フォントを先に当てる」と
     書いてあったが、実現する仕組み（unicode-range の @font-face 等）は
     入っていなかったし、そもそも本人の指示は逆だった。
     「℃が欧文と並ぶと気持ち悪い。欧文の℃を使って欲しい」＝本文では
     SF が描く「°」+「C」の合成でよい。ロゴは SVG なので正しい ℃ のまま。
     つまり現状で意図どおり。仕組みは足さない。 */
  /* ★Windows では先頭5つが全部外れて sans-serif（メイリオ等）に落ちる。
     游ゴシックにはウェイト500が無いので、見出しが 400 か 700 に丸められて
     「見出し500・本文400」の階層が2段に潰れる。Yu Gothic UI を挟んでおく。
     ウェブフォントは初回転送との相談なので別の巡で。 */
  /* ★和文を A1ゴシック にする。A1ゴシックが先頭でなければならない。
     以前は SF を先に置いて「和文だけ後ろの A1 が拾う」つもりだったが、
     Safari / iOS では -apple-system が和文もヒラギノ経由で持っているため
     そこで確定し、A1 まで進まない（実測：WebKit で和文の描画が
     -apple-system と画素まで一致。Chromium では -apple-system が和文を
     持たないので通っていた＝PCだけ A1 に見えていた原因）。
     先頭に置いても欧文は影響を受けない。下の @font-face が
     unicode-range で和文の範囲だけに限定してあるので、ラテン・数字・°は
     A1 を飛ばして次の SF が拾う（実測：欧文の幅は前後とも 1606.2px で不変）。
     ℃ を「°＋C」の合成で見せる既存の方針もそのまま保たれる。
     ★ウェイトは 400 と 500 を別の @font-face として登録して解決している。 */
  --sans: "A1 Gothic",
          -apple-system, BlinkMacSystemFont, "SF Pro Display",
          "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Noto Sans JP",
          "Yu Gothic UI", "Yu Gothic", "WorldClock JP", Meiryo, sans-serif;
  --latin: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue", sans-serif;

  /* ── フラットの階層 ── */
  --line:      rgba(60, 66, 80, 0.13);
  --line-soft: rgba(60, 66, 80, 0.08);
  --fill:      #f3f4f7;   /* 地より少し明るい面 */
  --fill-sunk: #e2e5ea;   /* 地より沈んだ面 */

  /* 照明色（JS が上書き） */
  --orb-cold-rgb: 92 194 255;
  --orb-warm-rgb: 255 210 132;

  /* 温度スケール（実機の LED が光る色。js/site.js の COLOR_STOPS と同一） */
  --temp-scale: linear-gradient(90deg,
    rgb(41,100,255) 0%, rgb(67,140,255) 12.5%, rgb(122,199,255) 25%,
    rgb(201,244,255) 37.5%, rgb(234,252,255) 45%, rgb(250,252,255) 52.5%,
    rgb(255,252,250) 60%, rgb(255,225,150) 67.5%, rgb(255,174,98) 75%,
    rgb(255,111,54) 87.5%, rgb(255,58,25) 100%);

  /* ── グリッド（12カラム＋8ptスケール＋24pxベースライン） ──
     出典と規律は _reference/グリッドシステム_実装スキル.md */
  --cols: 12;
  --container: 1360px;
  --gutter: 24px;                          /* カラム間 */
  /* ★viewport-fit=cover を指定しているので、iPhone 横向きでは左右に 59px の
     安全域ができる。外側マージンがそれを下回ると、本文とロゴと購入ボタンが
     カメラと角丸の下に潜る（幅932pxのとき clamp は 37.3px しか出ない）。
     余白と安全域の大きいほうを採る（左右は揃える）。 */
  --margin: max(clamp(20px, 4vw, 64px),
                env(safe-area-inset-left, 0px),
                env(safe-area-inset-right, 0px));
  --bl: 1.5rem;                              /* ベースライン */
  /* ── 文字の段は6つだけ ──
     参考にした照明ブランド（Louis Poulsen 5段・Vibia 7段・Balmuda 6段）に合わせる。
     0.5px刻みのような、意味を持たない中間値は作らない。 */
  --t-disp:  clamp(2.75rem, 5.4vw, 4.75rem);   /* 温度の大きな数字（表示専用） */
  /* ★幅だけで決めると、縦に長い画面で文字が小さいまま張り付く。
     820x1180 のタブレット縦では 3.2vw = 26.2px となり、390px のスマホと
     同じ 26px（下限）だった。高さの側も見て、大きいほうを採る。
       820x1180 : 26px → 38px
       768x1024 : 26px → 33px
       1440x900 : 42px のまま（3.2vw が勝つ）
       360x640  : 26px のまま（どちらも下限以下） */
  --t-hero:  clamp(1.625rem, max(3.2vw, 3.2vh), 2.625rem);   /* ヒーローの見出し */
  /* ★節の見出しは幅だけで決める。ヒーローと違って 4〜5列の枠の中にいるので、
     高さで大きくすると枠は広がらないまま字だけ育ち、折り返しが増える。
     実際 1024x1366（iPad Pro 縦）で 24px→30px になり、
     1行だった見出しが3つ2行に割れた。 */
  --t-head:  clamp(1.5rem, 2.2vw, 2rem);   /* 節の見出し */
  --t-sub:   1.1875rem;                        /* 小見出し・製品名 */
  --t-body:  clamp(0.9375rem, 1.15vw, 1rem);   /* 本文 */
  --t-cap:   0.8125rem;                        /* キャプション・注記・仕様の値 */
  --t-label: 0.6875rem;                        /* ラベル・法務・単位 */

  /* ── 字間は3つだけ ──
     和文の本文はベタ組み(0)。小さい文字だけ開き、大きい見出しだけ締める。 */
  --ls-tight: -0.01em;   /* 数字の大きな表示 */
  --ls-flat:  0;         /* 本文・見出し */
  --ls-wide:  0.06em;    /* ラベル・小さいキャプス */

  --s1: 8px;  --s2: 16px; --s3: 24px; --s4: 32px;
  --s5: 48px; --s6: 64px; --s7: 96px;  --s8: 128px; --s9: 160px;
  --radius-md: 16px;
  --radius-sm: 8px;
  --header-h: 56px;

  /* ── モーション ── */
  --ease-out:    cubic-bezier(0.16, 1, 0.30, 1);
  --ease-smooth: cubic-bezier(0.40, 0, 0.20, 1);
  /* ゲル。戻りで行き過ぎてから収まる。振動は付けない（1回だけ行き過ぎる）。 */
  --ease-gel:    cubic-bezier(0.18, 1.42, 0.34, 1);
  /* ★時間は「指が起こした変化」と「こちらが勝手に起こす変化」で分ける。
     以前はホバーも押下も 700ms × --ease-smooth で、触ってから 100ms 時点の
     進捗が 5.9%（半分まで 245ms・9割まで 443ms）。押し込みは 80〜120ms しか
     ないので、押した手応えの色が一度も出ていなかった。
     --ease-out は 10.2% で半分・32.9% で9割まで進むので、160ms なら
     16ms で半分・53ms で9割。即時に読めて、残りは尻尾として静かに伸びる。
     （Apple のホバーは 100ms linear、Carbon の最速は 70ms） */
  --dur-touch: 160ms;   /* ホバー・フォーカス＝返事 */
  --dur-press:  90ms;   /* 押し込み */
  --dur-calm:  700ms;   /* 雰囲気。押せないものはこちら */
}

/* ── 和文＝A1ゴシック（モリサワ） ──
   ★src の local() を先に置く。持っている環境（本人の Mac など）は
   自分の入っているものを使い、ダウンロードが走らない。
   ★unicode-range で和文だけに限定する。欧文と ℃ は --sans の先頭にある
   SF が担当する（「℃ は欧文の合成でよい」という既存の方針を保つ）ので、
   欧文の表示が原因でこのファイルを取りに行くことはない。
   ★収録は「画面に出る文字だけ」。HTML の本文と表示に使う属性、JS の
   文字列リテラルから集めた 597 字（漢字 250）。CSS/JS のコメントは
   表示されないので入れていない（入れると漢字が 752 字＝2.4倍になった）。
   使うウェイトは 400（本文）と 500（見出し）の2つだけ。
   ★ライセンス：A1ゴシックはモリサワの商用フォント。ここに置いてある
     woff2 は「画面に出る 597 字だけのサブセット」で、本文が読める分しか
     入っていない（全字種の再配布ではない）。ウェブフォントとしての利用可否は
     契約に依るので、条件が変わったら url() の行を外して local() だけに
     戻せばよい（持っていない環境はヒラギノに落ちる。実測で表示の崩れなし）。
     書き出し手順は _reference/フォント.md に残してある。 */
@font-face {
  font-family: "A1 Gothic";
  src: local("A P-OTF A1Gothic StdN R"), local("PA1GothicStdN-Regular"),
       url("../assets/font/a1g-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF,
                 U+4E00-9FFF, U+FF00-FFEF;
}
@font-face {
  font-family: "A1 Gothic";
  src: local("A P-OTF A1Gothic StdN M"), local("PA1GothicStdN-Medium"),
       url("../assets/font/a1g-medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF,
                 U+4E00-9FFF, U+FF00-FFEF;
}

/* 和文の保険。unicode-range で和文の範囲だけに限定し、
   欧文が理由でダウンロードが走らないようにする。
   font-display: swap ＝ 届くまでは代替で読める（真っ白にしない）。 */
@font-face {
  font-family: "WorldClock JP";
  src: url("../assets/font/wc-jp-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF,
                 U+4E00-9FFF, U+FF00-FFEF, U+2103;
}
@font-face {
  font-family: "WorldClock JP";
  src: url("../assets/font/wc-jp-medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF,
                 U+4E00-9FFF, U+FF00-FFEF, U+2103;
}

html { scroll-behavior: smooth; }
/* 動きを減らす設定のときは、スナップもスムーススクロールも止める */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; scroll-snap-type: none !important; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: var(--bl);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  /* ★和文の約物の空き。全角の始め括弧は字面の左に空きを持つので、
     行頭に来ると1文字ぶん字下げされたように見える（実測：仕様表の
     「（背面リング配置）」「（ACアダプタ付属）」で発生）。
     Chrome の既定 normal は行頭を詰めないので trim-start を指定する。
     欧文には影響しない。未対応のエンジンは無視するだけ。 */
  text-spacing-trim: trim-start;
}

img { max-width: 100%; display: block; }
a { color: inherit; }

.lg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ★ヘッダーに隠れないよう、飛び先を1ヘッダーぶん手前で止める。
   ただしピンの面は舞台が画面の高さぴったりで sticky なので、
   手前で止めるとその 84px ぶん舞台の下端が画面外に出て、
   注記の最終行が切れていた（768x1024・900x700・1024x768 で実測）。
   ピンは舞台の中身が下寄せなので、頭がヘッダーに掛かっても支障がない。 */
/* ★セレクタ全体を :where() で包んで詳細度を 0 にすること。
   前は `:where(section)[id]:not(.pin)` と書いていたが、:not() は
   中身（.pin＝クラス）ぶんの詳細度を外に持ち出すので (0,2,0) になり、
   下のスナップ用の打ち消し `:where(section, .pin)[id]`（0,1,0）に勝ってしまう。
   結果、スナップが効く画面では全部の面が 84px 手前で止まっていた
   （実測：ホイール1回ごとに statement も world も上端が +84px）。 */
:where(section[id]:not(.pin)) { scroll-margin-top: calc(var(--header-h) + 28px); }
.pin[id] { scroll-margin-top: 0; }

/* ────────────────────────────────────────────────
   Liquid Glass（ヘッダーのみ）
   ・backdrop-filter に SVG の変位マップ＝縁だけ背景が屈折して曲がる
   ・blur は浅く。透明感はぼかしではなく屈折で出す
   ──────────────────────────────────────────────── */
/* ── 和文の改行 ──
   ★word-break: auto-phrase は使えない。WebKit が非対応で、Chromium は
   CSS.supports が true を返すのに結果が素と1字も変わらない（実測）。
   7箇所に書いてあったが全部死んでいたので外した。
   代わりに keep-all で「文節の途中では折らない」を強制し、折ってよい位置は
   HTML 側の <wbr> で与える。<wbr> は BudouX で文節に分けて機械挿入し、
   活用語尾（照ら|すため）・複合助詞（光と|して）・行頭禁則（|・Wi-Fi）に
   当たる境界は後処理で畳んである（生成器は _reference/wbr.js）。
   overflow-wrap は非常口。<wbr> の間隔より狭い箱に入れられたとき、
   溢れさせるかわりに割る。break-word にしてあるのは、anywhere だと
   min-content 幅が変わって grid の列幅計算まで動くため。
   ★欧文には掛けない。単語単位の折り返しが既に正しく、ハイフンでの
   分割規則を壊す必要がない。 */
html[lang="ja"] body {
  word-break: keep-all;
  overflow-wrap: break-word;
}

.glass {
  position: relative;
  isolation: isolate;
  /* ★レンズと同じ考え方で、地に縦の傾きを持たせる（上をわずかに締め、下に
     光をためる）。ただし帯は高さ64・幅1100とレンズの何倍もあるので、
     同じ振幅を当てると「下だけ白く抜けた帯」に見える。振幅は半分にする。
     ★実測：従来は全高で +28.2 の完全な平坦だった。 */
  /* ★地の濃さ（スクロールで 0.30→0.44 に変わる）と、ガラスの厚みを出す
     縦の傾きは、別の層に分けること。ひとつの background にまとめると
     グラデーション同士の遷移になり、ブラウザは補間せず即座に切り替える
     （実測：0.5s の遷移なのに +80ms でもう最終値だった）。
     色＝background-color（補間される）、傾き＝background-image（不変）。 */
  background-color: rgba(255, 255, 255, 0.30);
  background-image: linear-gradient(180deg,
    rgba(43, 49, 62, 0.065) 0%,
    rgba(255, 255, 255, 0) 26%,
    rgba(255, 255, 255, 0.14) 70%,
    rgba(255, 255, 255, 0.55) 92%,
    rgba(255, 255, 255, 0.68) 100%);
  -webkit-backdrop-filter: blur(2px) saturate(1.7);
  backdrop-filter: blur(2px) saturate(1.7);
  box-shadow:
    0 8px 28px rgba(15, 23, 42, 0.10),
    0 2px 6px rgba(15, 23, 42, 0.06),
    inset 0 1px 1px rgba(255, 255, 255, 0.95),
    inset 0 -1px 1px rgba(255, 255, 255, 0.45),
    inset 0 0 0 1px rgba(255, 255, 255, 0.50);
  /* ★padding はスクロールでは変わらない（変わるのは 576px の段だけ）。
     ひとつの状態変化なので、時間もカーブもひとつに揃える。 */
  transition:
    top        0.5s var(--ease-out),
    background 0.5s var(--ease-out),
    box-shadow 0.5s var(--ease-out);
}
/* ★このブロックは Chromium でしか意味を持たない。@supports は「値が読めるか」
   しか答えないので Safari 18+ / Firefox 103+ でも true になるが、そちらでは
   url() が背景に適用されない（WebKit Bug 245510）。実際に .lg-ready を
   付けるかどうかは site.js の LG_OK が決めている。 */
@supports (backdrop-filter: url(#lgRefract)) {
  /* ★変位マップは要素の実寸で焼くので、大きさの違う要素は別のフィルタを使う。
     どれを引くかは site.js が --lg-url で要素ごとに指す。 */
  .glass.lg-ready {
    -webkit-backdrop-filter: var(--lg-url, url(#lgRefract)) blur(2px) saturate(1.7);
    backdrop-filter: var(--lg-url, url(#lgRefract)) blur(2px) saturate(1.7);
  }
}

/* ────────────────────────────────────────────────
   グリッド
   すべてのセクションは .grid の子としてカラム線に載せる。
   ──────────────────────────────────────────────── */
/* ★width:100% が要る。.snap は display:flex なので、これが無いと
   .grid がフレックスアイテムとして中身の幅に縮み、セクションごとに
   カラムの位置がずれる（実測で本文の左端が10本に割れていた）。 */
.grid {
  display: grid;
  width: 100%;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  gap: var(--gutter);
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--margin);
}
/* ★ステートメントの見出しだけ1列広い。
   「遠くの町の空気を、<br>壁の色として置いておく照明。」の2行目が
   4列（1024pxで298px / 1920pxで395px）に収まらず、末尾2文字が3行目へ
   こぼれていた（実測：1024pxで36px・1920pxで48pxのぶら下がり）。
   <br> を外すと「壁の / 色として」で切れて読みが悪化するので、
   改行位置は保ったまま箱を広げる。 */
.statement__title { grid-column: span 5; }
/* ★ここはサイトの主張そのもので、他の節見出しと同じ 32px では場が持たない。
   実測：この節だけ画面の 19% しか埋まっておらず（他は48〜68%）、
   上下に 350〜380px の空白が残って「作りかけ」に見えていた。
   見出しを一段上げ、本文も一段上げて、1画面ぶんの余白に見合う量にする。 */
.statement .lede { font-size: clamp(16px, 1.35vw, 19px); line-height: 2rem; }
.statement .lede + .lede { margin-top: 2rem; }
/* ★見出しと本文を横に並べると、どちらも短いので塊の高さが 192px にしかならず、
   1画面（900px）に対して 21% しか埋まらなかった。
   縦に積んで塊を厚くし、画面の天地中央に置く。 */
.statement__title { grid-column: 1 / span 8; }
/* ★見出しの行長も同じ理由で 992px→1000px に 27.1em→17.8em の段差があった
   （箱が 913px→605px と、画面を広げたのに 3 割狭くなる）。
   デスクトップ側は列の都合でもともと 17.7〜17.9em に収まっているので、
   18em で頭打ちにすれば宣言ひとつで全幅そろう。 */
.statement__title { max-width: 18em; }
/* ★414px 未満では2行目「壁の色として置いておく照明。」(14字) が入らず、
   実測 9 / 11 / 3 字となって「照明。」だけが取り残されていた（375・390px）。
   <br> を外すと balance が 9 / 2 / 12 と割って「壁の」が孤立し、さらに悪い。
   入らない幅だけ2つ目の改行を出して 9 / 6 / 8 に整える。 */
/* ── 本人が指定した本文の改行（#statement / #world / #pair / #app の4段落） ──
   ★入らない幅で出すと、意図した行がさらに折れて3行・4行になり、かえって崩れる
   （実測：#world は 1024px で箱540pxに対し2行目が575px必要）。
   1200px 未満では自動の折り返しに任せる。狭い幅の折り返しは
   keep-all＋<wbr> で検証済み（想定外の分断0・禁則0）。
   ★5箇所すべて直前が句読点なので、br を消しても句読点で折れる。 */
.br-lede { display: none; }
@media (min-width: 1200px) { .br-lede { display: inline; } }

.br-sp { display: none; }
@media (max-width: 413px) { .br-sp { display: inline; } }
/* ★本文の行長がこの節だけ他とずれていた。実測（和文の1字＝1em）：
   992px で 57字 → 1000px で 28字と、8px の差で倍半分に振れる。
   サイトの本文は他節が 44〜45字、この CSS 自身の狙いは 36字。
   広いほうは 7列（他節と同じ列数）に、狭いほうは 36em で頭打ちにして、
   どの幅でも 36字前後に収める。 */
.statement__body  { grid-column: 1 / span 7; margin-top: var(--s5); }
@media (max-width: 992px) { .statement__body { max-width: 36em; } }
/* ★狭い幅では <br> の前後がどちらも折り返して4行になり、
   中央寄せの末尾が 120px・56px とばらついていた（390px 実測）。
   収まらない幅では改行指定をやめ、自動の折り返しに任せる。 */
@media (max-width: 576px) { .cta__body br { display: none; } }
.c-3  { grid-column-end: span 3; }
.c-4  { grid-column-end: span 4; }
.c-5  { grid-column-end: span 5; }
.c-6  { grid-column-end: span 6; }
.c-7  { grid-column-end: span 7; }
.c-8  { grid-column-end: span 8; }
.c-12 { grid-column: 1 / -1; }
.at-4 { grid-column-start: 4; }
.at-5 { grid-column-start: 5; }
.at-6 { grid-column-start: 6; }
/* ★CTA の本文は中央寄せなので、<br> の後ろがさらに折り返すと
   短い行がまん中にぶら下がって特に目立つ。1024px で箱 459px に対し
   1行目が 457px と際どく、末尾 47px が次行へこぼれていた（実測）。
   6列→8列（3〜10列＝左右2列ずつで中央のまま）に広げて余裕を作る。 */
.cta { grid-column: 3 / span 8; }
@media (max-width: 992px) {
  :root { --cols: 8; --gutter: 16px; }
  /* ★開始位置の解除を必ず先に書く。これを .c-* より後ろに置くと、
     `.c-7 { grid-column: 1 / -1 }` の「1」を `.at-6 { grid-column-start: auto }`
     が後勝ちで打ち消し、`auto / -1` になる。Grid の仕様では
     「開始 auto ＋ 終端が確定」は span 1 と解釈されるので、
     本文が最終カラム1本＝74px まで潰れる（577〜992px の全域で発生していた）。 */
  .at-4, .at-5, .at-6 { grid-column-start: auto; }
  .c-3, .c-4, .c-5 { grid-column-end: span 4; }
  .c-6, .c-7, .c-8 { grid-column: 1 / -1; }
}
@media (max-width: 576px) {
  :root { --cols: 1; }
  .c-3, .c-4, .c-5, .c-6, .c-7, .c-8 { grid-column: 1 / -1; }
}
/* .section の中に置いた .grid は外側の余白を二重にしない */
.section > .grid,
.statement.grid { max-width: none; padding-inline: 0; }
.statement.grid { max-width: var(--container); margin-inline: auto; padding-inline: var(--margin); }

/* 開発時の確認用：body に grid-debug を付けるとカラムが見える */
body.grid-debug::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--margin);
  background-clip: content-box;
  background-image: repeating-linear-gradient(90deg,
    rgba(255, 0, 80, 0.07) 0 calc((100% - 11 * var(--gutter)) / 12),
    transparent 0 calc((100% - 11 * var(--gutter)) / 12 + var(--gutter)));
}

/* ────────────────────────────────────────────────
   共通
   ──────────────────────────────────────────────── */
.section {
  max-width: var(--container);
  margin: 0 auto;
  /* ★上下 160px 固定だと、横持ちのスマホ（390px高）で余白だけで 320px＝
     画面の 82% を使い、中身が押し出されていた（実測：844x390 で節1083px・
     中身763px）。画面の高さに追随させる。背の高い画面は従来どおり 160px。
       390px高 → 70px（画面の36%）  600px高 → 108px  900px高 → 160px */
  padding: clamp(56px, 18vh, 160px) var(--margin);
}
/* ★導入と本体の間隔。以前は 16 / 32 / 48 / 64 の4種類が同じ関係に当たっていた。
   48（＝24px ベースライン2本）に統一する。 */
.world__head,
.pair__head { margin-bottom: var(--s5); }

/* ── 文字の階層は3段だけ ──
   1) 見出し：ウェイト500・#1f232b・行送り1.45
   2) 本文  ：ウェイト400・#5b6270・16px/行送り28px・1行40〜46字（可読幅の定石）
   3) 補助  ：ウェイト400・#8b93a2・13px
   本文は 400 を下回らない（軽いウェイトは大見出しだけの特権）。 */
.section__title,
.cta__title,
.statement__title,
.world__title,
.pair__title,
.temp-ui__title,
.structure__title,
.hero__title {
  font-feature-settings: "palt" 1;   /* 詰め組みは見出しだけ */
  font-weight: 500;
  font-size: var(--t-head);
  line-height: 1.45;
  letter-spacing: var(--ls-flat);
  color: var(--ink);
  text-wrap: balance;
  /* ★balance は「行の長さを均す」だけで、どこで切るかは見ない。
     1024x768 で「0℃から40℃まで／を、ひと続きの色で」と助詞が割れていた。
     文節の切れ目で折るのは keep-all＋<wbr>（下の html[lang="ja"] body）が担う。
     欧文には影響しない。 */
}
/* ★ここはサイトの主張そのもので、他の節見出しと同じ 32px では場が持たない。
   （この宣言は上の共通見出しブロックより後ろに置くこと。前に置くと
     同じ詳細度の var(--t-head) に上書きされて、実測 24px のまま効かない。） */
.statement__title { font-size: clamp(28px, 3.4vw, 46px); }
/* 本文 */
/* 行長は em で持つ。和文は 1em = 1字なので、そのまま字数になる。
   ch は欧文の「0」の幅（SFで約0.55em）なので和文の字数と一致しない。
   モリサワの推奨は12〜59字。本文は36字に置く。 */
.lede {
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.75rem;
  /* ★最終行に1語だけ落ちるのを避ける（実測：英語のアプリ節が
     507px の段で最終行 53px になっていた）。見出しの balance と違い、
     pretty は最終行だけを見るので本文の行長は変わらない。 */
  text-wrap: pretty;
  letter-spacing: 0;      /* 和文本文はベタ組み。palt と二重に詰めない */
  color: var(--text-2);
  /* ★行長は箱（c-7 = 7列）が決める。em で頭打ちにすると 1440 で右端が
     12列目より 140.1px 手前で止まり、カード・表・数字と揃わなかった。
     実測で 1000→35.1字 / 1280→45.1字 / 1440→44.8字 / 1920→44.3字。 */
  max-width: none;
  /* 和文は文節の途中でも折り返せてしまうので「色は段階な／く移り変わります」
     のような割れ方をする。文節単位で折り返す（Chrome 119+）。
     対応していないブラウザでは従来どおり。 */
}
.lede + .lede { margin-top: 1.75rem; }

/* ── 英語の本文の行長と行末 ──
   ★英語だけ。和文は <wbr>＋keep-all と本人指定の <br> で組んであるので触らない。
   ★max-width: 62ch。英語の行長が幅によって 60〜85字と振れており、
   820px では85字＝読みやすさの上限（45〜75字）を超えていた。
   ★text-wrap: balance を併用する。62ch だけだと最終行が短いままで、
   世界の空気の段落は最長行の12%しか無かった（実測）。
   balance 単独だと逆に段落が箱の54〜60%まで細り、右に350pxの空白ができる。
   62ch で行長を抑えたうえで balance を掛けると、最終行は全幅で90〜100%、
   段落の幅は箱の87%に収まる（実測：1440pxで箱716pxに対し625px）。
   ★pretty では直らない。2行の塊に対しては balance でないと効かない。 */
html[lang="en"] .lede {
  max-width: 62ch;
  text-wrap: balance;
}
/* ── ボタン ──
   ホバーは明度がゆっくり変わるだけ。動かない・光らない。 */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  /* ★px 固定だと、文字サイズ設定を上げたとき文字だけ育って
     詰まって見える。rem にして箱も一緒に育てる。 */
  height: 2.875rem;
  padding: 0 1.5rem;
  border-radius: 999px;   /* ボタンはすべてピル型 */
  font-family: var(--sans);
  font-size: var(--t-cap);
  font-weight: 500;
  letter-spacing: var(--ls-wide);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background   var(--dur-touch) var(--ease-out),
    border-color var(--dur-touch) var(--ease-out),
    color        var(--dur-touch) var(--ease-out),
    /* ★transform を並べないと :active の沈みが瞬間移動になる（実測） */
    transform    var(--dur-touch) var(--ease-out);
}
/* 押し込みは 80〜120ms しかない。そこに収まる速さで返す。 */
/* ★押し込みの手応え。今までは地の色が変わるだけだった。
   沈みは 2%。ピルは高さ 40px なので見た目 0.8px 相当＝気づかないが手応えは出る。
   transform も --dur-press(90ms) で返す。 */
.btn:active { transition-duration: var(--dur-press); transform: scale(0.98); }
.lang:active { transform: scale(0.94); transition-duration: var(--dur-press); }
@media (prefers-reduced-motion: reduce) {
  .btn:active, .lang:active { transform: none; }
}
.btn--dark { background: var(--ink); color: #f2f4f8; border: 0; }
.btn--dark:hover { background: #3c424e; }
.btn--dark:active { background: #14171d; }
.btn--ghost {
  background: transparent;
  color: var(--ink);
  /* ★枠線だけがボタンである手がかりなので、WCAG 1.4.11 の 3:1 が要る。
     alpha .24 は合成すると 1.50:1 しかなく、ただの文字と区別がつかない。
     .62 で #7f848e 相当・3.26:1。細い1本なので静けさは保てる。 */
  border: 1px solid rgba(60, 66, 80, 0.62);
}
.btn--ghost:hover { border-color: var(--ink); background: rgba(255, 255, 255, 0.7); }
.btn--ghost:active { background: #e7ebf1; }
.btn--lg { height: 54px; padding: 0 32px; font-size: var(--t-body); }

/* ────────────────────────────────────────────────
   フォーカス
   ブラウザ既定のリングは色も太さも環境依存で、暗いピルやガラスの上での
   見え方が管理できない。面の明度差で組む方針に合わせて自前で定義する。
   ──────────────────────────────────────────────── */
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
  border-radius: 999px;
}
/* 暗い面の上では反転させる。--ink の 2px は沈む。 */
.btn--dark:focus-visible,
.badge:focus-visible,
.header-cta:focus-visible {
  outline-color: #f2f4f8;
  outline-offset: 2px;
}
/* ガラスヘッダーは写真の上に乗る。背景の明度がどこであってもリングが
   消えないよう、白い下敷きを一枚かませる。 */
.header__nav a:focus-visible {
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.85);
}

/* 目には出さず、読み上げには残す */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* 本文へ飛ばす。ふだんは画面の外。 */
.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 200;
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--ink);
  color: #f2f4f8;
  font-size: var(--t-cap);
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform 0.2s var(--ease-out);
}
.skip-link:focus-visible { transform: none; }

/* ── 画面左上の独立ロゴ（ガラスの外） ──
   ★clamp で決めていたので、1920px ではロゴが1列目より 292px も左にいた。
   .grid と同じ式（max-width で余った分の半分 ＋ マージン）で1列目に乗せる。
   ナビのピルだけは画面中央に固定でよい。面の要素ではなく浮いている道具なので、
   グリッドから独立していることに意味がある。 */
.site-logo {
  /* ★ピルの中身になったので fixed をやめる。位置は grid が決める。 */
  position: static;
  justify-self: start;
  /* ★指で押せる大きさを確保する。ロゴ画像は 26px（スマホの欧文は 15px）しか
     高さが無く、そのままだとタップ領域が WCAG 2.5.8 の 24px を割っていた（実測15px）。
     fixed なのでパディングを足してもレイアウトには響かない。
     top は「見た目の位置」を保つため、足した分だけ引く。 */
  /* 左は 22px。ピルの padding 10px と合わせて、マークの左端が縁から 32px。
     ★弧の左端は細く尖っているので、字面を基準に詰めると光学的に外へ
     落ちて見える。ソリッドな文字より内側に入れておく。 */
  padding: 9px 6px 9px 22px;
  /* ★ボタンの高さが rem になったので、固定の top では文字サイズ設定を上げた
     ときにロゴだけ取り残される。ボタンの中心（26px + 高さの半分）に
     translateY で合わせ、どの設定でも揃うようにする。 */
}
/* ★SVG に width/height 属性が無く viewBox だけなので、届くまで幅が 0 になる。
   ヘッダーは fixed なので実害は無いが、フッターのロゴは grid の auto 列にいて
   届いた瞬間に法務リンクの行が 130px 横へ飛ぶ。比を先に宣言して箱を確保する。 */
/* ★シンボルマーク。縦横比 229.26:54.43（≒4.2:1）。
   高さは PC 15px / 992px以下 17px。旧テキストロゴ（26px）より小さく取る。
   細長い記号なので、同じ高さでも横幅はテキストロゴより広い。
   ★スマホの方を大きく残しているのは、あちらがピルの外に単独で立っていて
   囲みの助けが無いから。ピルの中では枠が輪郭を補ってくれる。 */
.site-logo__mark {
  display: block;
  height: 15px;
  width: auto;
  aspect-ratio: 229.26 / 54.43;
  color: var(--ink);
}
/* ★ヘッダーのロゴは記号なので、言語別の調整（縦位置・縦横比・高さ）は不要になった。 */

/* ────────────────────────────────────────────────
   フルページのスクロールスナップ
   各エリアを画面ぴったりにし、スクロールすると必ずそのブロックで止まる。
   ・縦の余裕がある環境（デスクトップ／タブレット横）だけ有効。
     背の低い画面や狭い画面では中身が入りきらないので通常スクロールに戻す。
   ・ピン留めのシーンは 100svh ごとにスナップ点を置く（js が生成）。
   ──────────────────────────────────────────────── */
/* ★発動は 1200px から。1000〜1092px では仕様表が2列に入る幅
   （300px×2＋ガター24＝624px）をどう置いても確保できず1列に潰れ、
   表の高さが 438 → 583px になって画面から溢れる。
   1200px 以上なら 6〜12列が 634px となり2列を保てる。 */
@media (min-width: 1200px) and (min-height: 720px)
   and (hover: hover) and (pointer: fine) {
  html { scroll-snap-type: y mandatory; }
  /* ★scroll-margin-top 84px はスナップ領域を上へ広げるので、
     領域(984px) > スナップポート(900px) になり、「領域がポートを覆っていれば
     どこでも有効」という規則が効いて、同じ面が top にも top−84 にも止まる
     （実測で #spec / #lineup が 84px 手前に着地していた）。
     この幅では面の上余白 96px が固定ヘッダー 88px を上回るので余白は要らない。 */
  :where(section, .pin)[id] { scroll-margin-top: 0; }
  /* ★height 固定＋overflow:hidden にすると、入りきらない面の中身が
     黙って消える（実測で購入ボタンが画面外に落ちていた）。
     min-height にして、溢れたぶんは2フリックで読ませる。 */
  .snap {
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }
  /* ★同じ役割の余白に 0/88/96/98 と 0/24/32/48/64 の値が当たっていて、
     結果として内容の中心が面ごとに 50.0〜53.7% でばらついていた。
     1組に畳む。どちらも 24px ベースラインの倍数。
     ★上 96 / 下 24。
     「下を大きく」は固定ヘッダーが無いページの作法で、ここでは逆に効く。
     ヘッダーのピルが上端 20〜84px を覆うので、目が空きとして読むのは
     84px から下だけ。96/120 では見えている空きが 上119 : 下215（1440×900）
     で下が1.8倍あり、内容が上に張りついていた。
     ★効いているのは「上−下＝72px」の差だけで、合計は見た目に関与しない。
     min-height:100svh ＋ justify-content:center なので、余った高さは
     左右対称に配られ、比は差だけで決まる（実測：合計216でも120でも
     見えている空きの比は同じ）。だから合計は小さいほうがよい。
     溢れる面（1200×720 の #spec は中身636px）では内容の開始位置が
     そのまま上余白になるので、上を 96 に留めると下へのはみ出しも
     96−84＝12px で済む（上を144にすると60pxに増えた）。
     96 と 24 はどちらも 24px ベースラインの倍数。 */
  .snap.section,
  .world.snap,
  .pair.snap,
  .statement.snap { padding-block: 96px 24px; }
  /* 最後の1画面は CTA とフッターをまとめる */
  .closing {
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }
  .closing { min-height: 100svh; }
  /* ★width:100% が要る。.closing は flex なので margin:0 auto が stretch を
     打ち消し、この面だけ中身の幅に縮んでいた（1244.8 → 1191.6px）。
     .grid に入れたのと同じ対策。 */
  .closing #contact {
    flex: 1;
    width: 100%;
    display: flex;
    align-items: center;
    padding-block: var(--head-guard) var(--s3);
  }
  .closing #contact > .grid { flex: 1; }
  /* ピン留め：100svh ごとのスナップ点。位置指定なので高さには影響しない。 */
  .pin__snaps {
    position: absolute;
    inset: 0;
    pointer-events: none;
  }
  /* ★積み上げではなく top で置く。等間隔でない着地点を作れるようにするため。 */
  .pin__snaps > i {
    display: block;
    position: absolute;
    left: 0;
    right: 0;
    height: 100svh;
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }
  /* ★画面より高い面のための「下端の着地点」。
     mandatory で「スナップ領域がスナップポートより大きい」ときの挙動は
     仕様が曖昧なままエンジンごとに割れていて（csswg-drafts#6863）、
     Safari は「手を離すと先頭へ戻される」実装として名指しで挙がっている。
     Chromium は「領域がポートを覆っていればどこでも有効」なので溢れたぶんも
     読めるが、その前提は Safari / Firefox では成り立たない保証がない。
     下端にもうひとつ着地点を置いておけば、どのエンジンでも必ず読める。
     実測で 1200×720 のとき pair +12px / spec +6px / lineup +85px が溢れる。 */
  .snap { position: relative; }
  .snap__end {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
    scroll-snap-align: end;
  }
}

/* ────────────────────────────────────────────────
   Header
   ──────────────────────────────────────────────── */
.header {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  /* 本文と同じ最大幅・同じ左右余白に収める */
  width: min(var(--container), calc(100vw - var(--margin) * 2));
  /* ★1fr / auto / 1fr。左右の中身の幅が違っても、ナビは必ずピルの中央に来る。
     flex + space-between だと、ロゴと右のかたまりの幅差ぶんナビがずれる。 */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: clamp(10px, 1.6vw, 22px);
  height: 4rem;
  /* ★左右は同じにすること。24/10 と非対称にしていたとき、grid の内容box の
     中心がピルの中心から (24−10)/2 = 7px ずれ、中央列のナビがそのぶん右に
     寄っていた（実測：ピル中心720に対しナビ中心727）。
     ロゴの内側の余白は .site-logo 側で持つ。 */
  padding-inline: 0.625rem;
  border-radius: 999px;
}
.header.is-scrolled {
  /* ★top はいじらない。以前は 26px→20px に動かしていたので、
     スクロールを始めた瞬間にヘッダーが上へ滑る挙動になっていた（本人指摘）。
     スクロールで変わるのは「地の色と影」だけにする。 */
  /* ★変えるのは濃さだけ。傾き（background-image）は .glass のまま触らない。 */
  background-color: rgba(255, 255, 255, 0.44);
  box-shadow:
    0 12px 34px rgba(15, 23, 42, 0.13),
    0 3px 8px rgba(15, 23, 42, 0.08),
    inset 0 1px 1px rgba(255, 255, 255, 1),
    inset 0 -1px 1px rgba(255, 255, 255, 0.5),
    inset 0 0 0 1px rgba(255, 255, 255, 0.6);
}
.header__nav {
  justify-self: center;
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
}
.header__nav a {
  position: relative;
  z-index: 1;
  padding: 7px 13px;
  border-radius: 999px;
  font-size: var(--t-cap);
  letter-spacing: var(--ls-wide);
  color: var(--text-2);
  text-decoration: none;
  transition: color var(--dur-touch) var(--ease-out);
}
.header__nav a:hover { color: var(--ink); }
/* ★ガラスのマーカーの下なので、白ではなく墨。白のままだと地と同化して消える。
   周りの項目（--text-2）より濃くすることで「いまここ」を示す。 */
.header__nav a.is-current { color: var(--ink); }
/* ★レンズは「移動」と「伸び」を別の要素に分ける。
   ひとつの transform に translate と scaleX を同居させると、伸びを戻すために
   custom property を書き換えた瞬間に transform の transition が再スタートし、
   移動のイージングまで途中からやり直しになる（着地が鈍って合計 750ms になる）。
   外＝位置と幅、内＝伸びと縁の光。 */
.header__marker {
  /* ★ヘッダーの外に出したので fixed。z-index はヘッダー(100)より上。
     位置は site.js が画面座標で与える（--mx / --my）。 */
  position: fixed;
  top: 0;
  left: 0;
  z-index: 101;
  height: 30px;
  width: var(--mw, 0px);
  transform: translate(var(--mx, 0px), var(--my, 0px));
  opacity: 0;
  pointer-events: none;
  transition:
    transform 0.55s var(--ease-out),
    width 0.55s var(--ease-out),
    opacity 0.4s var(--ease-smooth);
}
.header__marker.is-on { opacity: 1; }
/* ナビが消える幅ではレンズも出さない（以前はナビの子だったので自動で消えていた） */
@media (max-width: 992px) { .header__marker { display: none; } }
/* ── Safari 用：レンズの中に敷いたナビの複製を歪ませる ──
   .hm-clip がピルの形に切り抜き、.hm-warp が filter:url() を掛け、
   .hm-nav がレンズの移動を打ち消して複製を画面に固定する。
   打ち消しの transition は外側の移動とまったく同じにすること。
   違うと移動中に複製がずれ、下の本物と二重に見える。 */
.hm-clip {
  display: none;
  position: absolute;
  inset: 0;
  border-radius: 999px;
  overflow: hidden;
}
.header__marker.lg-warp .hm-clip { display: block; }
.hm-warp {
  position: absolute;
  inset: 0;
  filter: var(--lg-url);
}
.hm-nav {
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(calc(-1 * var(--mx, 0px)), calc(-1 * var(--my, 0px)));
  transition: transform 0.55s var(--ease-out);
}
/* 複製は読み上げにも打鍵にも出さない。中のナビは元の位置に絶対配置する。 */
.hm-nav > .header__nav {
  position: absolute;
  top: var(--ny, 0px);
  left: var(--nx, 0px);
  display: block;
}
.header__marker > i {
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 999px;
  /* ★墨のピルではなくガラスの片にする（本人指示）。
     ヘッダー自身と同じ言語で、地・内側のハイライト・外側の柔らかい影を持つ。
     ★背後が暗くなくなるので、現在地の文字は白ではなく墨のまま
     （下の .is-current を参照）。 */
  /* ★地は 0.10 まで薄くする。レンズが文字の「上」に来る構造になったので、
     濃い地だと下の文字が白く飛ぶ（0.58 で 5.99:1 まで落ちた）。
     0.10 なら 11.93:1 で、縁のハイライトも残る（実測）。
     参考動画のレンズも地をほとんど持たず、縁と屈折で立体を出している。 */
  /* ★地は平らにしない。参考動画のレンズを縦に測ると、上端がわずかに締まり
     （地に対して −2.2%）、下へ向かって光がたまる（+7.5%）。ガラスの中を
     通った光が下の内側にたまる形で、これが「板ではなく塊」に見せている。
     ヘッダーの地はほぼ白（246）なので上へは +3.7% しか伸ばせないが、
     平坦な +1 から −5→+7 の傾きにするだけで厚みが出る。
     ★文字は縦の中ほど（30px のうち 8〜22px）にあるので、光をためるのは
     下の 2 割だけにして字にかからないようにする。 */
  background: linear-gradient(180deg,
    rgba(43, 49, 62, 0.077) 0%,
    rgba(43, 49, 62, 0.020) 30%,
    rgba(255, 255, 255, 0.22) 66%,
    rgba(255, 255, 255, 0.95) 100%);
  /* ★縁は4層で作る。参考動画のレンズを拡大して読み取った構成。
     ① 外側の柔らかい影（浮いていることを示す）
     ② 外周のごく淡い輪郭（地との境目を締める）
     ③ 内側の白い輪郭＋上下のハイライト（鏡面）
     ④ その内側の暗い等高線（ガラスの「厚み」。参考でいちばん効いている層）
     ⑤ 進行方向と反対の縁の寒色（色収差。参考では左縁にシアンが出ている） */
  box-shadow:
    0 2px 8px rgba(15, 23, 42, 0.10),
    0 0 0 1px rgba(60, 66, 80, 0.06),
    inset 0 1px 1px rgba(255, 255, 255, 1),
    inset 0 -1px 1px rgba(255, 255, 255, 0.6),
    inset 0 0 0 1px rgba(255, 255, 255, 0.75),
    inset 0 0 0 2.5px rgba(60, 66, 80, 0.055),
    inset calc(var(--mdir, 1) * 2px) 0 3px -1px rgba(120, 170, 255, 0.12);
  /* 進行方向へ伸びて、着地でわずかに行き過ぎてから戻る。
     振幅は最大 +14%（縦は −7%）。 */
  /* ★進行方向へ「伸びる」。原点を後ろの端に置くので、レンズは前へ
     引き伸ばされる（左右対称に膨らむのではなく、先に前が出る）。
     ★同時に縦を縮める。体積が保たれて見えるので、固い板ではなく
     液体が引き延ばされたように読める。 */
  transform-origin: calc(50% - var(--mdir, 1) * 50%) center;
  transform: scaleX(var(--ms, 1)) scaleY(var(--msy, 1));
  transition: transform 0.44s var(--ease-gel);
}
/* 進行方向の縁だけ明るくする。移動中だけ出て、着地で消える。 */
.header__marker > i::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  /* ★ガラスになったぶん、進行方向の光は白ではなく「明るさの増し」で出す。
     白を重ねると地と同化して見えないため。 */
  background: linear-gradient(calc(90deg * var(--mdir, 1)),
    rgba(255, 255, 255, 0.85) 0%,
    rgba(255, 255, 255, 0) 52%);
  opacity: var(--mglow, 0);
  transition: opacity 0.3s var(--ease-out);
}
/* ★屈折。ヘッダーの外に出したので入れ子が解け、濁らずに掛かる。
   site.js が要素ごとに細い縁の変位マップを作り、--lg-url を挿してから
   .lg-ready を付ける。Chromium 限定（WebKit Bug 245510）。
   効かない環境でも地と縁だけで成立する。 */
.header__marker > i.lg-ready {
  /* ★ぼかしは入れない。レンズが文字の上に来るので、blur(1px) でも
     下の文字がぼけて読めなくなる（実測）。屈折だけを掛ける。 */
  -webkit-backdrop-filter: var(--lg-url) saturate(1.15);
  backdrop-filter: var(--lg-url) saturate(1.15);
}
/* 購入ボタンはヘッダーのピルから独立させた別のピル */
/* 右上のかたまり：言語切替 ＋ 購入する */
.header-side {
  position: static;
  /* ★列を明示すること。992px 以下でナビが display:none になると
     グリッド項目ごと消え、残る2つ（ロゴと右のかたまり）が自動配置で
     1列目と2列目に入る。右のかたまりが真ん中の列に置かれ、その中で
     右寄せされるだけになっていた（実測：ピル右端から 769pxで293px、
     992pxで396px も内側にいた）。 */
  grid-column: 3;
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 10px;
}
.header-cta {
  position: static;
  height: 2.5rem;
  /* ★min-width で日英の幅を揃える。「購入」は2字で約71px、Buy は約70px と
     1px 強ずれる。両方が収まる下限を置いて同じ幅に落ち着かせる。
     em にしてあるのは自分の font-size 基準で、文字設定が変わっても崩れないため。 */
  min-width: 5.5em;
  padding: 0 1.375rem;
  font-size: var(--t-cap);
  border-radius: 999px;
}
/* 言語切替。ナビのピルと同じガラス。地は .glass が持つので here では持たない */
.lang {
  appearance: none;
  /* ★中身を中央に置く指定が無く、SVG がベースラインに乗っていた。
     実測：PC で 3.5px 上、スマホ（フッター側は flex だが中央指定なし）で
     縦横とも 9px 左上へずれていた。 */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 2.5rem;
  padding: 0 1rem;
  border: 0;
  border-radius: 999px;
  /* ★.glass の 0.30 では足りない。ナビのピルは壁の明るい所に載るので
     5.22:1 出るが、この位置はカーテンの影に重なって 4.44:1 まで落ちた（実測）。
     ここだけ地を厚くして、13px の文字でも 4.5:1 を割らないようにする。 */
  background: rgba(255, 255, 255, 0.46);
  color: var(--text-2);
  font: inherit;
  font-family: var(--latin);
  font-size: var(--t-cap);
  letter-spacing: var(--ls-wide);
  cursor: pointer;
  /* ★.glass の transition（0.5s）はスクロールで地が変わるヘッダー用。
     押して返事が要るボタンなので、こちらは触感の速さに寄せて上書きする。 */
  transition: background var(--dur-touch) var(--ease-out),
              color var(--dur-touch) var(--ease-out),
              transform var(--dur-touch) var(--ease-out);
}
.lang:hover { background: rgba(255, 255, 255, 0.52); color: var(--ink); }
.lang:active { background: rgba(255, 255, 255, 0.62); transition-duration: var(--dur-press); }

/* 購入ボタンも同じガラスだが、地を濃くして主役の座は渡さない。
   ★透け方は 0.78 が下限。これより薄いと白文字のコントラストが
   4.5:1 を割る（背景 #eceef2 に対して実測 8.6:1 → 4.4:1）。 */
/* ★以前は .glass を併記していたが、ガラスは親のピル1枚に集約した。
   入れ子の backdrop-filter は効かないので、地色だけをここで持つ。 */
.header-cta {
  background: rgba(24, 28, 36, 0.78);
  color: #f4f6fa;
  box-shadow:
    0 8px 28px rgba(15, 23, 42, 0.18),
    0 2px 6px rgba(15, 23, 42, 0.10),
    inset 0 1px 1px rgba(255, 255, 255, 0.28),
    inset 0 -1px 1px rgba(255, 255, 255, 0.10),
    inset 0 0 0 1px rgba(255, 255, 255, 0.16);
  transition: background var(--dur-touch) var(--ease-out);
}
.header-cta:hover { background: rgba(40, 46, 57, 0.82); }
.header-cta:active { background: rgba(16, 19, 25, 0.86); transition-duration: var(--dur-press); }

/* ★ここは以前「ナビだけのピル」を丸ごと消す指定だった。
   ヘッダーがロゴも右のボタンも含む1本のピルになったので、
   消すのはナビだけにする（ピルごと消すと上部が空になる）。 */
@media (max-width: 992px) {
  .header__nav { display: none; }
}

/* ────────────────────────────────────────────────
   Hero — 全面写真
   ──────────────────────────────────────────────── */
.hero {
  position: relative;
  height: 100svh;
  min-height: 560px;
  justify-content: flex-start;   /* .snap の中央寄せを打ち消す */
}
/* 3枚を重ね、時間でふわっと入れ替える */
.hero__photos { position: absolute; inset: 0; }
.hero__photos img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 2.6s var(--ease-smooth);
}
.hero__photos img.is-on { opacity: 1; }
/* コピーは家具のない「壁の面」に置く。写真は下側に家具が来るので上三分の一へ。
   万一背景が明るくても読めるよう、ごく淡い縦グラデを敷く。 */
.hero__overlay {
  position: absolute;
  left: 0;
  right: 0;
  top: clamp(230px, 46svh, 520px);   /* 3枚とも照明の下に来る高さ */
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--margin);
}
/* ★コピーの背後に白い帯は敷かない（本人指摘）。
   以前は rgba(255,255,255,0.42) のグラデーションを可読性のために置いていたが、
   帯として見えてしまう。部屋の写真は7枚とも壁が明るいので、素の写真の上でも
   墨の文字は読める（実測：最も暗い箇所でも 7.9:1）。 */
/* ★写真の z-index が外へ漏れないよう、ここで積み重ねの文脈を閉じる。
   JS 側も 1〜3 に固定してあるが、二重に止めておく。 */
.hero__photos { isolation: isolate; }
.device__screen { isolation: isolate; }
.hero__overlay { z-index: 1; }
.hero__title {
  font-weight: 500;
  font-size: var(--t-hero);
  line-height: 1.45;
  letter-spacing: var(--ls-flat);
  white-space: nowrap;   /* 改行は <br> だけ。中途半端な折返しをさせない */
}
/* 320px では 10文字がぎりぎり収まっているだけ。コピーが1文字増えると
   切れるので、狭い幅では折返しを許して切れないほうを優先する。 */
@media (max-width: 420px) {
  .hero__title { white-space: normal; }
}

/* ────────────────────────────────────────────────
   Statement
   ──────────────────────────────────────────────── */
.statement { padding-block: clamp(56px, 18vh, 160px); }
.statement__inner { width: 100%; }
.statement.snap { position: relative; }
.statement.snap { display: flex; align-items: center; }
.statement.snap > .statement__inner { width: 100%; }

/* ────────────────────────────────────────────────
   世界の空気 — スクロールで横に流れる帯
   ──────────────────────────────────────────────── */
.world { padding-block: var(--s6); }
.world__flow { overflow: hidden; }
/* 10枚を2周ぶん並べ、-50% まで動かして継ぎ目なくループ */
.world__strip {
  display: flex;
  gap: var(--s3);
  width: max-content;
  animation: worldflow 78s linear infinite;
  will-change: transform;
}
/* ★1周の距離は -50% ではない。gap があるぶん半ガターぶん足りない。
   帯は「10枚＋同じ10枚の複製」で、正しい1周＝1枚目の左端から11枚目の左端まで
   ＝（10枚の幅の合計）＋（ガター10個）。
   一方 -50% は（20枚の幅＋ガター19個）÷2 ＝（10枚の幅）＋ガター9.5個。
   差はちょうど半ガター＝12px で、78秒ごとに帯が12px 飛んでいた（実測：
   1440pxで 2628px 動くべきところ 2640px 必要）。半ガターを足して継ぎ目を消す。 */
@keyframes worldflow { to { transform: translateX(calc(-50% - var(--s3) / 2)); } }
/* ホバーで止める挙動は撤去。クリックできる要素ではないので、
   止まると「押せそう」に見えてしまう（本人指摘）。 */
@media (prefers-reduced-motion: reduce) {
  /* ★アニメを止めるだけだと overflow:hidden で 10枚中4枚に到達できなくなる。
     しかも消えるのが高温側なので「氷点下から灼熱まで」という節の主旨ごと落ちる。
     動きの代わりに手で送れるようにして、内容は落とさない。 */
  .world__strip { animation: none; }
  .world__flow { overflow-x: auto; scrollbar-width: thin; }
  /* 2周目は同じ写真の複製。送れるようになったら不要。 */
  .world__strip .place[aria-hidden="true"] { display: none; }
}
.place {
  width: auto;
  flex-shrink: 0;
}
.place img {
  height: min(36svh, 320px);
  width: auto;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius-md);
  filter: saturate(0.82);
}
.place__temp {
  margin-top: 14px;
  font-family: var(--sans);
  font-size: var(--t-head);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.place__temp small { font-size: var(--t-cap); font-weight: 500; margin-left: 2px; }
@media (max-width: 768px) {
  /* ★54s だと 46.4px/s で、1440px の 33.7px/s より 1.38倍速い。
     1周の幅が 2507px なので 74s で速さが揃う。 */
  .world__strip { animation-duration: 74s; }
}

/* ────────────────────────────────────────────────
   Pin scenes（スクロールスクラブ）
   ──────────────────────────────────────────────── */
/* ★スナップ点(.pin__snaps > i)は 100svh 刻みなので、ここも svh で揃える。
   vh と svh が混在すると4画面ぶんで誤差が積もり、狙った位置で止まらない。 */
.pin { height: calc(var(--pin-len, 4) * 100svh); position: relative; }
.pin__stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
}

/* ── 温度 → 色：画面いっぱいの実レンダー ── */
.temp-shots { position: absolute; inset: 0; }
.temp-shots img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.temp-shots img:first-child { opacity: 1; }
.temp-ui {
  position: absolute;
  left: 0;
  right: 0;
  bottom: var(--s5);
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  gap: var(--gutter);
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--margin);
  align-items: end;
  /* ★下のスクリム（::before）を .temp-ui の中に閉じ込めるための重ね順。
     これが無いと z-index:-1 が .temp-shots より後ろへ抜けて見えなくなる。 */
  z-index: 1;
}
.temp-ui__title { grid-column: 1 / span 5; }
.temp-ui__note {
  grid-column: 1 / span 5;
  font-size: var(--t-cap);
  /* ★ここだけ 26px で、同じ 13px の仕様表の見出しやフッターの 24px と
     ずれていた。サイト全体の 24px の刻みに揃える。 */
  line-height: 1.5rem;
  letter-spacing: var(--ls-flat);
  /* ★ここだけ実レンダーの上に直接乗るので、--text-2 では 3.54:1 しか出ない。
     白いスクリムを敷くと灯りの裾まで曇るので、文字側を締めて 4.57:1 にする。
     見出し（32px）との差はサイズが担うので、階層は崩れない。 */
  color: #454b57;
  max-width: 36em;
}
.temp-readout {
  grid-column: 10 / -1;
  /* ★注記と同じ行に置き、ベースラインで揃える。
     以前は 1 / span 3 で3行にまたがり align-self:end だったので、
     箱の下端だけが揃い、文字の大きさが違うぶんベースラインがずれていた
     （実測：墨の下端で数値が注記より 21.5px 下、1200px では 22.5px）。
     ★行をまたいでいる間は last baseline が効かない。ベースライン揃えは
     同じ行の要素どうしでしか成立しないため（実測：span 3 のままだと
     last baseline を当てても1pxも動かない）。 */
  grid-row: 2;
  align-self: last baseline;
  text-align: right;
}
.temp-readout__value {
  font-family: var(--sans);
  font-size: var(--t-disp);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--ls-tight);
  line-height: 1;
}
/* ℃ は数字に追従させたいので em のまま持つ */
.temp-readout__value small { font-size: 0.42em; font-weight: 500; margin-left: 4px; }
/* スロットのように桁が回る */

/* ── 構造：実時間3D ── */
/* ★プロダクトを画面いっぱいに使う。見出しは重なってよいので、
   3Dを面いっぱいに敷き、見出しだけを上に浮かせる。 */
.pin__stage--plain {
  display: block;
  padding: 0;
}
/* ★製品はほぼ白なので、地が --bg(#edeff2) のままだと輪郭が消える
   （実測で明度比 1.06:1）。この面だけ地を一段沈めて 1.30:1 にする。
   影を使わず面の明度差で組む、というこのサイトの作法どおりのやり方。 */
#structure { background: #bfc4ce; }  /* 3D側の背景(0xa9afba)のトーンマップ後に合わせる */
/* 3Dの上に重ねるが、位置は他の見出しと同じ1列目に揃える。
   中央揃えはページに1箇所（最後のCTA）だけにする。 */
/* ★位置は包みの箱（名前＋見出し）が持つ。見出し単体に持たせると
   節の名前を上に置けない。 */
.structure__head {
  position: absolute;
  /* ★+44px。以前は +8px（＝上端96px）で、ヘッダーのピルの下端84pxとの間隔が
     12px しかなかった。他の節の見出しは84〜203px 空いている。
     さらにピルの影（0 12px 34px）が下へ34px伸びるので、実際には見出しが
     影の中に入っていた（実測：この帯の26%がピルの影で覆われている）。
     132px にすると影の裾から14px 下に出る。3Dの円盤がこの帯まで届くのは
     7場面中1場面だけで、そこも円盤は明るく（233）文字は読める。 */
  top: calc(var(--head-guard) + 44px);
  left: 0;
  right: 0;
  z-index: 1;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--margin);
  pointer-events: none;
}
.explode {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
}
.explode__viewer {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.1s var(--ease-smooth);
  cursor: grab;
  touch-action: pan-y;
}
.explode__viewer.is-ready { opacity: 1; }
.explode__viewer:active { cursor: grabbing; }
.explode__viewer canvas { display: block; width: 100%; height: 100%; }
.explode__fallback {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  /* ★既定で隠す。以前は「読み込み中は静止画→読めたらフェード」だったが、
     その静止画は斜めの組んだ姿なので、リロードのたびに
     「斜めの照明が一瞬見える」バグとして見えていた（本人指摘）。
     GLB を読んでいる間は何も出さないのが正しい。静止画を出すのは
     WebGL が使えない・落ちたときだけ。 */
  opacity: 0;
  transition: opacity 1.1s var(--ease-smooth);
  /* ★これが無いと、透明なまま inset:0 で viewer 全面を覆い、
     ポインタを全部吸ってしまう。実測：円盤をドラッグしても回らず、
     当たっていた要素は毎回 IMG.explode__fallback だった。
     3D 側に回転・慣性のコードはあるのに、一度も届いていなかった。
     出ているときも「ただの静止画」なので、常に透過でよい。 */
  pointer-events: none;
}
.explode__viewer.is-failed ~ .explode__fallback { opacity: 1; }

/* ────────────────────────────────────────────────
   Pair — ふたつの部屋の対比
   ──────────────────────────────────────────────── */
.pair { padding-block: var(--s6) 0; }
.pair__rooms {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
}
.pair__room img {
  width: 100%;
  height: min(48svh, 480px);
  object-fit: cover;
}
/* ★写真は全面ブリードのままでよいが、キャプションは文字なのでカラム線に乗せる。
   以前はどちらも x=24（ページ最左）で、見出しと 73.6px ずれていた。
   左は1列目、右は7列目。7列目の線は必ずページ中央からガター半分ぶん右にあるので
   （grid の中心 = M + 6colw + 5.5g、7列目 = M + 6colw + 6g）、右は gutter/2 で決まる。 */
.pair__room:first-child figcaption {
  padding-left: calc(max(0px, (var(--vw, 100vw) - var(--container)) / 2) + var(--margin));
}
.pair__room:last-child figcaption {
  padding-left: calc(var(--gutter) / 2);
}
.pair__room figcaption {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 16px var(--gutter) 0;
  font-size: var(--t-cap);
  letter-spacing: var(--ls-flat);
  line-height: var(--bl);
  color: var(--text-3);
}
.pair__room figcaption b {
  font-size: var(--t-cap);
  font-weight: 500;
  letter-spacing: var(--ls-wide);
  color: var(--ink);
}
@media (max-width: 768px) {
  .pair__rooms { grid-template-columns: 1fr; }
  .pair__room img { height: 52vw; min-height: 220px; }
  /* ★1カラムになったら、上の「右は7列目に乗せる」規定は無効。
     そのままだと2枚目のキャプションだけ gutter/2 ＝ 8px の位置に出て、
     1枚目（20px）と揃わなかった（実測：390pxで20 vs 8、768pxで31 vs 8）。
     縦積みでは2枚とも本文と同じマージンに乗せる。 */
  .pair__room:first-child figcaption,
  .pair__room:last-child figcaption {
    padding-left: var(--margin);
    padding-right: var(--margin);
  }
  /* ★下の余白。横並びのときは隣同士なので要らないが、縦積みでは
     キャプションの下端が次の写真に 0px で接し、説明が「下の写真のもの」に
     見えていた（実測：自分の写真からは 16px、次の写真とは 0px）。
     写真→説明 16px に対し、説明→次の写真を 40px にして所属を明示する。 */
  .pair__room figcaption { padding-bottom: 40px; }
  .pair__room:last-child figcaption { padding-bottom: 0; }
}

/* ────────────────────────────────────────────────
   App
   ──────────────────────────────────────────────── */
.store {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "icon meta badges";
  align-items: center;
  gap: clamp(24px, 3.4vw, 44px);
  padding: clamp(28px, 4vw, 48px) clamp(28px, 4vw, 52px);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  background: var(--fill);
}
.store__icon {
  grid-area: icon;
  width: clamp(92px, 9vw, 124px);
  height: auto;
  border-radius: 22.5%;
}
.store__meta { grid-area: meta; min-width: 0; }
.store__name {
  font-size: var(--t-sub);
  font-weight: 500;
  letter-spacing: var(--ls-flat);
}
.store__name span {
  margin-left: 10px;
  font-family: var(--latin);
  font-size: var(--t-cap);
  font-weight: 500;
  letter-spacing: var(--ls-wide);
  color: var(--text-3);
}
/* ★430px で「WORLD CL℃K Inc.・ライフスタイル」が折れ、最終行に「ル」1文字だけが
   残っていた（実測）。keep-all＋<wbr> が「ライフスタイル」を割らない。 */
.store__dev {
  font-size: var(--t-cap); color: var(--text-3); letter-spacing: var(--ls-wide);
  text-wrap: pretty;
}
.store__stats {
  display: flex;
  gap: clamp(28px, 3vw, 44px);
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--line-soft);
}
.store__stats > div { display: flex; flex-direction: column; line-height: 1.6; }
.store__stat {
  font-family: var(--sans);
  font-size: var(--t-sub);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.store__stat i { font-style: normal; font-size: var(--t-label); margin-left: 2px; color: var(--text-3); }
.store__stats small { font-size: var(--t-label); color: var(--text-3); letter-spacing: var(--ls-wide); }
.store__badges {
  grid-area: badges;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  padding-left: clamp(24px, 3vw, 44px);
  border-left: 1px solid var(--line-soft);
}
.badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 2.875rem;
  padding: 0 1.125rem;
  border: 0;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  cursor: pointer;
  transition: background var(--dur-touch) var(--ease-out);
}
.badge:hover { background: #3c424e; }
.badge__glyph { width: 20px; height: 20px; }
/* ★Apple マークだけ「重い所」が下にある。葉が上に細く伸びるぶん外形の中心は
   合っていても、面積の重心はピルの中心より 1.44px 下にいた（実測。Play の
   三角は +0.19px で問題なし）。マークの形の問題なので、Apple だけ持ち上げる。 */
.badge__glyph--apple { margin-bottom: 3px; }

/* ── 欧文だけ、ピル型ボタンの文字が下に沈む ──
   align-items:center が揃えるのは「行ボックス」であって墨ではない。
   欧文は上に使われないアセンダの空きが残り、下にはディセンダ（p / y / g）が
   伸びるので、墨の重心が箱の中心より下に来る。
   実測（8倍で撮って墨の面積の重心を取った値。ずれ＝ピル中心からの差）：
     英語  .btn 暗 +1.44px / .btn 白 +1.94px / ナビ +1.44px
     日本語 .btn 暗 -0.31px / .btn 白 +0.38px / ナビ +0.06px
   和文は仮想ボディのほぼ中央に字面が入るのでずれない。よって英語のときだけ直す。
   下に 3px 足すと箱ごと 1.5px 持ち上がる（box-sizing:border-box・高さ固定のため）。 */
/* ★補正量は 3px（＝1.5px 持ち上げ）から 2px（1px）へ。
   判定基準が2つあり、約2px 食い違うため中間を取った：
     ・面積の重心で見ると、補正前は +1.4px 下（小文字の量が下に寄る）
     ・墨の外接で見ると、3px 補正後は「Go to store」のように
       ディセンダの無い語が 1.7px 上がりすぎる
   1px の持ち上げなら、どちらの基準でも1px以内に収まる。 */
html[lang="en"] .btn { padding-bottom: 2px; }
/* ナビは高さが中身で決まるので、上下の合計を変えずに配分だけ変える。
   増やすと行が高くなり、ホバーの丸マーカー（JSが矩形から位置を取る）までずれる。 */
html[lang="en"] .header__nav a { padding: 6px 13px 8px; }
/* ★「Download on the」の小見出しをやめたので、2行組みの縦積みも要らない。
   1行になったぶん字面が小さく見えるので、キャップ相当まで一段上げる。 */
.badge__text {
  /* ★align-items:center が揃えるのは「行ボックス」の中心で、墨の中心ではない。
     欧文はディセンダ（g / y / p）の分だけ墨が下に伸びる一方、上には
     使われないアセンダの空きが残るので、実測で墨の中心がボタンの中心より
     1.5px 下にいた（ボタン46px：墨 17.5〜31.5＝中心24.5 / ボタン中心23.0）。
     下に 3px の余白を足すと、箱ごと 1.5px 持ち上がって墨の中心が合う。
     transform でずらすと文字がにじむので padding で動かす。 */
  padding-bottom: 3px;
  font-size: var(--t-body);
  font-weight: 500;
  font-family: var(--latin);
  letter-spacing: var(--ls-flat);
}
/* ★1.9 の比率だと 20.9px という端数になり、行が半ピクセルずつずれる。
   同じ 11px の .place__loc（16px）と揃えるほどは詰められないので 20px に固定。 */
.store__note { text-wrap: pretty; font-size: var(--t-label); line-height: 1.25rem; color: var(--text-3); max-width: 24em; }

/* ── 端末はCSSで作るフラットな枠（Blenderのレンダーは重いのでやめた） ──
   ベゼル＋Dynamic Island だけの簡素な形。 */
/* ── 端末：黒ベタのシンプルな形 ──
   ★画面の箱は「島の帯 + スクショ」の合成比 393:908 にする。
     スクショ(393:852)を上から 6.17% の位置に 93.83% の高さで置くと、
     画像の箱の比がちょうど 393:852 になり、拡縮も切り取りも起きない。
     画像をずらしたり cover で切ると、下端のタブバーが枠に食われる。 */
.device {
  position: relative;
  display: inline-block;
  padding: 10px;
  /* ★角丸は寸法に追従させる。iPhone 15 Pro は画面角 R 55pt / 幅 393pt ＝ 14%。
     固定 px だと端末を小さく描くほど丸くなりすぎる（本人指摘）。
     百分率の border-radius は「横＝幅の%／縦＝高さの%」なので、
     縦は 14% × 393/908 ＝ 6.06% にすると角が真円になる。
     外枠は内側 +10px（ベゼル厚）ぶんを足して同心に。 */
  border-radius: calc(14% + 7px) / calc(6.06% + 7px);
  background: #0b0c0f;
  box-shadow:
    0 26px 50px rgba(15, 23, 42, 0.22),
    0 6px 14px rgba(15, 23, 42, 0.12);
}
.device__screen {
  position: relative;
  height: min(66svh, 700px);
  aspect-ratio: 393 / 908;      /* 852 + ステータスバー領域 56pt */
  border-radius: 14% / 6.06%;
  overflow: hidden;
  /* ★地色はアプリの画面色。上下に残る帯（ステータスバー / ホームインジケータ）は
     ここが透けて見えるので、黒だと「黒い帯」になる（本人指摘は下部の件）。
     （本人指摘：実機はこんなに黒くない）。実機ではアプリの地色が
     最上部まで伸び、黒いのは Dynamic Island だけ。
     4画面のスクショの最上段は全て rgb(230,233,239) ＝ この色で埋める。 */
  background: #e6e9ef;
}
.device__screen img {
  position: absolute;
  top: 6.17%;                   /* 56 / 908 */
  left: 0;
  width: 100%;
  /* ★下端いっぱい(93.83%)まで敷くと、アプリのタブバーが画面の縁に
     くっついて見える（本人指摘）。実機ではタブバーの下に
     ホームインジケータの帯（34pt相当）が挟まる。その分だけ持ち上げる。 */
  height: 90.0%;
  opacity: 0;
  transition: opacity 0.7s var(--ease-smooth);
}
/* ホームインジケータ */
.device__screen::after {
  content: "";
  position: absolute;
  bottom: 0.95%;
  left: 50%;
  transform: translateX(-50%);
  width: 36%;
  height: 0.55%;
  border-radius: 999px;
  background: rgba(28, 32, 40, 0.72);
  z-index: 1;
}
.device__screen img.is-on { opacity: 1; }
/* Dynamic Island（iPhone 15 Pro 実寸 125×37.33pt、上余白 11pt） */
.device__island {
  position: absolute;
  top: 1.21%;                   /* 11 / 908 */
  left: 50%;
  transform: translateX(-50%);
  width: 31.8%;                 /* 125 / 393 */
  aspect-ratio: 125 / 37.33;
  border-radius: 999px;
  background: #000;
  z-index: 1;
}
@media (max-width: 576px) {
  /* 角丸は百分率で自動追従するので、ここではベゼル厚だけ詰める */
  .device { padding: 7px; border-radius: calc(14% + 5px) / calc(6.06% + 5px); }
  .device__screen { height: min(56svh, 470px); }
}

/* ────────────────────────────────────────────────
   Spec — テキストのみ
   ──────────────────────────────────────────────── */
.spec-grid {
  display: grid;
  grid-template-columns: repeat(var(--cols), minmax(0, 1fr));
  gap: var(--gutter);
  align-items: start;
}
/* ★他の5面はすべて「見出し 1〜4列 ＋ 本文 6〜12列」。仕様の面だけが
   丸ごと1列（105.7px）左にずれていた。空白の幅は同じなので別の型ではなく単なるずれ。
   なお7列目からにはできない（7〜12列＝610.4px で、300px×2＋ガター24＝624px に
   9.6px 足りず表が1列に潰れる）。見出しは4列が上限、右ブロックは6列目が確定。 */
.spec-grid > div:first-child { grid-column: span 4; }
.spec-grid > .spec { grid-column: 6 / -1; }
@media (max-width: 992px) {
  .spec-grid > div:first-child, .spec-grid > .spec { grid-column: 1 / -1; }
}
.spec { border-top: 1px solid var(--line); }
/* 2段組の段間はガターと同じにする。そうすると右の段の左端が
   ちょうど7列目に落ちる（64pxだと23pxずれていた）。 */
/* ★2段組をやめて1段にする。
   実測：1024px では1段（値の幅428px）で 11行中0行しか折り返さないのに、
   1440px では2段になって値の幅が234pxまで落ち、11行中9行が2行になっていた。
   画面を広げるほど表が読みにくくなる、という逆転が起きていた。
   2段が成立するには1段あたり見出し106＋間20＋値343（欧文最長
   "Australian BoM apparent temperature (AT) formula"）＝469px 必要で、
   2段だと 962px。表の箱は 1920px でも 709px（コンテナ上限1184pxの6〜12列）
   までしか広がらないので、2段は原理的に成立しない。
   1段なら値に604px使えて、和欧どちらの最長値も1行に収まる。 */
.spec--two {
  display: grid;
  grid-template-columns: 1fr;
  column-gap: var(--gutter);
  border-top: 0;
}
.spec--two > div { border-top: 1px solid var(--line-soft); }
/* ★見出し列の 120px は欧文（Apparent temperature ＝約135px）に合わせた幅。
   和文の見出しは最長でも「本体サイズ」の5文字＝約70px なので、120px だと
   50px を捨てて値の側が 206px しか残らず、付属品や電源が3行に折れていた（実測）。
   和文のときだけ 92px に詰めて、その分を値へ回す（206→234px）。 */
html[lang="ja"] .spec > div { grid-template-columns: 92px 1fr; }
.spec > div {
  display: grid;
  /* ★欧文で最長の見出しは「Apparent temp.」で実測113px。
     0.8fr にしていたら1段組にした余白を吸って199pxまで伸び、
     見出しと値のあいだに86pxの死んだ隙間ができていたので固定値にする。 */
  grid-template-columns: 120px 1fr;
  gap: 20px;
  padding: 14px 0;
  border-bottom: 0;
}
/* ★スマホでは見出し列（92〜120px）が値から3割を奪って、11行中7〜9行が
   2行に折れていた。横に並べる幅がないので、見出しを値の上に積む。 */
@media (max-width: 576px) {
  .spec > div,
  html[lang="ja"] .spec > div { grid-template-columns: 1fr; gap: 4px; }
}
.spec dt { font-size: var(--t-cap); letter-spacing: var(--ls-wide); color: var(--text-3); }
.spec dd {
  font-size: var(--t-body);
  letter-spacing: var(--ls-wide);
  /* 2段組の1段が 346px なので和文がよく折り返す。
     「ACアダ／プタ付属」のような割れ方を避けて文節で折る。 */
}
@media (max-width: 768px) {
  .spec-grid { grid-template-columns: 1fr; }
}

/* ────────────────────────────────────────────────
   CTA
   ──────────────────────────────────────────────── */
/* ★幅は ch（欧文の「0」幅）基準で 4.69列〜9.08列という半端な位置にいた。
   HTML 側で 4〜9列の箱に入れ、幅の決定は列に任せる。 */
.cta { text-align: center; padding-block: 0; }
/* ★360px で最終行に「す。」の2文字だけが残っていた（実測）。
   中央寄せなので短い最終行はまん中に浮いて特に目立つ。
   折る位置は keep-all＋<wbr> が決め、pretty で最終行の長さを均す。 */
.cta__body {
  margin-top: var(--s3); color: var(--text-2);
  font-size: var(--t-body); line-height: var(--bl);
  text-wrap: pretty;
}
.cta__actions {
  display: flex;
  justify-content: center;
  gap: 14px;
  margin-top: var(--s5);
  flex-wrap: wrap;
}
/* ★20px は 8pt の刻みにも自分の行送り 24px にも乗っていなかった。 */
/* ★中央寄せの注記は、最後の1語だけが次行に落ちる（実測：英語で
   「…about two weeks to / deliver.」）。pretty は最終行が
   極端に短くならないよう折り位置を選び直す。 */
.cta__note { text-wrap: pretty; max-width: 46em; margin-inline: auto; margin-top: var(--s3); font-size: var(--t-label); letter-spacing: var(--ls-wide); color: var(--text-3); }

/* ────────────────────────────────────────────────
   Footer
   ──────────────────────────────────────────────── */
/* ★padding-inline を .footer に持たせていたので、中身は max-width で
   さらに内側に寄り、1440 で 40px・1920 で 64px だけ1列目より左にいた。
   背景と罫線は全幅のまま、中身を .grid と同じ3段（max-width → auto → padding）に通す。 */
.footer {
  border-top: 1px solid var(--line-soft);
  background: var(--fill);
  padding: var(--s5) 0 var(--s3);
}
.footer__nav,
.footer__legal {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--margin);
}
.footer__logo { height: 22px; width: auto; aspect-ratio: 943.82 / 160; }
/* 英語ロゴは横幅の比率が違う（943.82:160 → 1500:160）ので一緒に替える。 */
html[lang="en"] .footer__logo { aspect-ratio: 1500 / 160; }
.footer__nav {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 220px));
  gap: var(--gutter);
  /* ★3列 × 220px ＋ ガター48 = 708px しか使わず、1244px の器の右 536px（43%）が
     空いていた。下の帯（ロゴ｜法務｜著作権）は全幅なので、そこだけ左に寄って見える。
     塊の幅は 220px のまま、余りを塊の間に配って器の端まで届かせる。
     ★768px 以下は 1fr 1fr で余りが出ないので、この指定は効かない。 */
  justify-content: space-between;
}
.footer__nav > div { display: flex; flex-direction: column; gap: 8px; }
.footer__head { font-size: var(--t-label); font-weight: 500; letter-spacing: var(--ls-wide); color: var(--ink); margin-bottom: 6px; }
/* ★販売ページだけ URL がまだ無いので <span> で置いている。
   a と同じ見た目に揃えないと、そこだけ濃く出て「現在地」に見える。 */
.footer__nav a,
.footer__nav > div > span {
  font-size: var(--t-cap);
  color: var(--text-2);
  text-decoration: none;
  letter-spacing: var(--ls-wide);
  transition: color var(--dur-touch) var(--ease-out);
}
.footer__nav a:hover { color: var(--ink); }
/* ★3列固定（ロゴ｜リンク｜著作権）だと、真ん中に残る幅が足りない所で
   リンクだけが2行に折れて左右非対称になっていた
   （実測：和文 820〜900px で枠403〜477px に対し必要505px、欧文 1024px でも発生）。
   横並びのまま「入らなければリンクごと次の行へ」に変える。 */
.footer__legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3) var(--s4);
  margin-top: var(--s5);
  padding-top: var(--s3);
  border-top: 1px solid var(--line-soft);
}
@media (max-width: 768px) {
  .footer__legal { flex-direction: column; align-items: flex-start; gap: var(--s3); }
}
/* 入るときは1行に収まり、入らないときだけ自分の行へ落ちる幅を基準にする */
.footer__links { display: flex; gap: 22px; flex-wrap: wrap; list-style: none; flex: 1 1 auto;
                 justify-content: center; }
@media (max-width: 768px) { .footer__links { justify-content: flex-start; } }
/* 飛び先ができるまでは <span>。押せると見せて何も起きないほうが不親切なので、
   リンクにはせず色の変化も付けない。 */
.footer__links span {
  font-size: var(--t-label);
  letter-spacing: var(--ls-wide);
  color: var(--text-3);
}
.footer__copy { font-size: var(--t-label); letter-spacing: var(--ls-wide); color: var(--text-3); }
@media (max-width: 768px) { .footer__nav { grid-template-columns: 1fr 1fr; } }

/* ────────────────────────────────────────────────
   入場モーション
   ──────────────────────────────────────────────── */
/* ★.js が付いているとき＝JSが生きているときだけ隠す。
   付かなければ最初から見えている（JSが落ちても白くならない）。 */
.js .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 1.2s var(--ease-out), transform 1.2s var(--ease-out);
}
.reveal.is-in { opacity: 1; transform: none; }
.js [data-stagger] > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 1.0s var(--ease-out), transform 1.0s var(--ease-out);
  transition-delay: calc(var(--d, 0) * 90ms);
}
.reveal.is-in [data-stagger] > *,
[data-stagger].is-in > * { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal, [data-stagger] > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  /* ★スクロール連動を止めるので、4画面ぶんの空走もいらない。
     20画面ぶんを黙って通過させても何も起きない面になる。 */
  .pin { height: 100svh; }
}

/* ────────────────────────────────────────────────
   Mobile
   ──────────────────────────────────────────────── */
@media (max-width: 992px) {
  .store { grid-template-columns: auto 1fr; grid-template-areas: "icon meta" "badges badges"; }
  .store__badges { border-left: 0; padding-left: 0; border-top: 1px solid var(--line-soft); padding-top: 18px; }
}

/* ── レスポンシブ ──
   576 / 768 / 992 / 1200 の4段。fluid な clamp を基本にし、
   段でしか変えられないもの（並び・表示/非表示）だけメディアクエリで扱う。 */
@media (max-width: 992px) {
  /* ★ロゴ・右のかたまりとも、ピルの grid が位置を決めるようになったので
     ここで top / transform を触る必要はなくなった。 */
  .site-logo__mark { height: 17px; }
  .pair__rooms { grid-template-columns: 1fr; }
  .pair__room img { height: 56vw; min-height: 240px; }
  .store { grid-template-columns: auto 1fr; grid-template-areas: "icon meta" "badges badges"; }
  .store__badges { border-left: 0; padding-left: 0; border-top: 1px solid var(--line-soft); padding-top: var(--s3); }
  .temp-ui__title, .temp-ui__note { grid-column: 1 / -1; }
  .temp-readout { grid-column: 1 / -1; grid-row: auto; text-align: left; }
}
@media (max-width: 768px) {
  /* ★屈折フィルタは .glass.lg-ready（詳細度 0,2,0）なので上で消せない。 */
  .glass.lg-ready.header { -webkit-backdrop-filter: none; backdrop-filter: none; }
  :root { --gutter: 16px; }
  .footer__nav { grid-template-columns: 1fr 1fr; }
  /* ★スマホのヘッダーはロゴだけ。狭い幅で3者を並べると製品の絵に
     使える面積が削られるうえ、ロゴが中央に来ない。
     ナビはもともと非表示、言語はフッターへ移してあるので、
     ここで消えるのは購入ボタン（最後の面に同じものがある）。
     ★ピルで囲まない。地・影・屈折は .glass / .is-scrolled が持っているので
     ここで全部打ち消す（class は CSS から外せない）。
     ロゴは左上。箱の左端＝本文と同じマージンなので、内側の余白を 0 にすると
     記号の左辺が本文の1列目にそのまま乗る。 */
  .header,
  .header.is-scrolled {
    grid-template-columns: 1fr;
    justify-items: start;
    height: auto;
    padding: 0;
    background: none;
    box-shadow: none;
    border-radius: 0;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  /* ★本文の1列目にぴったり合わせると、弧の細く尖った左端が
     グリッドから落ちて見える。8px だけ内へ寄せて光学的に揃える。 */
  .site-logo { justify-self: start; padding-left: 8px; padding-right: 0; }
  .header__nav, .header-side { display: none; }
  /* ★スクロールしても残す（本人の判断）。囲みが無いので、本文の黒い
     文字の上を弧が通る場面がある（実測：ヒーローの見出しと重なるとき
     コントラスト1.00、縦37地点のうち8地点が4.5:1未満）。
     地を敷けば解けるが「囲まない」が要件なので、そのまま出す。 */
}
/* ★320px でストアカードの3項目が5px はみ出し、ページに横スクロールが出ていた。
   原因はカードがアイコン＋本文の2列のままで、本文欄が126pxしか無いのに
   3項目が175px 必要だったこと（実測）。
   .store__stats を minmax(0,auto) にして縮める手もあるが、それだと 360px でも
   「アプリ内課金なし」が2行に折れて、いま問題の無い幅まで劣化する（実測）。
   ここだけカードを1列に畳んで本文欄に全幅を渡す。 */
@media (max-width: 340px) {
  /* ★.store だけでは効かない。同じ詳細度の .store--stack が
     この規則より後（レスポンシブ節の末尾）にあって勝つ。
     .store.store--stack で詳細度を上げる。 */
  .store,
  .store.store--stack {
    grid-template-columns: 1fr;
    grid-template-areas: "icon" "meta" "badges";
  }
}
@media (max-width: 576px) {
  body { font-size: var(--t-body); }
  .header__nav { display: none; }
  .store { padding: var(--s4) var(--s3); }
  /* ★flex + wrap だと 3項目が 2+1 に折れ、「無料／アプリ内課金なし」だけが
     次の行に取り残されて空きが目立っていた（390px 実測）。
     3等分の格子にして必ず1行に並べる。 */
  /* 3等分だと「32件の評価」が1列に収まらず「32件の／評価」と折れた。
     中身の幅で3列にして、余りは列の間へ逃がす。 */
  .store__stats { display: grid; grid-template-columns: auto auto auto;
                  justify-content: space-between; gap: 10px; }
  /* ★「アプリ内課金なし」が「アプリ内課／金なし」と熟語の途中で割れていた。
     keep-all＋<wbr> が文節の切れ目（アプリ内／課金なし）で折る。 */
  /* ★10px まで落としていたが、サイトの下限は 11px（--t-label）。
     列を等分から中身の幅に変えたので 11px でも1行に収まる。 */
  .store__stats small {
    letter-spacing: 0;
    text-wrap: pretty;
  }
  /* ★アイコンは既定で meta 全体（名前＋区切り線＋評価）に対して天地中央なので、
     meta が3行に伸びる狭い幅では区切り線の高さまで下がり、名前から離れて見えた。
     上端を名前に揃える。 */
  .store--stack .store__icon { align-self: start; }
  .cta__actions { flex-direction: column; }
  .cta__actions .btn { width: 100%; }
}


/* ── スマホの構造シーン ──
   ★3Dは stage 全面に敷いてあり、縦長の画面ではカメラが横幅で画角を決めるため、
   製品が小さいまま上下に大きな余白が残る（390x844 で円盤の下に 470px の空き）。
   温度の面と同じ作りに揃える：見出しを流し、3Dは高さを決めた帯にして、
   塊ごと天地中央に置く。面ごとに構成の型が違うのをやめる。 */
@media (max-width: 768px) {
  #structure .pin__stage {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 24px;
    padding-top: var(--head-guard);
  }
  /* ★flex の子では margin-inline:auto が「中央寄せ」として効く。
     見出しはサイト全体で1列目の左揃えなので、幅を100%にして auto を殺す。
     位置を持つのは包みの箱（名前＋見出し）のほう。 */
  .structure__head { position: relative; top: auto; z-index: 1; width: 100%; }
  /* ★3D の地色は 3D 側が塗っている。帯にすると節の地色との段差が見える。
     色は viewer.js が「実際に描かれた背景の画素」を読んで節に書き戻すので、
     ここの値は 3D が読み込めない間の近似でしかない。
     ★それでも矩形の輪郭は残る（3D側にはノイズの粒とにじみがあり、
     色を完全に合わせても質感の境目が水平線として読める。等倍実測で確認）。
     帯の上下 32px をフェードして、質感ごと地に溶かす。 */
  #structure { background: rgb(180, 183, 191); }
  .explode {
    position: relative; inset: auto; height: 52svh; flex: none;
    -webkit-mask-image: linear-gradient(180deg,
      transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%);
    mask-image: linear-gradient(180deg,
      transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%);
  }
}

/* ── スマホの温度シーン ──
   ★横長(2000x857)の絵を縦長の画面に cover すると、原画の横20%しか映らない
   （390x844 実測。デスクトップは69%）。中央だけが拡大されるので照明が巨大に
   見えて、左右へ広がる光が画面外へ切れてしまう。
   スマホでは全面に敷くのをやめ、上に絵の帯、その下に文字、と面を分ける。
   帯の高さ 38svh なら原画の横 56% が入り、円盤は画面幅の 54% に収まる。 */
@media (max-width: 768px) {
  /* ★絶対配置に固定の top を積むと、機種の高さが変わるたびに
     下の余りが変わる（844px で 170px 余った）。縦フローに直して
     「帯＋文字」の塊ごと天地中央に置く。数字は帯の高さだけで済む。 */
  #feature .pin__stage {
    background: var(--bg);
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 28px;
    padding-top: var(--head-guard);
  }
  .temp-shots { position: relative; inset: auto; height: 38svh; flex: none; }
  .temp-ui { position: relative; inset: auto; align-items: start; }
  /* 文字は絵の外に出たので、読ませるためのスクリムは不要 */
  .temp-ui::before { display: none; }
}

/* ── ヘッダーの購入ボタンの光学補正 ──
   ★言語ボタン（直径40pxの円）と購入ボタン（40×99pxのピル）は
   実測で高さも上下端も完全に一致している（どちらも 40.0px / top 26 / bottom 66）。
   それでも購入のほうが低く見えるのは形の差で、横に長いピルは同じ高さの円より
   平たく読める。幾何ではなく見た目を合わせるので、ピル側だけ 2px 足す。 */
/* ★min-width で日英の幅を揃える。「購入」は 2 字＝約71px、Buy は約70px と
   1px 強ずれるので、両方が収まる 5.5em を下限にして同じ幅に落ち着かせる。
   em にしてあるのは自分の font-size（13px）基準で、文字設定が変わっても
   比が崩れないため。height の +2px は光学補正（既存）。 */
.header-cta { height: calc(2.5rem + 2px); min-width: 5.5em; }

/* ── 言語切替のアイコン ──
   文字（EN／日本語）をやめて地球儀にする。文字だと切り替えのたびに
   ボタン幅が 51→70px と変わり、右隣の購入ボタンごと位置が動いていた。
   幅＝高さの正方形にして、どちらの言語でも動かない。 */
.lang {
  width: 2.5rem;
  padding: 0;
  flex: none;
}
.lang__icon {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linecap: round;
  /* ★経線・緯線は外周より細くする。同じ太さだと球ではなく
     平らな模様に見える（実測で線が4本とも同じ濃さになる）。 */
  vector-effect: non-scaling-stroke;
}
.lang__icon circle { stroke-width: 1.4; }
.lang__icon ellipse, .lang__icon path { stroke-width: 1.05; opacity: 0.8; }

/* ── 言語切替の置き場所 ──
   ★スマホではヘッダーから外してフッターに置く。上部の横幅が狭く、
   ロゴ・言語・購入の3つを並べると製品の絵に使える面積が削られるため。
   ボタンは HTML に2つあり、幅で出し分ける（付け替えないので
   リサイズのたびにフォーカスが飛ぶこともない）。 */
.lang--foot { display: none; }
@media (max-width: 768px) {
  .header-side .lang { display: none; }
  .lang--foot {
    display: inline-flex;
    background: rgba(255, 255, 255, 0.66);
    border: 1px solid var(--line);
    backdrop-filter: none;
  }
}

/* ── 前面円盤の仕上げ切り替え ──
   ★通常は出さない。円盤はスクロールで白→木→石と入れ替わるので、
     3種類とも見ることができ、ボタンは重複した案内になる。
   ただし「動きを減らす」設定のときは、ピンが1画面に潰れて
   スクロールで送る余地が無くなり、円盤が1種類のまま固定される。
   その場合だけ、内容に届く手段としてボタンを残す。 */
.finish {
  position: absolute;
  left: 50%;
  bottom: clamp(24px, 5vh, 56px);
  transform: translateX(-50%) translateY(10px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-calm) var(--ease-out),
              transform var(--dur-calm) var(--ease-out),
              visibility 0s linear var(--dur-calm);
}
.finish.is-on {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
  transition-delay: 0s;
}
/* ★この2行は上の .finish / .finish.is-on より後ろに置くこと。
   同じ詳細度なので、前に置くと display:flex に上書きされる（実測で
   display=flex のまま残った）。 */
.finish { display: none; }
@media (prefers-reduced-motion: reduce) { .finish { display: flex; } }
.finish__label {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.25rem;
  color: var(--text-3);
}
.finish__opts { display: flex; gap: 8px; }
.finish__opt {
  appearance: none;
  border: 1px solid rgba(28, 32, 40, 0.14);
  background: rgba(255, 255, 255, 0.72);
  color: var(--text-2);
  font: inherit;
  font-size: 0.875rem;
  line-height: 20px;
  padding: 7px 20px;
  border-radius: 999px;
  cursor: pointer;
  transition: background var(--dur-touch) var(--ease-out),
              border-color var(--dur-touch) var(--ease-out),
              color var(--dur-touch) var(--ease-out);
}
.finish__opt:hover { background: #fff; border-color: rgba(28, 32, 40, 0.26); }
.finish__opt:active { transition-duration: var(--dur-press); }
.finish__opt.is-on {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}
@media (prefers-reduced-motion: reduce) {
  .finish { transition: none; }
}

/* ── 3Dの「作り物感」を抜くための後処理 ──
   ・粒状感：真っさらなグラデーションはCGにしか見えない。写真は必ず粒を持つ。
   ・周辺減光：レンズで撮ったなら四隅は必ず落ちる。
   どちらもキャンバスの上に薄く重ねるだけなので、描画の負荷は増えない。 */
.explode__viewer::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    radial-gradient(120% 100% at 50% 45%,
      rgba(0, 0, 0, 0) 50%, rgba(28, 32, 40, 0.10) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.52'/%3E%3C/svg%3E");
  background-size: auto, 160px 160px;
  mix-blend-mode: multiply;
  opacity: 0.6;
}
@media (prefers-reduced-motion: reduce) { .explode__viewer::after { opacity: 0.4; } }

/* 世界の写真：国名。
   ★サブコピー（.place__name「雪ふかい山里で」など）は廃止した。
   国名が温度の直下に上がったので、間は name が持っていた 6px を引き継ぐ。 */
.place__loc {
  margin: 6px 0 0;
  font-size: 0.6875rem;
  line-height: 1rem;
  letter-spacing: 0.14em;
  color: var(--text-3);
}


/* ── アプリ節：左＝説明とストアカード、右＝端末（プレビュー画面のみ）。
   ★12カラムの位置指定だと端末が右カラムの中で左に寄って見える（本人指摘）。
     ここは素直に「半分に割って、それぞれの真ん中に置く」。 */
.app-cols.grid { grid-template-columns: 1fr 1fr; }
/* ★高さは左に合わせる：面の上端＝見出しの上、下端＝ストアカードの下。
   stretch で行の高さ（＝左カラムの高さ）に面を張り、端末はその中で伸縮する。 */
.app-cols { align-items: stretch; }
.app-cols__left {
  /* ★start。center だと列幅(1440px で 610px)より中身の上限(592px)が小さいとき、
     余った 18px が左右に 9px ずつ配られ、この節の見出しと本文だけが
     他の全節より 9px 右にいた（実測：1440で67 vs 58、1920/2560で70 vs 64、
     1200では列が592px以下になるので一致）。
     右カラムの端末は .app-cols__right が別に中央へ置いている。 */
  justify-self: start;
  width: 100%;
  /* ★560px では足りない。この節の .lede は font-size が 15→16px の clamp で
     育つのに列が固定なので、行あたりの字数が 36→35 に減り、本人指定の2行目
     （36字）が 1366px 以上で入らず4行に折れていた（実測：必要576px／列560px）。
     16px×36字＝576px を収める 592px にする。 */
  /* ★上限を置かない。592px で止めていたとき、右の面が列いっぱいの 610px
     なのに左だけ 592px になり、列の間が本来の 24px ではなく 42px に見えていた。
     列いっぱいにして左右を対称にする。 */
}
.app-cols__right { justify-self: stretch; }
/* 端末を載せる面。ストアカードと同じ地（fill/角丸/線）で揃える */
.app-cols__panel {
  /* ★親（右カラム）は flex で中央寄せしているので、面自身が width を
     持たないと端末の幅まで縮む。カラム全幅に広げる。 */
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: clamp(14px, 1.8vw, 28px);
  padding: clamp(24px, 3vw, 40px);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  background: var(--fill);
  container-type: size;
}
.app-cols__panel .device {
  height: 100%;
  box-sizing: border-box;
  /* ★黒枠は実機どおり細く。iPhone 15 Pro のベゼルは 1.55mm、
     画面実寸は幅 65.1mm（1179px / 460ppi）＝ 画面幅の 2.4%。
     以前の 10px は画面幅 174px に対して 5.7% で倍以上太かった（本人指摘）。
     枠 p は容器の高さから逆算：p = 0.0101 × 高さ（画面比 393:908 を解いた値）。
     角丸も同心を保つよう p の 0.72 倍を足す。 */
  padding: calc(1.01cqh);
  border-radius: calc(14% + 0.727cqh) / calc(6.06% + 0.727cqh);
}
/* ★height はここでは 100%。.device が box-sizing:border-box なので
   子の 100% は既にベゼル(padding 10px×2)を除いた内寸を指す。
   calc(100% - 20px) にすると 20px 二重に引かれ、その余りが
   端末の下に「黒い帯」として残っていた（本人指摘）。 */
.app-cols__panel .device__screen { height: 100%; }
/* 検索画面のスクショは地色がわずかに明るい（実測 rgb(233,237,242)）。
   ダイナミックアイランド周りの帯に出るので、その色に合わせる。 */
.device--sub .device__screen { background: #e9edf2; }
/* 2台目（地点検索）は一段小さく、少し下げて奥に置く */
.app-cols__panel .device--sub {
  height: 86%;
  padding: calc(0.87cqh);
  border-radius: calc(14% + 0.625cqh) / calc(6.06% + 0.625cqh);
  align-self: flex-end;
  margin-bottom: 3%;
  opacity: 0.96;
}
/* ★max-width は置かない。左カラムいっぱいに使う。
   本人指定の2行目「天気を手で作って色を試すシミュレーション、過去の推移を見る
   プレイバック、」は36字＝16px で 576px 必要。列は 610px あるので収まる。 */
.app-cols__left .lede { margin-top: var(--s2); }
/* ★本文からこの節の主役までの間隔。--s3(24px) だと光学（墨から墨）で 38px、
   同じ関係が世界の空気・ペアではどちらも 62px だった（実測）。--s5 に上げて揃える。 */
.app-cols__left .store { margin-top: var(--s5); }
.app-cols__right {
  display: flex;
  justify-content: center;
}
/* 半分の幅に収めるストアカード：バッジ列を下段へ回す */
.store--stack {
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "icon meta"
    "badges badges";
}
.store--stack .store__icon { width: clamp(80px, 7vw, 104px); }
.store--stack .store__badges {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  padding-left: 0;
  border-left: none;
  margin-top: 4px;
}
.store--stack .store__note { flex-basis: 100%; max-width: none; }

/* ★短い注記の最終行が1語だけ落ちていた。実測：
   .store__note 和文 1024px で最終行「けます。」＝前行の12%、
   欧文 375〜414px で "the lamp." ＝17%、.temp-ui__note 欧文 375px で "visible." ＝14%。
   pretty は最終行だけを見る指定で、2行しかない塊では動かせる余地がない。
   balance は行の長さを均すので、2〜3行の注記にはこちらが効く。
   1行に収まるときは何もしないので、収まる幅で無駄に2行にはならない。
   （balance 非対応のブラウザでは従来どおりの折り返しに戻るだけ） */
/* ★balance は「切ってはいけない空き」を尊重しない。Chromium・WebKit とも、
   U+00A0 でも <span style="white-space:nowrap"> でも構わず改行した（実測）。
   欧文は語のまとまりを U+00A0 で守っているが、幅が詰まって行数が増えると
   balance が勝つ（.cta__note は 320〜360px の3行のときだけ
   「14-day / returns」に割れる）。
   ★それでも balance を外さないこと。pretty に落とすと最終行が
   前行の 20〜30% の切れ端になる（balance では 76〜100%）。
   「稀な幅で語が割れる」より「常に切れ端が出る」ほうが悪い。 */
.store__note,
.temp-ui__note,
.cta__note { text-wrap: balance; }
/* ★ただし balance は明示的な <br> がある塊では働かない。
   .temp-ui__note は1文ずつ改行しているので、幅が足りるうちはその改行を保ち、
   スマホでは改行をやめて balance に任せる（欧文は <br> の前に半角空きを
   入れてあるので、改行を消しても "temperature.The" とはくっつかない）。 */
.br-wide { display: inline; }
@media (max-width: 576px) { .br-wide { display: none; } }
/* ★仕様の値もスマホでは 2 行になり、「…で算出」の「算出」だけが
   前行の 10% の長さで落ちていた（390px 実測）。2行までの短い塊なので
   balance で行を均す。1行に収まる幅では何もしない。 */
.spec dd { text-wrap: balance; }
@media (max-width: 992px) {
  /* 狭い幅は縦積み。左の高さに合わせる根拠がなくなるので固定寸へ */
  /* ★縦積みになると、列のガター（16px）がそのまま縦の間隔として使われ、
     ストアカードと端末の面という2つの大きな塊が 16px しか離れていなかった。
     ガターは横方向の指標なので、縦にはこの節の他の間隔（--s5）を使う。 */
  .app-cols.grid { grid-template-columns: 1fr; row-gap: var(--s5); }
  /* ★container-type:size は「この要素の大きさは中身に依存しない」という宣言。
     縦積みで height:auto にすると高さが 0 に潰れ（実測：面の高さ50px）、
     端末がそこからはみ出して上のストアカードに重なっていた。
     768〜992px の全域で起きていたので、縦積みではコンテナ指定ごと外す。 */
  /* ★縦積みでは、説明とストアカードの列（max-width 560px・中央寄せ）に対して
     端末の面だけが全幅に広がり、左端も 70〜180px ずれていた（640〜992px で発生）。
     同じ幅・同じ中心に揃える。 */
  .app-cols__right { justify-self: center; width: 100%; max-width: 560px; }
  .app-cols__panel { container-type: normal; height: auto; }
  /* ★ベゼルは実機比で持つ。ここで固定 10px に戻していたため、
     デスクトップ 2.38%（実機どおり）に対してスマホだけ 5.95% と
     2.5倍太かった（390px 実測：枠188 / 画面168）。
     コンテナ単位は使えない（size は高さを封じ、inline-size はパネル幅基準に
     なるので、端末がパネルより小さい 768px で逆に太った＝実測 6.27%）。
     端末の幅は「画面の高さ × 393/908」で決まるので、そこから直に出す。
       枠 = 画面幅 × 0.024 = 画面高 × 393/908 × 0.024 = 画面高 × 0.0104 */
  .app-cols__panel .device {
    height: auto;
    padding: calc(min(46svh, 430px) * 0.0104);
    border-radius: calc(14% + min(46svh, 430px) * 0.0075)
                 / calc(6.06% + min(46svh, 430px) * 0.0075);
  }
  .app-cols__panel .device__screen { height: min(46svh, 430px); }
  /* 狭い幅は1台だけに絞る */
  .app-cols__panel .device--sub { display: none; }
}
/* ★タブレットの帯では2台目を戻す。1台だけだと面560pxに対し端末が195px＝
   幅の35%しか占めず、面の65%が空いていた（実測 769〜992px）。
   2台なら 195＋168＋隙間15＋面の内余白80 ＝ 458px で 560px に収まる。
   ★ここで寸法を与え直すのは、上のブロックが container-type を normal に
   しているため cqh が死んでいるから。素の .device--sub は 0.87cqh で
   ベゼルを持っており、この帯では解決できない。
   画面高は主端末の86%、ベゼルと角丸はその比で出す（実機比 0.024 を保つ）。 */
@media (min-width: 641px) and (max-width: 992px) {
  .app-cols__panel .device--sub { display: block; }
  .app-cols__panel .device--sub .device__screen { height: calc(min(46svh, 430px) * 0.86); }
  .app-cols__panel .device--sub {
    padding: calc(min(46svh, 430px) * 0.86 * 0.0104);
    border-radius: calc(14% + min(46svh, 430px) * 0.86 * 0.0075)
                 / calc(6.06% + min(46svh, 430px) * 0.86 * 0.0075);
  }
}

/* ────────────────────────────────────────────────
   印刷
   ★実測（A4・修正前）：18ページ・10MB。position:fixed のヘッダーと
   「本文へスキップ」のピルが全18ページに刷り込まれ、ピン留めの節
   （--pin-len で4〜7画面ぶんの高さを持つ）が白紙ページを量産していた。
   紙に「読める1本の文書」を出すのが目的なので、画面のための仕掛け
   （固定・スティッキー・スナップ・出現アニメ）を全部たたむ。
   ──────────────────────────────────────────────── */
@media print {
  /* ① 画面に貼り付く物は紙では全ページに複写されるだけ。落とす。 */
  .header,
  .header__marker,
  .skip-link,
  .pin__snaps,
  .snap__end { display: none !important; }

  /* ② スクロールで出す仕掛けは紙では動かない。最初から出しておく。 */
  .reveal,
  [data-stagger] > * {
    opacity: 1 !important;
    transform: none !important;
  }
  html {
    scroll-snap-type: none !important;
    scroll-behavior: auto !important;
  }

  /* ③ ピン留めの節は「N画面ぶんの高さ＋sticky」で出来ている。
     紙ではその高さがそのまま白紙になるので、1面ぶんに畳む。
     ★stage の高さは残すこと。中身（.temp-shots など）は
     position:absolute; inset:0 なので、height:auto にすると潰れる。 */
  .pin { height: auto !important; }
  .pin__stage {
    position: static !important;
    height: 170mm !important;
    overflow: hidden !important;
    break-inside: avoid;
  }

  /* ④ 意味のまとまりはページの境目で割らない。 */
  .spec dl > div,
  .store,
  .pair__room,
  .cta,
  .footer__nav > div { break-inside: avoid; }

  /* ⑤ 世界の写真は2周ぶん並んでいる（横に流すための複製）。紙では1周でよい。 */
  .world__strip .place[aria-hidden="true"] { display: none !important; }

  /* ⑥ 3D は紙では描かれない（WebGL の canvas は空のまま）。
     画面では常に透過にしてある静止画を、紙のときだけ出す。
     これが無いと構造の面がただの灰色の箱になる（実測）。 */
  .explode__fallback { opacity: 1 !important; }

  /* ⑦ 端末のモックはページの境目でちょうど割れていた（実測：6→7ページ）。 */
  .app-cols__panel,
  .device { break-inside: avoid; }

  /* ⑧ 紙に時間軸は無い。遷移が残っていると、印刷の瞬間の途中の値
     （実測：静止画の opacity が 0.0005）がそのまま焼き付く。 */
  *, *::before, *::after {
    transition: none !important;
    animation: none !important;
  }
}
