/* ============================================================================
   ギフト開封演出 (gift-open.js とセット)
   ----------------------------------------------------------------------------
   ・全モーションは WAAPI (element.animate) で駆動する。 七転機は
     prefers-reduced-motion が常時 ON のため CSS keyframes / transition は殺される。
   ・アニメは transform / opacity のみ。 filter は静的にしか使わない
     (拡大しながら filter を動かすとカクつく実績あり)。
   ・券のデザインは 366x156 固定。 画面が狭いときは .gopen-slots ごと縮める
     (文字組みを崩さないため)。
   ・最終状態は WAAPI の fill だけに頼らず、 CSS 側にも既定値を持たせる。
   ========================================================================== */

.gopen {
  position: relative;
  overflow: hidden;
  background: #08070b;
  perspective: 1600px;
  perspective-origin: 50% var(--gopen-top, 38%);
  /* サイトの本文書体に合わせる */
  font-family: 'Zen Kaku Gothic New', system-ui, -apple-system, 'Hiragino Sans', 'Noto Sans JP', sans-serif;
  letter-spacing: -0.03em;
  -webkit-font-smoothing: antialiased;
}
.gopen * { pointer-events: none; }
.gopen .gopen-ui { pointer-events: auto; }

/* --- ジャケット (合成サムネ 512px。 無ければ原寸 bg + mono へ落ちる) ------ */
.gopen-jk-img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover; }
.gopen-jk-bg   { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover; }
.gopen-jk-mono { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: contain; padding: 12%; }

