/* ============================================================
   夢のプロポーズ ｜ オープニング演出（index.php 専用）
   ベルベットの指輪ケースがひらき、収まったままのダイヤが放つ光からページが現れる。

   構造は okaeshi.innovativeai.jp の暖簾と同じ4段:
     ① 描画前に html.opshut を付け、全画面オーバーレイ＋スクロール錠
     ② 本編は普通に描画済み（JSが死んでも読める。伏せている op-hold は
        必ず opacity:1 で終わるので自己修復する）
     ③ html.op-open で純CSSキーフレームが走る（JSはクラスを付け替えるだけ）
     ④ animationend ＋ タイマー保険の二段構えでオーバーレイをDOMごと撤去

   reduced-motion / JS無効 / アンカー付き来訪では最初から出さない。

   ★動きの方針: 指輪は跳ね上げない。ケースに収まったまま、カメラが寄る
     （箱ごと大きくなり、傾きが深くなって中がよく見える）。跳ねる動きは
     安っぽく見えるため、ジュエリー映像の作法に合わせて「寄り」と「光」で見せる。

   箱の寸法（px・.op-scale の scale() でまとめて縮尺する）
     幅 W=200 / 奥行 D=166 / 台座 HB=70 / 蓋 HL=88
     蓋の甲は丸みのあるドーム（腰 34px ＋ 半楕円の甲 54px を帯8枚で近似）
     蓋の蝶番は台座の背面上辺 = 箱座標 (0, -35, -83)
     蓋は rotateX(+98deg) で開く（＋方向でないと机側へ沈む）
     クッションは開口より 2px 落とす（辺が一致すると縁がチカチカする）

   ★3D（preserve-3d）の中では filter: を使わないこと。Chrome がレイヤーを
     平面化して、要素の外形どおりでない矩形のにじみが出る。光はすべて
     3D の外の 2D レイヤー（.op-halo / .op-core / .op-rays）が持つ。
   ============================================================ */

/* ---------- オーバーレイの器 ---------- */
.op{
  display:none;position:fixed;inset:0;z-index:300;overflow:hidden;
  place-items:center;

  /* ベルベットの起毛（グレースケールのノイズ。soft-light で地色に織り込む） */
  --vn:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  /* 蓋に箔押しする紋（本編のヘッダーと同じダイヤのマーク） */
  --crest:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cg stroke='%23d9b978' fill='none' stroke-width='3.4' stroke-linejoin='round'%3E%3Cpath d='M18 38 L50 10 L82 38 L50 94 Z'/%3E%3Cpath d='M18 38 H82'/%3E%3Cpath d='M34 38 L50 94 M66 38 L50 94'/%3E%3Cpath d='M50 10 L34 38 M50 10 L66 38'/%3E%3C/g%3E%3C/svg%3E");

  /* 本編の .night と同じ夜空。撤去した瞬間に背景が変わらないようにする */
  background:
    radial-gradient(1200px 700px at 78% -6%, rgba(58,111,208,.20), transparent 60%),
    radial-gradient(900px 600px at 12% 8%, rgba(198,161,91,.12), transparent 55%),
    linear-gradient(180deg,#070b14 0%, #0a0e18 34%, #0b101c 100%);
}
html.opshut .op,html.op-open .op{display:grid}
html.opshut,html.opshut body{
  overflow:hidden;height:100%;touch-action:none;overscroll-behavior:none;
}
html.op-open .op{pointer-events:none}

/* 星（本編の canvas は隠れるので、同じ密度感をタイルで再現する）＋中央のほのかな灯り */
.op::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:
    radial-gradient(1.6px 1.6px at 20% 28%, rgba(236,211,154,.9), transparent 100%),
    radial-gradient(1.2px 1.2px at 72% 62%, rgba(245,239,227,.75), transparent 100%),
    radial-gradient(1px 1px at 44% 84%, rgba(245,239,227,.55), transparent 100%),
    radial-gradient(1.4px 1.4px at 87% 14%, rgba(236,211,154,.6), transparent 100%),
    radial-gradient(72% 60% at 50% 42%, rgba(198,161,91,.11), transparent 64%);
  background-size:330px 290px,255px 235px,195px 185px,425px 375px,100% 100%;
  background-repeat:repeat,repeat,repeat,repeat,no-repeat;
  animation:op-twinkle 6.5s ease-in-out infinite;
}
@keyframes op-twinkle{0%,100%{opacity:.62}50%{opacity:1}}

.op-inner{position:relative;display:flex;flex-direction:column;align-items:center}