/* --- 背景のビート壁 ------------------------------------------------------ */
.gopen-wall { position: absolute; inset: 0; z-index: 5; }
.gopen-jk { position: absolute; overflow: hidden; background: #111; }
.gopen-jk .lay { position: absolute; inset: 0; }
/* 施錠側は静的フィルタ。 解錠は opacity を 1 → 0 にするだけ (filter は動かさない) */
.gopen-jk .lay.locked { filter: grayscale(1) brightness(0.4); }

/* --- 暗転 (着地後は浅く / すべて見るときは深く) --------------------------- */
.gopen-scrim { position: absolute; inset: 0; background: #050409; z-index: 16; opacity: 0; }

/* --- 券 ------------------------------------------------------------------ */
.gopen-slots { position: absolute; inset: 0; z-index: 18; transform-origin: 50% var(--gopen-top, 38%); }
/* 縦型: 券は覆いのグラデ (30) より前面に出す (七転指示 2026-08-17:
   券も文面も全面表示。 グラデは壁と受け取り欄まわりの暗がりに徹する)。 */
.gopen-vert .gopen-slots { z-index: 32; }
/* 振替の裏返し中だけ券を文面 (45) より前へ — 回転で広がった札が文面の下に
   潜ると立体感が台無しになる (七転指示 2026-08-19)。 操作列 (50) は超えない。 */
.gopen-vert.gopen-flipping .gopen-slots { z-index: 48; }
/* perspective はここに書かない。 書くと 3D レンダリング文脈が常時できてしまい、
   カードが合成レイヤに載ったまま残って、 演出中に焼かれた粗い絵が居座る。
   奥行きは配りのキーフレーム側で perspective() 関数として与え、
   終わったら 2D に戻すことで文脈ごと消える。 */
.gopen-slot {
  position: absolute; left: 50%; top: var(--gopen-top, 38%);
  width: 366px; height: 156px; margin: -78px 0 0 -183px;
}
/* will-change も付けない (同じ理由)。 ブラウザに任せると静止時に必ず描き直される */
.gopen-card { position: absolute; inset: 0; }
.gopen-face {
  position: absolute; inset: 0; display: flex; overflow: hidden;
  background: #0d0c11;
  box-shadow: 0 26px 56px -18px rgba(0, 0, 0, .92), inset 0 1px 0 rgba(255, 255, 255, .12);
}
/* 束の奥へ回った券を沈める板。 中身を見せず紙の小口だけを見せる */
.gopen-dim { position: absolute; inset: 0; background: #05040a; z-index: 5; opacity: 0; }
.gopen-shadow {
  position: absolute; left: 8%; right: 8%; bottom: -15px; height: 24px; border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, .7), transparent 70%);
  opacity: 0; z-index: -1;
}

/* 半券 (左の正方形) */
.gopen-stub { position: relative; width: 156px; height: 156px; flex: 0 0 auto; overflow: hidden; }
/* すべてのビートから選べる券: ブランドのグラデーション + 8on7 マーク */
.gopen-stub.grad {
  background-image:
    radial-gradient(120% 130% at 85% 90%, #8a8ce8 0%, #b49be7 22%, rgba(180, 155, 231, 0) 55%),
    radial-gradient(100% 110% at 70% 70%, #ff2d91 0%, #f56ab3 28%, rgba(245, 106, 179, 0) 60%),
    linear-gradient(135deg, #ff4a1c 0%, #ff6b1c 35%, #ff3d8a 65%, #a08ef5 100%);
}
.gopen-slot.tier-basic .gopen-stub.grad {
  background-image:
    radial-gradient(110% 120% at 80% 90%, #5b53d8 0%, rgba(91, 83, 216, 0) 58%),
    linear-gradient(135deg, #17b3a3 0%, #2f7ae5 55%, #5b53d8 100%);
}
.gopen-slot.tier-exclusive .gopen-stub.grad {
  background-image:
    radial-gradient(110% 120% at 82% 88%, #a08ef5 0%, rgba(160, 142, 245, 0) 58%),
    linear-gradient(150deg, #e8c15a 0%, #ff3d8a 55%, #a08ef5 100%);
}
.gopen-mark { position: absolute; inset: 7%; z-index: 2; }
/* filter を付けると合成レイヤになり、 拡大時に解像度が上がらない。 影は諦める */
.gopen-mark img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* このビートを贈る券は半券がそのままジャケット (.gopen-jk-* を共用) */

/* 券の本文 */
.gopen-body {
  flex: 1; min-width: 0; position: relative; overflow: hidden;
  padding: 16px; display: flex; flex-direction: column; justify-content: space-between;
  border-left: 1px solid rgba(255, 255, 255, .14);
}
.gopen-cover { position: absolute; inset: 0; background: #0d0c11; z-index: 4; }
.gopen-plan {
  font-family: 'JetBrains Mono', monospace; font-size: 9.5px; letter-spacing: .2em;
  color: rgba(255, 255, 255, .62);
}
.gopen-main { font-size: 19px; font-weight: 800; line-height: 1.32; color: #fff; letter-spacing: -.01em; }
.gopen-main.beat { font-size: 22px; }
/* 本数の数字。 桁を縦に並べて 1 枚の帯にし、 transform で送る。
   1 文字ずつ差し替えて拡大縮小させると、 文字が毎フレーム焼き直されて
   ガタつくうえ、 桁が増えた瞬間に幅が変わって行が動く。
   .sz が見えないまま幅と行の基準（ベースライン）を作り、 .win がその窓になる。 */
.gopen-num {
  font-style: normal; font-size: 26px; display: inline-block; position: relative;
  line-height: 1.05;
}
.gopen-num .sz { visibility: hidden; }
.gopen-num .win { position: absolute; inset: 0; overflow: hidden; }
.gopen-num .roll { position: absolute; left: 0; top: 0; width: 100%; }
.gopen-num .roll i {
  display: block; height: 1.05em; line-height: 1.05em;
  font-style: normal; text-align: center;
}
.gopen-sub { font-size: 10.5px; line-height: 1.55; color: rgba(255, 255, 255, .58); }
.gopen-no {
  font-family: 'JetBrains Mono', monospace; font-size: 8.5px; letter-spacing: .16em;
  color: rgba(255, 255, 255, .4);
}
.gopen-band {
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px; z-index: 4;
  background: linear-gradient(90deg, #ff4a1c, #ff3d8a, #a08ef5);
}
.gopen-slot.tier-basic     .gopen-band { background: linear-gradient(90deg, #17b3a3, #2f7ae5, #5b53d8); }
.gopen-slot.tier-exclusive .gopen-band { background: linear-gradient(90deg, #e8c15a, #ff3d8a, #a08ef5); }
.gopen-shine {
  position: absolute; top: 0; left: 0; width: 55%; height: 100%; z-index: 6; opacity: 0;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .5), transparent);
  transform: translateX(-190%) skewX(-18deg);
}
.gopen-qty {
  position: absolute; right: 10px; top: 10px; z-index: 7;
  font-family: 'JetBrains Mono', monospace; font-size: 9px; letter-spacing: .14em;
  color: rgba(255, 255, 255, .92); background: rgba(0, 0, 0, .45); padding: 3px 7px;
}

/* --- 縦型の券 (スマホ縦画面 .gopen-vert)。 DOM は横型と同一、 寸法だけ変える ---
   本文は 380 - 250 - 1 = 129px。 詰め込みすぎない (下端接触の再発防止):
   plan 12 + main 51 (18px x 1.44 x 2行) + sub 16 + No 11 + 余白 27 + padding = 129 */
.gopen-vert .gopen-slot { width: 250px; height: 380px; margin: -190px 0 0 -125px; }
.gopen-vert .gopen-face { flex-direction: column; }
.gopen-vert .gopen-stub { width: 100%; height: 250px; flex: 0 0 auto; }
.gopen-vert .gopen-body {
  border-left: 0; border-top: 1px solid rgba(255, 255, 255, .14);
  padding: 13px 16px 14px;
}
.gopen-vert .gopen-plan { font-size: 9px; }
.gopen-vert .gopen-main { font-size: 18px; line-height: 1.44; }
.gopen-vert .gopen-main.beat { font-size: 22px; }
.gopen-vert .gopen-sub { margin-top: 3px; line-height: 1.55; }
.gopen-vert .gopen-num { font-size: 22px; }
.gopen-vert .gopen-msg { width: min(calc(250px * var(--ms)), calc(100% - 24px)); }
/* 文面の保険: 縦は最大8行で必ず打ち切る (行数見積もりの上限と一致させる) */
.gopen-vert .gopen-text { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 8; overflow: hidden; }

/* --- ボトム・コンソールの帯 (縦型) ----------------------------------------
   画面下部を〔覆いのグラデ(30) → 文面(45) → 操作列(50) → 受け取り欄〕の
   一体の帯として扱う (七転指示 2026-08-16: 構造の根本見直し)。
   縦位置はこの包みが一手に持ち (bottom は --gopen-inset に追従)、
   文面本体は幅 (--ms) の FLIP だけを担当する。 */
.gopen-msgwrap {
  position: absolute; left: 0; right: 0; z-index: 45;
  display: flex; justify-content: center;
  pointer-events: none;
  /* 開幕幅 → 最終幅の FLIP は下端を軸に縮む (券と同じ1本のアニメで同期) */
  transform-origin: 50% 100%;
}
.gopen-vert .gopen-msgwrap .gopen-msg {
  position: relative; left: auto; top: auto; bottom: auto;
  transform: none; transform-origin: 50% 100%;
}

/* --- メッセージ: 券と同じ地色・同じ帯・同じ幅で組む ------------------------ */
.gopen-msg {
  /* --ms = 実寸の倍率。 幅も余白も文字も、 これを掛けた**実寸**で組む。
     scale で引き伸ばすと 1 倍で焼いた絵が拡大されて字がぼやけるため
     (七転指摘 2026-08-06)。 動かす間だけ scale を使い、 止まったら実寸へ戻す。 */
  --ms: 1;
  position: absolute; left: 50%; bottom: 64px; transform: translateX(-50%);
  transform-origin: 50% 0;   /* 拡大しても上端が動かない = 券の真下に留まる */
  width: min(calc(366px * var(--ms)), calc(100% - 28px)); box-sizing: border-box;
  padding: calc(15px * var(--ms)) calc(16px * var(--ms)) calc(16px * var(--ms));
  text-align: left; overflow: hidden;
  background: #0d0c11; box-shadow: 0 20px 46px -18px rgba(0, 0, 0, .9);
  z-index: 45; opacity: 0;
}
/* 帯の色は一番高いプランのグレードカラーに揃える */
.gopen-msg::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: calc(3px * var(--ms)); z-index: 2;
  background: linear-gradient(90deg, #ff4a1c, #ff3d8a, #a08ef5);
}
.gopen-msg.tier-basic::before     { background: linear-gradient(90deg, #17b3a3, #2f7ae5, #5b53d8); }
.gopen-msg.tier-exclusive::before { background: linear-gradient(90deg, #e8c15a, #ff3d8a, #a08ef5); }
/* 「Message from」だけ等幅の英字。 名前は日本語が来るので本文と同じ書体で組む */
.gopen-from { display: flex; align-items: baseline; gap: calc(9px * var(--ms));
  margin-bottom: calc(8px * var(--ms)); flex-wrap: wrap; }
.gopen-from .k {
  font-family: 'JetBrains Mono', monospace; font-size: calc(9.5px * var(--ms)); letter-spacing: .2em;
  text-transform: uppercase; color: rgba(255, 255, 255, .5); white-space: nowrap;
}
.gopen-from .n {
  font-size: calc(12.5px * var(--ms)); font-weight: 700; line-height: 1.4; letter-spacing: .02em;
  color: rgba(255, 255, 255, .9); word-break: break-word; min-width: 0;
}
/* --mf = 文字だけの縮小率 (長文/狭い置き場)。 幅 (--ms) は券と常に一致させる */
/* 🔴 改行をそのまま出す（2026-08-24 七転さん指示）
   「ギフトメッセージについて、改行したい人もいると思います。
     ですので、改行は反映し、改行の場合は何行までという制限を作っておいてください。」
   指定が無いと、
 は**ただの空白に潰れます**。打った改行が消えていました。
   pre-wrap にすると、改行はそのまま・行末の折り返しもそのまま効きます。 */
.gopen-text { font-size: calc(13px * var(--ms) * var(--mf, 1)); line-height: 1.72; color: rgba(255, 255, 255, .94);
              white-space: pre-wrap; overflow-wrap: anywhere; }
/* 差出人だけの時は本文が無い。 見出しの下の余白を殺し、 名前を大きくして
   1行の署名として成立させる (そのままだと文字が上に張り付いて下が空く) */
.gopen-msg.is-sign { padding: calc(17px * var(--ms)) calc(16px * var(--ms)); }
.gopen-msg.is-sign .gopen-from { margin-bottom: 0; gap: calc(11px * var(--ms)); }
.gopen-msg.is-sign .gopen-from .n { font-size: calc(16px * var(--ms)); }
/* --- ギフトカード仕立て (差出人がいない時。 七転指示 2026-08-24) -----------
   名前で飾れない代わりに、 細い罫と GIFT FOR YOU の箔押し風の見出しで
   「贈りもの」であることを静かに示す。 券と同じ地色・同じ帯のまま。 */
.gopen-msg.is-card { text-align: center; padding-top: calc(18px * var(--ms)); }
.gopen-gfy {
  display: flex; align-items: center; justify-content: center;
  gap: calc(11px * var(--ms)); margin-bottom: calc(11px * var(--ms));
}
.gopen-gfy::before, .gopen-gfy::after {
  content: ""; height: 1px; flex: 1 1 auto; max-width: calc(52px * var(--ms));
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .3));
}
.gopen-gfy::after { background: linear-gradient(90deg, rgba(255, 255, 255, .3), transparent); }
.gopen-gfy span {
  font-family: 'JetBrains Mono', monospace; font-weight: 600;
  font-size: calc(9.5px * var(--ms)); letter-spacing: .3em; text-indent: .3em;
  text-transform: uppercase; white-space: nowrap;
  background: linear-gradient(90deg, #ff6b1c, #ff3d8a, #a08ef5);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.gopen-msg.is-card .gopen-text { text-align: center; }

/* ── メッセージカード「プレゼント」（2026-08-24 七転さん指示①・第1弾） ──
   自由入力をやめ、デザインされたカードを出す。寸法は --ms 連動の固定形なので、
   行数でレイアウトが変わる問題そのものが起きない。
   絵柄を差し替えるときは .gopen-present の中身だけを入れ替えればよい。 */
.gopen-msg.is-design { padding-bottom: calc(18px * var(--ms)); }
.gopen-present {
  display: flex; flex-direction: column; align-items: center;
  gap: calc(7px * var(--ms));
  padding: calc(8px * var(--ms)) 0 calc(4px * var(--ms));
}
.gp-eyebrow {
  font-family: 'JetBrains Mono', monospace; font-weight: 600;
  font-size: calc(8.5px * var(--ms)); letter-spacing: .34em; text-indent: .34em;
  color: rgba(255, 255, 255, .55); text-transform: uppercase; white-space: nowrap;
}
.gp-word {
  font-family: 'Archivo Black', 'Corporate Logo Bold', 'Zen Kaku Gothic New', sans-serif;
  font-size: calc(26px * var(--ms)); line-height: 1.15; letter-spacing: .04em;
  background: linear-gradient(92deg, #ff6b1c 0%, #ff3d8a 52%, #a08ef5 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  white-space: nowrap;
}
.gp-sub {
  font-size: calc(10.5px * var(--ms)); letter-spacing: .06em;
  color: rgba(255, 255, 255, .66); white-space: nowrap;
}
.gopen-msg.is-design .gp-from {
  justify-content: center; margin-top: calc(10px * var(--ms)); margin-bottom: 0;
}

.gopen-msg-cover { position: absolute; inset: 0; background: #0d0c11; z-index: 3; }

/* --- 操作列 --------------------------------------------------------------- */
/* 下端に張り付くと窮屈なので底から離す。 メッセージ側の余白計算
   (gift-open.js の DOCK_SPACE) もこの値に合わせてあるので、 変える時は両方直すこと。 */
.gopen-dock {
  /* --gopen-inset = 下から重なってくる UI の高さ (受け取りページの操作欄)。
     --gopen-plift = パネルが予約より背が高い時の追加持ち上げ (liftForPanel が焼く)。
     受け取り欄の**直上**に置く (七転指示 2026-08-17: カーソルを下げて場所を空ける)。
     最終位置は必ずこのレイアウト式が持つ (fill:forwards は後発アニメに
     自動置換されて消えるため、 位置の記憶に使ってはならない)。 */
  position: absolute; left: 0; right: 0;
  bottom: calc(12px + var(--gopen-inset, 0px) + var(--gopen-plift, 0px));
  /* ★文面 (45) より必ず後ろ。 飾り幕 (::before) が文面にかぶらない (七転指示 2026-08-23) */
  height: 46px; z-index: 43;
  display: flex; align-items: center; justify-content: center; gap: 12px; opacity: 0;
}
/* ドックの暗幕。 ただし下から UI が重なる画面 (.has-inset) では出さない。
   覆いは呼び出し側が1枚だけ敷く — 2枚あると必ずどこかに境目ができる。 */
.gopen-dock::before {
  content: ""; position: absolute; left: 0; right: 0; top: -22px; bottom: -26px; z-index: -1;
  background: linear-gradient(to top, rgba(6, 5, 9, .92) 58%, rgba(6, 5, 9, 0));
}
.gopen.has-inset .gopen-dock::before { display: none; }
/* 空のドック (1枚の開幕など) は飾り幕も出さない — 黒グラデが2回出るの真因 */
.gopen-dock.is-empty::before { display: none; }
/* 縦型は飾り幕自体を廃止 — 黒グラデは受け取り欄のベール1回だけ (七転確認 2026-08-23) */
.gopen-vert .gopen-dock::before { display: none; }
.gopen-btn {
  font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: .16em;
  /* 暗い下地では覆いのグラデーションに沈んで見落とされる (七転指摘 2026-08-09)。
     ‹ › も「すべて見る」と同じ白の面にして、 どの背景でも必ず目に入るようにする。 */
  text-transform: uppercase; color: #0d0c11;
  /* hover でグラデに変わるボタンに枠は置かない (枠との継ぎ目が出る。 七転指示 2026-08-10) */
  background: #f4f2ee; border: 0;
  padding: 9px 17px; cursor: pointer;
}
/* hover は白→白だと反応が見えないので、 primary と同じブランドの色に変える */
.gopen-btn:hover {
  background: linear-gradient(120deg, #ff4a1c, #ff3d8a, #a08ef5); color: #fff;
}
.gopen-btn.primary { background: #fff; color: #0d0c11; }
.gopen-btn.primary:hover {
  background: linear-gradient(120deg, #ff4a1c, #ff3d8a, #a08ef5); color: #fff; border-color: transparent;
}
.gopen-btn:focus-visible { outline: 2px solid #ff3d8a; outline-offset: 2px; }
.gopen-idx {
  font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: .14em;
  color: rgba(255, 255, 255, .95); min-width: 56px; text-align: center;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .85);
}
.gopen-grab { position: absolute; inset: 0; z-index: 42; cursor: grab; touch-action: pan-y; }
.gopen-tip {
  position: absolute; left: 50%; top: 14px; transform: translateX(-50%); z-index: 46; opacity: 0;
  font-family: 'JetBrains Mono', monospace; font-size: 9.5px; letter-spacing: .18em;
  color: rgba(255, 255, 255, .5);
}

/* --- 再生前のヒント ------------------------------------------------------- */
.gopen-hint {
  position: absolute; inset: 0; z-index: 60; display: flex;
  align-items: center; justify-content: center; flex-direction: column; gap: 9px;
  color: rgba(255, 255, 255, .82);
}
/* 再生ボタンはサイト共通の .play-btn と同じ見た目にする
   (白い丸に濃い三角)。 細い白枠だと画面ごとに印象が変わって一貫しない。 */
.gopen-hint .ring {
  width: 54px; height: 54px; border-radius: 50%; border: 0;
  background: #fff; display: grid; place-items: center;
  box-shadow: 0 6px 20px -8px rgba(0, 0, 0, .55);
}
.gopen-hint .ring::after {
  content: ""; margin-left: 3px;
  border-left: 13px solid #0a0a0a;
  border-top: 8px solid transparent; border-bottom: 8px solid transparent;
}
.gopen-hint span {
  font-family: 'JetBrains Mono', monospace; font-size: 10px; letter-spacing: .2em; text-transform: uppercase;
}