/* ---------- 前後の文字 ---------- */
.op-eyebrow{
  margin:0 0 clamp(10px,2.4vh,26px);
  font-family:var(--latin);font-weight:600;font-size:.84rem;
  letter-spacing:.62em;text-indent:.62em;text-transform:uppercase;
  color:rgba(236,211,154,.75);
  animation:op-fadein 1.4s var(--ease) .25s both;
}
.op-hint{
  margin:clamp(12px,2.6vh,30px) 0 0;
  font-family:var(--serif);font-size:.82rem;
  letter-spacing:.36em;text-indent:.36em;color:rgba(183,173,153,.85);
  animation:op-fadein 1.2s var(--ease) 1.2s both;
}
.op-hint::before,.op-hint::after{
  content:"";display:inline-block;width:22px;height:1px;vertical-align:middle;
  background:linear-gradient(90deg,transparent,rgba(198,161,91,.7));
  margin:0 14px 3px 0;
}
.op-hint::after{margin:0 0 3px 14px;transform:scaleX(-1)}
@keyframes op-fadein{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes op-dissolve{to{opacity:0;transform:translateY(-6px)}}
html.op-open .op-eyebrow{animation:op-dissolve .6s var(--ease) both}
html.op-open .op-hint{animation:op-dissolve .4s var(--ease) both}

/* ---------- 縮尺（画面サイズに応じて箱ごと縮める） ---------- */
.op-scale{
  --bs:1.42;
  position:relative;width:330px;height:400px;
  transform:scale(var(--bs));transform-origin:50% 50%;
}
/* 幅 → 高さ の順に書き、狭いほうの制約が後勝ちで効くようにする */
@media (max-width:1100px){.op-scale{--bs:1.2}}
@media (max-width:900px){.op-scale{--bs:1.02}}
@media (max-width:640px){.op-scale{--bs:.86}}
@media (max-width:420px){.op-scale{--bs:.7}}
@media (max-height:820px){.op-scale{--bs:1.1}}
@media (max-height:700px){.op-scale{--bs:.92}}
@media (max-height:600px){.op-scale{--bs:.72}}
@media (max-height:500px){.op-scale{--bs:.56}}

/* ---------- 3Dの舞台 ---------- */
.op-scene{position:absolute;inset:0;perspective:1250px;perspective-origin:50% 56%}
.op-box{
  position:absolute;left:50%;top:64%;width:200px;height:70px;
  transform-style:preserve-3d;
  transform:translate(-50%,-50%) rotateX(-15deg) rotateY(-8deg);
  animation:op-float 7s ease-in-out infinite;
}
/* 待機中のごく浅い呼吸。transform を上書きするので全成分を書く */
@keyframes op-float{
  0%,100%{transform:translate(-50%,-50%) translateY(-3px) rotateX(-15deg) rotateY(-8deg)}
  50%    {transform:translate(-50%,-50%) translateY(3px)  rotateX(-13.5deg) rotateY(-5.5deg)}
}
/* 開幕＝カメラの寄り。跳ねさせず、ひと呼吸置いてから静かに近づき、
   傾きを深めて中を見せる。行き過ぎ（オーバーシュート）は入れない */
html.op-open .op-box{animation:op-present 2.1s cubic-bezier(.3,.02,.16,1) both}
@keyframes op-present{
  0%  {transform:translate(-50%,-50%) rotateX(-15deg) rotateY(-8deg) scale(1)}
  8%  {transform:translate(-50%,-50%) translateY(2px) rotateX(-13.5deg) rotateY(-8deg) scale(1)}
  55% {transform:translate(-50%,-50%) translateY(-4px) translateZ(48px) rotateX(-24deg) rotateY(-4deg) scale(1.09)}
  100%{transform:translate(-50%,-50%) translateY(-9px) translateZ(96px) rotateX(-31deg) rotateY(0deg) scale(1.2)}
}
/* 接地感。箱は浮いたままだが、下に落ちる光の溜まりで空間に置く */
.op-shadow{
  position:absolute;left:50%;top:80%;width:300px;height:74px;
  margin:-37px 0 0 -150px;border-radius:50%;pointer-events:none;z-index:0;
  background:radial-gradient(circle, rgba(198,161,91,.3) 0%, rgba(120,96,150,.14) 42%, transparent 72%);
  filter:blur(13px);
}
html.op-open .op-shadow{animation:op-shadow 2.1s var(--ease) both}
@keyframes op-shadow{
  0%{opacity:1;transform:scale(1)}
  55%{opacity:.6;transform:scale(1.22)}
  100%{opacity:0;transform:scale(1.55)}
}

/* ★ここで border-radius を指定しないこと。詳細度が (0,2,0) で高く、
   側面の D 字形（.ll/.lr の border-radius）を打ち消してしまう。
   角丸が要る面には、その面のルールで個別に指定する */
.op-box .f,.op-lid .f{position:absolute;left:50%;top:50%;display:block}
.bf,.bl,.br{border-radius:1px}
.bt{border-radius:11px}

/* ---------- ベルベットの外装 ----------
   起毛は「広くやわらかい照り」と「細かい繊維」でできている。
   革のような鋭いハイライトを入れると途端に安っぽくなるので入れない。 */
.bf,.bl,.br{
  background-size:140px 140px,100% 100%,100% 100%,100% 100%;
  background-blend-mode:soft-light,screen,multiply,normal;
}
.bf{
  width:178px;height:70px;transform:translate(-50%,-50%) translateZ(83px);
  background-image:
    var(--vn),
    radial-gradient(160% 200% at 24% -34%, rgba(158,178,238,.32), rgba(158,178,238,0) 58%),
    radial-gradient(130% 170% at 50% 132%, rgba(0,0,0,.6), rgba(0,0,0,0) 62%),
    linear-gradient(180deg,#27365f 0%,#1b2545 46%,#0e1428 100%);
  box-shadow:
    inset 0 1px 0 rgba(236,211,154,.32),
    inset 0 0 0 1px rgba(0,0,0,.3),
    inset 0 -14px 20px -13px rgba(0,0,0,.72);
}
.bl,.br{
  width:155px;height:70px;
  background-image:
    var(--vn),
    radial-gradient(160% 200% at 30% -30%, rgba(140,160,220,.2), rgba(140,160,220,0) 56%),
    radial-gradient(130% 170% at 50% 132%, rgba(0,0,0,.66), rgba(0,0,0,0) 60%),
    linear-gradient(180deg,#1d2949 0%,#141c37 46%,#090e1e 100%);
  box-shadow:inset 0 1px 0 rgba(236,211,154,.16),inset 0 0 0 1px rgba(0,0,0,.3);
}
.bl{transform:translate(-50%,-50%) translate3d(-100px,0,-5.5px) rotateY(-90deg)}
.br{transform:translate(-50%,-50%) translate3d(100px,0,-5.5px) rotateY(90deg)}
/* 台座の縦の角の面取り（正面と側面を 45° でつなぐ） */
.bcf{
  width:16px;height:70px;
  background-image:var(--vn),linear-gradient(180deg,#212d4e 0%,#161e3a 46%,#0b1122 100%);
  background-size:140px 140px,100% 100%;background-blend-mode:soft-light,normal;
  box-shadow:inset 0 1px 0 rgba(236,211,154,.22);
}
.bcfr{transform:translate(-50%,-50%) translate3d(96.78px,0,79.78px) rotateY(45deg)}
.bcfl{transform:translate(-50%,-50%) translate3d(-96.78px,0,79.78px) rotateY(-45deg)}

/* 台座の開口＝シャンパン色のベルベットクッション。中央のくぼみが指輪のスリット */
/* ★台座の底＝黒に近いベルベット。指輪を受けるのは、この上に立てる
   アイボリーのサテンの羽根（.wingl/.wingr）。参考写真の EXELCO の箱と同じ作り。
   開口の縁より 2px 落として置くのは、台座の壁の上端と高さが完全に一致すると
   辺が重なって、箱が回るあいだ縁がチカチカするため（Zファイティング） */
.bt{
  width:200px;height:166px;
  transform:translate(-50%,-50%) translate3d(0,-33px,0) rotateX(90deg);
  background-image:
    var(--vn),
    radial-gradient(130% 120% at 50% 22%, rgba(140,160,215,.16), rgba(140,160,215,0) 62%),
    linear-gradient(180deg,#111930 0%,#0d1424 50%,#0a0f1d 100%);
  background-size:140px 140px,100% 100%,100% 100%;
  background-blend-mode:soft-light,screen,normal;
  box-shadow:
    inset 0 0 0 3px #0a0f1c,
    inset 0 0 0 4px rgba(236,211,154,.28),
    inset 0 0 26px rgba(0,0,0,.5);
}

/* ★指輪を受けるサテンの枕（参考写真 EXELCO の箱を再現）。
   左右のサテンが中央へせり上がりながら「くびれ」、真ん中に前後方向の谷を残す。
   バンドはその谷に差し込まれ、上の弧だけが見える。
   ★くびれ（蝶ネクタイ形）は clip-path では作れない。3D（preserve-3d）の中では
     Chrome が要素を平面化して、形も位置も大きさも壊れる（filter と同じ）。
     対角のグラデーションを暗色でハードストップさせて切り落とす。切り落とした
     部分は床と同じ暗色なので、黒ベルベットが見えているように読める。
   ★CSS のグラデーション角は向き d に対して atan2(dx, -dy)、ハードストップの位置は
     (L/2 + 中心の符号付き距離)/L。どちらも符号を落としやすく、間違えると
     切る側が逆になる（面が全部暗くなる／くびれが外側にできる）。
   ★片側を帯に分割しないこと。継ぎ目と帯ごとの照りで扇（プリーツ）に見える。
   数値は scratchpad の生成スクリプトが算出（せり上がり 8.5° / くびれ 78）。 */
.wg{width:88.0px;height:166.0px}
.wgl{transform:translate(-50%,-50%) translate3d(-56.5px,-39.5px,0) rotateX(90deg) rotateY(8.5deg);background-image:linear-gradient(206.57deg, #0d1424 0 20.95%, transparent 20.95%),linear-gradient(333.43deg, #0d1424 0 20.95%, transparent 20.95%),linear-gradient(90deg, #aba495 0%, #b4ad9f 10%, #c3beb1 20%, #dad6cd 30%, #f3f1ec 40%, #fffefa 50%, #fffefa 60%, #fffefa 70%, #e9e7e0 80%, #d0ccc1 90%, #bcb6a9 100%)}
.wgr{transform:translate(-50%,-50%) translate3d(56.5px,-39.5px,0) rotateX(90deg) rotateY(-8.5deg);background-image:linear-gradient(153.43deg, #0d1424 0 20.95%, transparent 20.95%),linear-gradient(26.57deg, #0d1424 0 20.95%, transparent 20.95%),linear-gradient(90deg, #bcb6a9 0%, #d0ccc1 10%, #e9e7e0 20%, #fffefa 30%, #fffefa 40%, #fffefa 50%, #f3f1ec 60%, #dad6cd 70%, #c3beb1 80%, #b4ad9f 90%, #aba495 100%)}

/* ★クッション奥の立ち上がり。蓋が開くと、蝶番のあたりに「台座の縁と蓋の内貼りの
   どちらにも属さない隙間」ができて背景の黒が帯状に覗く（要素を1枚ずつ消して確認済み。
   何を消しても暗くなる＝実際に何も無い）。ここを塞ぐと石の背景がクリームになって
   ダイヤが読みやすくなる。閉じているときは蓋の内側なので見えない */
.bback{
  width:178px;height:20px;
  transform:translate(-50%,-50%) translate3d(0,-43px,-83px);
  background-image:
    var(--vn),
    linear-gradient(180deg,#182135 0%,#0e1525 60%,#070b14 100%);
  background-size:140px 140px,100% 100%;
  background-blend-mode:soft-light,normal;
  box-shadow:inset 0 -6px 10px -6px rgba(0,0,0,.5);
}
/* 蓋との合わせ目からもれる光。3D の中なので blur() は使わず、
   縦方向のグラデーションでにじみを作る */
.seam{
  width:176px;height:7px;border-radius:4px;
  transform:translate(-50%,-50%) translate3d(0,-36px,86px);
  background:
    linear-gradient(180deg,transparent,rgba(255,247,225,.5) 34%,#fffaf0 50%,rgba(255,247,225,.5) 66%,transparent),
    linear-gradient(90deg,transparent,rgba(255,244,214,.9) 24%,rgba(255,250,240,1) 50%,rgba(255,244,214,.9) 76%,transparent);
  background-blend-mode:multiply;
  opacity:0;
}
html.op-open .seam{animation:op-seam 1s ease .12s both}
@keyframes op-seam{0%{opacity:0}26%{opacity:1}100%{opacity:0}}

/* ---------- 蓋（蝶番は背面上辺・甲は丸いドーム・左右の稜線も面取り） ---------- */
.op-lid{
  position:absolute;left:50%;top:50%;width:200px;height:88px;
  transform-style:preserve-3d;
  transform:translate(-50%,-50%) translate3d(0,-35px,-83px) rotateX(0deg);
}
/* ゆっくり開く。蝶番の重さを出すため、頭に小さなためだけ置いて跳ね返しはしない。
   開き切りを 98° に留めるのは、寝かせすぎると蓋と台座のあいだに
   背景が透けて黒い帯ができるため（実測で 105° は帯が目立った） */
html.op-open .op-lid{animation:op-lift 1.5s cubic-bezier(.36,.06,.18,1) .18s both}
@keyframes op-lift{
  0%  {transform:translate(-50%,-50%) translate3d(0,-35px,-83px) rotateX(0deg)}
  9%  {transform:translate(-50%,-50%) translate3d(0,-35px,-83px) rotateX(-2.5deg)}
  78% {transform:translate(-50%,-50%) translate3d(0,-35px,-83px) rotateX(101deg)}
  100%{transform:translate(-50%,-50%) translate3d(0,-35px,-83px) rotateX(98deg)}
}

/* 腰（下 34px の立ち上がり）。芯の幅は 178px＝200-2r で、左右 11px は面取りに使う */
.lf,.lbk{
  width:178px;height:34px;backface-visibility:hidden;
  background-image:
    var(--vn),
    radial-gradient(150% 300% at 28% -80%, rgba(166,186,244,.3), rgba(166,186,244,0) 62%),
    linear-gradient(180deg,#26355b 0%,#19223f 58%,#0e1428 100%);
  background-size:140px 140px,100% 100%,100% 100%;
  background-blend-mode:soft-light,screen,normal;
  box-shadow:inset 0 -1px 0 rgba(236,211,154,.3), inset 0 0 0 1px rgba(0,0,0,.28);
}
.lf{transform:translate(-50%,-50%) translate3d(0,-17px,166px)}
.lbk{transform:translate(-50%,-50%) translate3d(0,-17px,0) rotateY(180deg)}
/* 蓋の正面に紋を箔押しする（正対する面なので読める） */
.lf::before{
  content:"";position:absolute;inset:0;
  background:var(--crest) center/22px 22px no-repeat;opacity:.6;
}
/* 腰の縦の角の面取り（正面と側面を 45° でつなぐ） */
.lcf{
  width:15.9px;height:34px;backface-visibility:hidden;
  background-image:var(--vn),linear-gradient(180deg,#202c4d 0%,#161e3a 58%,#0c1224 100%);
  background-size:140px 140px,100% 100%;background-blend-mode:soft-light,normal;
}
.lcfr{transform:translate(-50%,-50%) translate3d(94.5px,-17px,160.5px) rotateY(45deg)}
.lcfl{transform:translate(-50%,-50%) translate3d(-94.5px,-17px,160.5px) rotateY(-45deg)}
/* 側面。外形は「蓋の断面を内側へ 11px オフセットした形」で、面取りの端と一致する */
.ll,.lr{
  width:144px;height:77px;border-radius:72px 72px 0 0 / 43px 43px 0 0;
  background-image:
    var(--vn),
    radial-gradient(140% 160% at 34% 6%, rgba(150,170,230,.24), rgba(150,170,230,0) 58%),
    linear-gradient(180deg,#26335a 0%,#182042 54%,#0b1122 100%);
  background-size:140px 140px,100% 100%,100% 100%;
  background-blend-mode:soft-light,screen,normal;
}
.ll{transform:translate(-50%,-50%) translate3d(-100px,-38.5px,83px) rotateY(-90deg)}
.lr{transform:translate(-50%,-50%) translate3d(100px,-38.5px,83px) rotateY(90deg)}

/* ---------- 甲（ドーム）: 楕円断面を9枚の帯で近似し、左右の稜線を半径11で面取り ----------
   帯の両端の法線から明るさを出し、グラデーションの始点・終点に使っている。
   こうすると隣の帯と色が連続するので、平面の集まりでも段差に見えない。
   .lc* は帯の両端に立てた 45° のフィレット面で、甲と側面を滑らかにつなぐ。
   数値は scratchpad/gen_dome.py が算出（D=166 / 腰34 / 甲54 / 角半径11）。 */
.ls,.lsi,.lc,.lci{border-radius:0;background-size:140px 140px,100% 100%;background-blend-mode:soft-light,normal}
.ls{width:178px}
.lsi{width:170px}
.lc,.lci{width:16.0px}
.ls0{height:19.9px;transform:translate(-50%,-50%) translate3d(0,-43.4px,1.3px) rotateX(164.8deg);background-image:var(--vn),linear-gradient(180deg,#10172d,#131b33)}
.lc0r{height:19.9px;transform:translate(-50%,-50%) translate3d(94.50px,-41.9px,6.6px) rotateX(164.8deg) rotateY(45deg);background-image:var(--vn),linear-gradient(180deg,#10172d,#121931)}
.lc0l{height:19.9px;transform:translate(-50%,-50%) translate3d(-94.50px,-41.9px,6.6px) rotateX(164.8deg) rotateY(-45deg);background-image:var(--vn),linear-gradient(180deg,#10172d,#121931)}
.lsi0{height:18.6px;transform:translate(-50%,-50%) translate3d(0,-42.7px,5.2px) rotateX(164.8deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#11182b,#12192d)}
.lci0r{height:18.6px;transform:translate(-50%,-50%) translate3d(91.67px,-41.2px,9.3px) rotateX(164.8deg) rotateY(45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#11182b,#12192d)}
.lci0l{height:18.6px;transform:translate(-50%,-50%) translate3d(-91.67px,-41.2px,9.3px) rotateX(164.8deg) rotateY(-45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#11182b,#12192d)}
.ls1{height:22.5px;transform:translate(-50%,-50%) translate3d(0,-61.0px,11.1px) rotateX(138.4deg);background-image:var(--vn),linear-gradient(180deg,#131b33,#222f54)}
.lc1r{height:22.5px;transform:translate(-50%,-50%) translate3d(94.50px,-57.3px,15.2px) rotateX(138.4deg) rotateY(45deg);background-image:var(--vn),linear-gradient(180deg,#121931,#1b2645)}
.lc1l{height:22.5px;transform:translate(-50%,-50%) translate3d(-94.50px,-57.3px,15.2px) rotateX(138.4deg) rotateY(-45deg);background-image:var(--vn),linear-gradient(180deg,#121931,#1b2645)}
.lsi1{height:21.2px;transform:translate(-50%,-50%) translate3d(0,-59.0px,14.6px) rotateX(138.4deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#12192d,#172037)}
.lci1r{height:21.2px;transform:translate(-50%,-50%) translate3d(91.67px,-55.5px,17.3px) rotateX(138.4deg) rotateY(45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#12192d,#172037)}
.lci1l{height:21.2px;transform:translate(-50%,-50%) translate3d(-91.67px,-55.5px,17.3px) rotateX(138.4deg) rotateY(-45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#12192d,#172037)}
.ls2{height:26.0px;transform:translate(-50%,-50%) translate3d(0,-75.4px,29.6px) rotateX(118.6deg);background-image:var(--vn),linear-gradient(180deg,#222f54,#2c3c69)}
.lc2r{height:26.0px;transform:translate(-50%,-50%) translate3d(94.50px,-70.5px,32.3px) rotateX(118.6deg) rotateY(45deg);background-image:var(--vn),linear-gradient(180deg,#1b2645,#212e52)}
.lc2l{height:26.0px;transform:translate(-50%,-50%) translate3d(-94.50px,-70.5px,32.3px) rotateX(118.6deg) rotateY(-45deg);background-image:var(--vn),linear-gradient(180deg,#1b2645,#212e52)}
.lsi2{height:24.6px;transform:translate(-50%,-50%) translate3d(0,-72.3px,32.2px) rotateX(118.6deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#172037,#1b253e)}
.lci2r{height:24.6px;transform:translate(-50%,-50%) translate3d(91.67px,-68.1px,33.6px) rotateX(118.6deg) rotateY(45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#172037,#1b253e)}
.lci2l{height:24.6px;transform:translate(-50%,-50%) translate3d(-91.67px,-68.1px,33.6px) rotateX(118.6deg) rotateY(-45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#172037,#1b253e)}
.ls3{height:28.6px;transform:translate(-50%,-50%) translate3d(0,-84.7px,54.6px) rotateX(103.3deg);background-image:var(--vn),linear-gradient(180deg,#2c3c69,#324476)}
.lc3r{height:28.6px;transform:translate(-50%,-50%) translate3d(94.50px,-79.4px,55.9px) rotateX(103.3deg) rotateY(45deg);background-image:var(--vn),linear-gradient(180deg,#212e52,#25335a)}
.lc3l{height:28.6px;transform:translate(-50%,-50%) translate3d(-94.50px,-79.4px,55.9px) rotateX(103.3deg) rotateY(-45deg);background-image:var(--vn),linear-gradient(180deg,#212e52,#25335a)}
.lsi3{height:27.3px;transform:translate(-50%,-50%) translate3d(0,-81.0px,56.0px) rotateX(103.3deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1b253e,#1d2743)}
.lci3r{height:27.3px;transform:translate(-50%,-50%) translate3d(91.67px,-76.6px,56.5px) rotateX(103.3deg) rotateY(45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1b253e,#1d2743)}
.lci3l{height:27.3px;transform:translate(-50%,-50%) translate3d(-91.67px,-76.6px,56.5px) rotateX(103.3deg) rotateY(-45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1b253e,#1d2743)}
.ls4{height:29.6px;transform:translate(-50%,-50%) translate3d(0,-88.0px,83.0px) rotateX(90.0deg);background-image:var(--vn),linear-gradient(180deg,#324476,#36497e)}
.lc4r{height:29.6px;transform:translate(-50%,-50%) translate3d(94.50px,-82.5px,83.0px) rotateX(90.0deg) rotateY(45deg);background-image:var(--vn),linear-gradient(180deg,#25335a,#283660)}
.lc4l{height:29.6px;transform:translate(-50%,-50%) translate3d(-94.50px,-82.5px,83.0px) rotateX(90.0deg) rotateY(-45deg);background-image:var(--vn),linear-gradient(180deg,#25335a,#283660)}
.lsi4{height:28.2px;transform:translate(-50%,-50%) translate3d(0,-84.0px,83.0px) rotateX(90.0deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1d2743,#1e2946)}
.lci4r{height:28.2px;transform:translate(-50%,-50%) translate3d(91.67px,-79.7px,83.0px) rotateX(90.0deg) rotateY(45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1d2743,#1e2946)}
.lci4l{height:28.2px;transform:translate(-50%,-50%) translate3d(-91.67px,-79.7px,83.0px) rotateX(90.0deg) rotateY(-45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1d2743,#1e2946)}
.ls5{height:28.6px;transform:translate(-50%,-50%) translate3d(0,-84.7px,111.4px) rotateX(76.7deg);background-image:var(--vn),linear-gradient(180deg,#36497e,#384c83)}
.lc5r{height:28.6px;transform:translate(-50%,-50%) translate3d(94.50px,-79.4px,110.1px) rotateX(76.7deg) rotateY(45deg);background-image:var(--vn),linear-gradient(180deg,#283660,#293862)}
.lc5l{height:28.6px;transform:translate(-50%,-50%) translate3d(-94.50px,-79.4px,110.1px) rotateX(76.7deg) rotateY(-45deg);background-image:var(--vn),linear-gradient(180deg,#283660,#293862)}
.lsi5{height:27.3px;transform:translate(-50%,-50%) translate3d(0,-81.0px,110.0px) rotateX(76.7deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1e2946,#1f2a47)}
.lci5r{height:27.3px;transform:translate(-50%,-50%) translate3d(91.67px,-76.6px,109.5px) rotateX(76.7deg) rotateY(45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1e2946,#1f2a47)}
.lci5l{height:27.3px;transform:translate(-50%,-50%) translate3d(-91.67px,-76.6px,109.5px) rotateX(76.7deg) rotateY(-45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1e2946,#1f2a47)}
.ls6{height:26.0px;transform:translate(-50%,-50%) translate3d(0,-75.4px,136.4px) rotateX(61.4deg);background-image:var(--vn),linear-gradient(180deg,#384c83,#374b81)}
.lc6r{height:26.0px;transform:translate(-50%,-50%) translate3d(94.50px,-70.5px,133.7px) rotateX(61.4deg) rotateY(45deg);background-image:var(--vn),linear-gradient(180deg,#293862,#283761)}
.lc6l{height:26.0px;transform:translate(-50%,-50%) translate3d(-94.50px,-70.5px,133.7px) rotateX(61.4deg) rotateY(-45deg);background-image:var(--vn),linear-gradient(180deg,#293862,#283761)}
.lsi6{height:24.6px;transform:translate(-50%,-50%) translate3d(0,-72.3px,133.8px) rotateX(61.4deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1f2a47,#1f2a46)}
.lci6r{height:24.6px;transform:translate(-50%,-50%) translate3d(91.67px,-68.1px,132.4px) rotateX(61.4deg) rotateY(45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1f2a47,#1f2a46)}
.lci6l{height:24.6px;transform:translate(-50%,-50%) translate3d(-91.67px,-68.1px,132.4px) rotateX(61.4deg) rotateY(-45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1f2a47,#1f2a46)}
.ls7{height:22.5px;transform:translate(-50%,-50%) translate3d(0,-61.0px,154.9px) rotateX(41.6deg);background-image:var(--vn),linear-gradient(180deg,#374b81,#314273)}
.lc7r{height:22.5px;transform:translate(-50%,-50%) translate3d(94.50px,-57.3px,150.8px) rotateX(41.6deg) rotateY(45deg);background-image:var(--vn),linear-gradient(180deg,#283761,#243258)}
.lc7l{height:22.5px;transform:translate(-50%,-50%) translate3d(-94.50px,-57.3px,150.8px) rotateX(41.6deg) rotateY(-45deg);background-image:var(--vn),linear-gradient(180deg,#283761,#243258)}
.lsi7{height:21.2px;transform:translate(-50%,-50%) translate3d(0,-59.0px,151.4px) rotateX(41.6deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1f2a46,#1c2742)}
.lci7r{height:21.2px;transform:translate(-50%,-50%) translate3d(91.67px,-55.5px,148.7px) rotateX(41.6deg) rotateY(45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1f2a46,#1c2742)}
.lci7l{height:21.2px;transform:translate(-50%,-50%) translate3d(-91.67px,-55.5px,148.7px) rotateX(41.6deg) rotateY(-45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1f2a46,#1c2742)}
.ls8{height:19.9px;transform:translate(-50%,-50%) translate3d(0,-43.4px,164.7px) rotateX(15.2deg);background-image:var(--vn),linear-gradient(180deg,#314273,#212e52)}
.lc8r{height:19.9px;transform:translate(-50%,-50%) translate3d(94.50px,-41.9px,159.4px) rotateX(15.2deg) rotateY(45deg);background-image:var(--vn),linear-gradient(180deg,#243258,#1b2544)}
.lc8l{height:19.9px;transform:translate(-50%,-50%) translate3d(-94.50px,-41.9px,159.4px) rotateX(15.2deg) rotateY(-45deg);background-image:var(--vn),linear-gradient(180deg,#243258,#1b2544)}
.lsi8{height:18.6px;transform:translate(-50%,-50%) translate3d(0,-42.7px,160.8px) rotateX(15.2deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1c2742,#172037)}
.lci8r{height:18.6px;transform:translate(-50%,-50%) translate3d(91.67px,-41.2px,156.7px) rotateX(15.2deg) rotateY(45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1c2742,#172037)}
.lci8l{height:18.6px;transform:translate(-50%,-50%) translate3d(-91.67px,-41.2px,156.7px) rotateX(15.2deg) rotateY(-45deg) rotateY(180deg);background-image:var(--vn),linear-gradient(180deg,#1c2742,#172037)}

/* 蓋の内貼り（腰・面取り・側面）。外装の 4px 内側に、内向きで置く。
   1px だとほぼ同一平面になり、回転中にどちらが手前か揺れて縁がチカチカする */
.lfi,.lbki,.lcfi{
  background-image:var(--vn),linear-gradient(180deg,#131b30 0%,#080d19 100%);
  background-size:140px 140px,100% 100%;background-blend-mode:soft-light,normal;
}
.lfi,.lbki{width:170px;height:30px}
.lfi{transform:translate(-50%,-50%) translate3d(0,-17px,162px) rotateY(180deg)}
.lbki{transform:translate(-50%,-50%) translate3d(0,-17px,4px)}
.lcfi{width:15.9px;height:30px}
.lcfir{transform:translate(-50%,-50%) translate3d(91.67px,-17px,157.67px) rotateY(45deg) rotateY(180deg)}
.lcfil{transform:translate(-50%,-50%) translate3d(-91.67px,-17px,157.67px) rotateY(-45deg) rotateY(180deg)}
.lli,.lri{
  width:136px;height:73px;border-radius:68px 68px 0 0 / 40px 40px 0 0;
  background-image:
    var(--vn),
    radial-gradient(130% 140% at 50% 6%, rgba(150,170,220,.18), rgba(150,170,220,0) 62%),
    linear-gradient(180deg,#1a2440 0%,#111931 60%,#070c17 100%);
  background-size:140px 140px,100% 100%,100% 100%;
  background-blend-mode:soft-light,screen,normal;
}
.lli{transform:translate(-50%,-50%) translate3d(-96px,-36.5px,83px) rotateY(90deg)}
.lri{transform:translate(-50%,-50%) translate3d(96px,-36.5px,83px) rotateY(-90deg)}

/* ---------- 指輪（ケースに収まったまま。動かさない） ---------- */
/* 高さ -74px / 縮尺 1.0 は実測で決めた値。サテンの谷からバンドの上の弧が
   はっきり出るところで止める。これより下げるとわっかが埋まって「浮いた石」に見え、
   指輪に見えなくなる。逆に上げると宙に浮いて安っぽい。
   ★枕の高さを変えたら、この値と .op-light/.op-halo の top を必ず測り直す */
.op-ring{
  position:absolute;left:50%;top:50%;width:100px;height:132px;
  transform:translate(-50%,-50%) translate3d(0,-74px,6px) scale(1);
}
.op-ring svg{display:block;width:100%;height:100%}
/* クッションへ落ちる影。blur() は 3D の中で使わないので放射グラデーションで作る */
/* クッション面（Y=-33）より 2px 手前に置く。近すぎるとどちらが手前か揺れる */
.ringshadow{
  width:44px;height:14px;border-radius:50%;
  transform:translate(-50%,-50%) translate3d(0,-34px,6px) rotateX(90deg);
  background:radial-gradient(circle, rgba(0,0,0,.7) 0%, rgba(0,0,0,.34) 44%, transparent 74%);
}
/* 石まわりの空気。SVG内の楕円を膨らませるだけで、外側の光は .op-halo/.op-core が受け持つ */
.op-ring .op-air{transform-box:fill-box;transform-origin:50% 50%;opacity:.32}
html.op-open .op-ring .op-air{animation:op-air 1.8s ease .7s both}
@keyframes op-air{
  0%  {opacity:.3;transform:scale(.8)}
  55% {opacity:.9;transform:scale(1.25)}
  100%{opacity:1;transform:scale(1.7)}
}
/* 石そのものの照り。指輪を動かさない代わりに、面が順に灯るように見せる */
.op-ring .op-spark{transform-box:fill-box;transform-origin:50% 50%;opacity:0}
html.op-open .op-ring .op-spark{animation:op-spark 1.5s ease-in-out .78s both}
@keyframes op-spark{
  0%{opacity:0}35%{opacity:.85}70%{opacity:.5}100%{opacity:1}
}

/* ---------- 光 ---------- */
/* 指輪の背後の逆光（3Dの外・2Dレイヤー） */
.op-halo{
  position:absolute;left:49.7%;top:40.85%;width:460px;height:460px;margin:-230px 0 0 -230px;
  border-radius:50%;pointer-events:none;z-index:0;opacity:0;
  background:radial-gradient(circle, rgba(236,211,154,.55) 0%, rgba(216,167,161,.24) 28%, transparent 66%);
  filter:blur(16px);
}
html.op-open .op-halo{animation:op-halo 1.9s var(--ease) .8s both}
@keyframes op-halo{
  0%{opacity:0;transform:scale(.25)}
  50%{opacity:.95;transform:scale(1)}
  100%{opacity:1;transform:scale(1.75)}
}
/* ダイヤの位置を原点にした光源。子はすべて中心合わせ */
.op-light{position:absolute;left:49.7%;top:40.85%;width:0;height:0;pointer-events:none;z-index:3}
.op-light i{
  position:absolute;left:0;top:0;display:block;
  transform:translate(-50%,-50%) scale(0);opacity:0;
  mix-blend-mode:screen;
}
/* 放射する光条 */
.op-rays{
  width:900px;height:900px;border-radius:50%;
  background:repeating-conic-gradient(from 0deg,
    rgba(255,252,244,.92) 0deg 1deg, transparent 1deg 8.4deg);
  -webkit-mask-image:radial-gradient(circle, #000 4%, rgba(0,0,0,.8) 13%, transparent 52%);
          mask-image:radial-gradient(circle, #000 4%, rgba(0,0,0,.8) 13%, transparent 52%);
}
html.op-open .op-rays{animation:op-rays 1.8s cubic-bezier(.22,.6,.3,1) 1.16s both}
@keyframes op-rays{
  0%  {opacity:0;transform:translate(-50%,-50%) scale(.04) rotate(0deg)}
  24% {opacity:.95;transform:translate(-50%,-50%) scale(.4) rotate(8deg)}
  100%{opacity:0;transform:translate(-50%,-50%) scale(2.7) rotate(26deg)}
}
/* ふくらむ光球 */
.op-core{
  width:560px;height:560px;border-radius:50%;
  background:radial-gradient(circle,#fff 0%,#fff8e8 8%,rgba(246,224,176,.88) 19%,rgba(216,167,161,.4) 35%,transparent 66%);
}
html.op-open .op-core{animation:op-core 2s cubic-bezier(.32,.5,.2,1) 1.1s both}
@keyframes op-core{
  0%  {opacity:0;transform:translate(-50%,-50%) scale(.02)}
  18% {opacity:1;transform:translate(-50%,-50%) scale(.16)}
  58% {opacity:1;transform:translate(-50%,-50%) scale(1.1)}
  100%{opacity:.92;transform:translate(-50%,-50%) scale(3.5)}
}
/* 石の四条のきらめき */
.op-flare{
  width:330px;height:330px;
  background:
    linear-gradient(90deg,rgba(255,255,255,0) 4%,rgba(255,252,242,.95) 50%,rgba(255,255,255,0) 96%) center/100% 2.4px no-repeat,
    linear-gradient(0deg, rgba(255,255,255,0) 14%,rgba(255,252,242,.9) 50%,rgba(255,255,255,0) 86%) center/2.4px 100% no-repeat;
}
html.op-open .op-flare{animation:op-flare 1.3s var(--ease) .95s both}
@keyframes op-flare{
  0%  {opacity:0;transform:translate(-50%,-50%) scale(.16) rotate(-8deg)}
  32% {opacity:1;transform:translate(-50%,-50%) scale(1) rotate(0deg)}
  100%{opacity:0;transform:translate(-50%,-50%) scale(1.85) rotate(7deg)}
}
/* 画面いっぱいの閃光。ここまで白く飛ばしてから本編へ渡す */
.op-veil{
  position:absolute;inset:0;pointer-events:none;opacity:0;z-index:5;
  background:radial-gradient(circle at 50% 38%, #fffdf7 0%, #fdf4df 24%, rgba(241,216,171,.9) 50%, rgba(200,163,152,.55) 74%, rgba(11,16,28,0) 100%);
}
html.op-open .op-veil{animation:op-veil 1.7s ease-out 1.4s both}
@keyframes op-veil{0%{opacity:0}38%{opacity:1}100%{opacity:1}}

/* 光が満ちたところでオーバーレイごと退場（＝本編が光の中から現れる） */
html.op-open .op{animation:op-away .85s ease 2.1s forwards}
@keyframes op-away{to{opacity:0;visibility:hidden}}
/* JSが完全に死んでも、演出の幕だけは必ず引く（スクロール錠は head 側の保険で外す） */
html.opshut .op{animation:op-failsafe 11s linear forwards}
@keyframes op-failsafe{0%,96%{opacity:1;visibility:visible}100%{opacity:0;visibility:hidden}}

/* ---------- 本編の立ち上がり ---------- */
/* 演出の間は伏せておき、光が引くのに合わせて起こす。
   op-hold は必ず opacity:1 で終わるので、開幕が来なくても自己修復する */
/* .concept は main の外（body 直下のセクション）なので、明示して同じ組に入れる */
html.opshut header.nav,html.opshut main,html.opshut .concept,html.opshut .footer{animation:op-hold 4s linear both}
@keyframes op-hold{0%,88%{opacity:0}100%{opacity:1}}
html.op-open header.nav,html.op-open main,html.op-open .concept,html.op-open .footer{
  animation:op-emerge 1.3s var(--ease) 1.95s both;
}
@keyframes op-emerge{
  0%{opacity:0;transform:translateY(20px) scale(1.015)}
  100%{opacity:1;transform:none}
}

/* ---------- 動きを減らす設定では出さない ---------- */
@media (prefers-reduced-motion:reduce){
  .op{display:none !important}
  html.opshut header.nav,html.opshut main,html.opshut .concept,html.opshut .footer,
  html.op-open header.nav,html.op-open main,html.op-open .concept,html.op-open .footer{animation:none;opacity:1;transform:none}
}
