/* ==========================================================================
   2026 Triangleヒロイン抱き枕 - style.css
   表示はダーク固定（テーマ切替なし）
   基準色は Triangle 本サイトに準拠（#D70058 / #3a312f / #F2F2F2）
   ========================================================================== */

:root {
  color-scheme: dark;
  /* ダーク背景では #d70058 はコントラスト不足になるため、ブランド色は明るい側の値を使う */
  --brand: #ff5c8f;
  --brand-dark: #ff7ba6;
  --brand-bg: #2b1a22;
  --ink: #f1eceb;
  --ink-soft: #b6adab;
  --line: #3b3432;
  --page: #1b1817;
  --panel: #242020;
  --surface: #242020;
  --on-brand: #1b1817;
  --max-width: 1080px;
  --radius: 10px;
  --shadow: 0 3px 14px rgba(0, 0, 0, 0.55);
  /* 固定ヘッダー分（main.js が実測値で上書きするまでの暫定値） */
  --header-offset: 120px;
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo, sans-serif;
  font-size: 16px;
  line-height: 1.8;
  word-break: break-word;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: var(--brand);
  /* 本文中のリンクは下線なし（色で判別する）。ボタン・ナビ・フッター側にも
     個別に text-decoration: none を書いてあるが、ここでまとめて消している */
  text-decoration: none;
}

a:hover {
  color: var(--brand-dark);
}

/* h4 は商品紹介の抱き枕絵柄フレームの中の名前見出し（.design-name）だけ。
   .character-name（h3）と同じ書体で揃える */
h1,
h2,
h3,
h4 {
  font-family: "M PLUS 1p", "Hiragino Kaku Gothic ProN", sans-serif;
  line-height: 1.4;
}

/* ===== 利便性: 本文へスキップ ===== */
/* 視覚的には見せないがスクリーンリーダーには読ませる */
.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: absolute;
  left: -9999px;
  top: 0;
  background: var(--brand);
  color: var(--on-brand);
  padding: 8px 14px;
  z-index: 1000;
}

.skip-link:focus {
  left: 8px;
}

/* ===== 年齢確認モーダル ===== */
#ageVerificationModal {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.8);
  z-index: 9999;
  justify-content: center;
  align-items: center;
}

.age-box {
  background: var(--surface);
  color: var(--ink);
  padding: 30px;
  border-radius: var(--radius);
  text-align: center;
  width: 400px;
  max-width: 90%;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
}

.age-box h2 {
  margin: 0 0 12px;
  font-size: 20px;
  color: var(--ink);
}

.age-box p {
  margin: 0 0 20px;
  color: var(--ink-soft);
  font-size: 14px;
}

.age-buttons button {
  border: none;
  border-radius: 5px;
  padding: 12px 22px;
  font-size: 15px;
  color: var(--on-brand);
  cursor: pointer;
  margin: 0 5px;
}

#ageYes {
  background: var(--brand);
}

#ageNo {
  background: var(--ink-soft);
}

/* ===== ヘッダー（ページ上部に固定） ===== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 900;
  border-top: 4px solid var(--brand);
  background: var(--page);
  box-shadow: 0 2px 8px rgba(95, 95, 95, 0.15);
}

.header-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 14px 20px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* ===== ヘッダー右側（ナビ） ===== */
.header-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
}

.brand-logo {
  text-decoration: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.brand-kicker {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2em;
  color: var(--brand);
}

.brand-title {
  font-family: "M PLUS 1p", "Hiragino Kaku Gothic ProN", sans-serif;
  font-weight: 800;
  font-size: 22px;
  line-height: 1.3;
  color: var(--ink);
}

.brand-logo:hover .brand-title {
  color: var(--brand);
}

.global-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.global-nav a {
  display: block;
  padding: 8px 14px;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 3px solid transparent;
}

.global-nav a:hover {
  color: var(--brand);
  border-bottom-color: var(--brand);
}

/* ===== アンカー移動時の位置調整（固定ヘッダーに隠れないため） ===== */
/* main.js が --header-offset にヘッダー実測高を代入する。未実行時のフォールバック値も置く */
section[id] {
  scroll-margin-top: var(--header-offset, 120px);
}

/* ===== ナビの現在地表示 ===== */
.global-nav a.is-active {
  color: var(--brand);
  border-bottom-color: var(--brand);
  background: var(--brand-bg);
}

/* ===== ヒーロー ===== */
.hero {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 32px 20px 40px;
  text-align: center;
}

.hero-logo {
  margin: 0 auto;
  max-width: 860px;
}

.hero-logo img {
  width: 100%;
  max-width: 780px;
  height: auto;
  margin: 0 auto;
}

/* ===== ボタン ===== */
.button {
  display: inline-block;
  padding: 12px 28px;
  background: var(--brand);
  color: var(--on-brand) !important;
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
  border-radius: 999px;
  box-shadow: 0 3px 10px rgba(215, 0, 88, 0.25);
}

.button:hover {
  background: var(--brand-dark);
}

/* 期間外で無効にしたボタン（通販ボタンは js/store-link.js、投票ボタンは js/costume-vote.js）。
   通販ボタンは href も外すのでリンクとして機能しない。見た目もグレーにする
   （.button の color は !important なのでこちらでも !important を使って上書きする）。
   button.button:disabled も同じ見た目にして、クラスを付け忘れた場合でもグレーになるようにする */
.button.is-disabled,
.button.is-disabled:hover,
button.button:disabled,
button.button:disabled:hover {
  background: var(--line);
  color: var(--ink-soft) !important;
  box-shadow: none;
  cursor: not-allowed;
}

/* <button> を .button として使う場合の既定値リセット */
button.button {
  border: none;
  font-family: inherit;
  letter-spacing: 0.06em;
  cursor: pointer;
}

button.button:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
}

/* ===== セクション共通 ===== */
.section {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 36px 20px;
  border-top: 1px solid var(--line);
}

/* 非表示にしたセクション（現状は #order の受注申込）。
   hidden 属性を外せばそのまま復活する。display を指定したセクションが増えた場合に
   上書きされないよう、ここで明示しておく */
section[hidden] {
  display: none;
}

.section-title {
  margin: 0 0 18px;
  padding-left: 12px;
  font-size: 22px;
  border-left: 6px solid var(--brand);
  color: var(--ink);
}

.note {
  margin: 0 0 16px;
  font-size: 13px;
  color: var(--ink-soft);
}

.note-list {
  margin: 0;
  padding-left: 20px;
  font-size: 14px;
}

.cta-block {
  margin: 18px 0 0;
}

/* 期間の外だけに出す案内（通販ボタン直下の #store-note は js/store-link.js、
   投票期間の直下の #vote-note は js/costume-vote.js が見せる）。.note をそのまま使うので
   色やサイズは共通で、周囲との余白だけ変えている */
.store-note,
.vote-note {
  margin: 10px 0 16px;
}

/* ===== 商品仕様テーブル ===== */
.spec-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.spec-table th,
.spec-table td {
  border: 1px solid var(--line);
  padding: 12px 14px;
  text-align: left;
  vertical-align: top;
}

.spec-table th {
  width: 30%;
  background: var(--panel);
  font-weight: 700;
}

/* ===== 商品紹介セクション内のブロック（抱き枕の絵柄・リポストキャンペーン） =====
   どちらも .section の本文の中に置くブロック。上余白と上線の実線で本文から区切る */
.campaign-block,
.design-block {
  margin-top: 34px;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}

/* ===== 抱き枕の絵柄（キャラクター別の表面・裏面） =====
   3キャラクター分のフレーム .design-card を .design-grid で横並びに並べる。
   狭い画面ではキャラクターごとに1列へ積む（下の @media (max-width: 820px)）。
   フレームの中の表面/裏面はどの幅でも左右に並べる（抱き枕は縦長いので上下に積まない）。
   拡大表示は立ち絵と同じ js/standing-lightbox.js（.design-zoom がトリガー） */

/* 3列。minmax(0,1fr) にしているので、フレームの中の2枚はどの幅でも折れない */
.design-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  margin: 18px 0 0;
  padding: 0;
  list-style: none;
}

/* キャラクター1体ぶん。見た目は投票セクションの .character-card と揃える */
.design-card {
  margin: 0;
  min-width: 0;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.design-name {
  margin: 0 0 14px;
  padding-left: 10px;
  font-size: 17px;
  color: var(--brand);
  border-left: 4px solid var(--brand);
}

/* 表面/裏面を左右に。ここは幅が変わっても2列のまま（上下に積むとフレームが異常に長くなる） */
.design-sides {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.design-side {
  min-width: 0;
}

/* 画像の左上に置く「表面」「裏面」のラベル（枠の中に重ねず、枠の上に書く） */
.design-side-label {
  display: block;
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
}

/* 実寸 439x1403（= 抱き枕 50cm x 160cm と同じ比率）の枠。
   aspect-ratio で枠の形を決めてあるので、画像が入っていない枠（後日公開の裏面）も同じ形。
   .image-slot を一緒に付けているので、<img> が入ると破線は自動で実線に切り替わる。
   position: relative は .design-zoom を重ねる基準 */
.design-photo {
  position: relative;
  aspect-ratio: 439 / 1403;
}

/* .image-slot img の width/height を上書きするので、クラスを1つ足して特度を上げる
   （.image-slot img は後ろに書かれているため、.design-photo img だけでは負ける） */
.image-slot.design-photo img {
  width: 100%;
  height: 100%;
  /* 枠が実画像と同じ比率なので、実際には何も切れない。
     後から別の比率の画像（裏面の完成絵柄など）が来てもフレームの形が崩れないよう cover にしてある。
     枠に合わせず画像全体をそのまま見たい場合は contain にする（上下または左右に地が出る） */
  object-fit: cover;
}

/* 枠全体を覆う透過ボタン（.prize-zoom と同じ組み方。js/standing-lightbox.js が .standing-zoom と一緒に拾う）。
   中身の文字は使わず aria-label で名前を付ける */
.design-zoom {
  position: absolute;
  inset: 0;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  cursor: zoom-in;
  font-size: 0;
  color: transparent;
}

.design-zoom:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: -3px;
}

/* 枠線がブランド色に変わるのを、その画像の上に乗った時だけにする（キャラクター枠全体ではない）。
   .image-slot:has(img) の border-color（クラス1＋擬似クラス1）に勝つため、クラスを2つ並べている */
.image-slot.design-photo:hover {
  border-color: var(--brand);
}

/* ===== 裏面絵柄ユーザー投票（企画の説明と投票期間） ===== */
.campaign-lead {
  margin: 0 0 14px;
}

.campaign-lead strong {
  color: var(--brand-dark);
}

/* セクションの中の企画ブロック（商品紹介にあるリポストキャンペーンなど）の小見出し。
   .section-title と同じ左の棒で系列を示しつつ、小さめ＋上余白で本文から区切る */
.campaign-title {
  margin: 30px 0 12px;
  padding-left: 10px;
  border-left: 4px solid var(--brand);
  font-size: 18px;
  letter-spacing: 0.06em;
  color: var(--ink);
}

/* 投票期間の一行案内。ブランド色の枠で囲んで本文から目立たせる（flex なので狭い幅では縦に積まれる） */
.campaign-period {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 12px;
  margin: 18px 0;
  padding: 12px 16px;
  border: 1px solid var(--brand);
  border-radius: var(--radius);
  background: var(--brand-bg);
  letter-spacing: 0.06em;
}

.campaign-period-label {
  padding: 2px 12px;
  border-radius: 999px;
  background: var(--brand);
  color: var(--on-brand);
  font-size: 13px;
  font-weight: 700;
}

.campaign-period-dates {
  font-size: 17px;
  font-weight: 700;
  color: var(--ink);
}

/* 投票が終わった後だけ、js/costume-vote.js が #vote-period（.campaign-period）に .is-ended を付ける。
   期間表記をグレー + 打消し線にして、右側に .campaign-period-ended を並べる。
   開始前（投票が始まる前）には付けない。リポストキャンペーン側の .campaign-period は
   スクリプトを持たないので、ここが効くのは投票期間の枠だけ */
.campaign-period.is-ended {
  border-color: var(--line);
  background: var(--panel);
}

.campaign-period.is-ended .campaign-period-label,
.campaign-period.is-ended .campaign-period-dates {
  color: var(--ink-soft);
}

.campaign-period.is-ended .campaign-period-dates {
  text-decoration: line-through;
}

/* .campaign-period は flex なので期間表記の右側に置かれる。
   狭い画面では折り返して次の行の右端に来る */
.campaign-period-ended {
  margin-left: auto;
  font-weight: 700;
  color: var(--ink-soft);
}

/* 投票ルールの案内。期間の枠の直下に置く小さな見出し＋箇条書き */
.campaign-rules {
  margin: 0 0 18px;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.campaign-rules-title {
  margin: 0 0 8px;
  font-size: 14px;
  letter-spacing: 0.06em;
  color: var(--brand-dark);
}

.campaign-rules ul {
  margin: 0;
  padding-left: 20px;
  font-size: 14px;
}

.campaign-rules li {
  margin: 0 0 6px;
}

.campaign-rules li:last-child {
  margin-bottom: 0;
}

/* ===== 裏面絵柄ユーザー投票（キャラクター枠） ===== */
.character-card {
  margin: 0 0 26px;
  padding: 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.character-name {
  margin: 0 0 16px;
  padding-left: 10px;
  font-size: 20px;
  color: var(--brand);
  border-left: 4px solid var(--brand);
}

/* 左カラム（立ち絵）/ 右カラム（コスチューム選択）
   1行目右列に選択見出し、2行目に左右カラムを置く。
   左右は同じ行にあるので上下のエッジがぴったり揃う */
.character-body {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  column-gap: 20px;
  row-gap: 12px;
  align-items: stretch;
}

.character-visual {
  grid-column: 1;
  grid-row: 2;
  min-width: 0;
  /* 内部の立ち絵枠を行の高さいっぱいまで伸ばす */
  display: flex;
}

/* 後で <img> をはめ込む枠。画像が入った瞬間にプレースホルダ用の装飾は外れる */
.image-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--panel);
  border: 2px dashed var(--line);
  border-radius: 6px;
}

/* 画像が入った枠も、枠線は残す（プレースホルダの破線だけを実線に切り替える）。
   立ち絵もコスチューム画像も背景透過なので、枠線がないと画像の範囲がどこまでか分からなくなる。
   枠線を消したい場合はこのブロックを消さず border-style: none; にする */
.image-slot:has(img) {
  border-style: solid;
  border-width: 1px;
  border-color: var(--line);
}

.image-slot img {
  display: block;
  width: 100%;
  height: auto;
  /* 画像ごとの微調整は、枠ではなく <img> 自身の style 属性で CSS 変数に渡す
       <img src="..." style="--img-scale:1.2; --img-x:-4%; --img-y:3%;">
     --img-scale : 倍率（既定 1）
     --img-x / --img-y : 移動量。% は画像要素自身のサイズ基準（この枠では枠のサイズと同じ）、px 指定も可（既定 0）
     --img-origin : 拡大・移動の基準点（既定 50% 50%。50% 100% にすると足元を固定して拡大できる）
     枠は overflow:hidden なので、拡大した分は枠の形で切り抜かれる。
     何も指定しない場合は object-fit: contain で画像全体が枠内に収まる */
  transform: translate(var(--img-x, 0%), var(--img-y, 0%)) scale(var(--img-scale, 1));
  transform-origin: var(--img-origin, 50% 50%);
}

/* 立ち絵枠・コスチューム画像枠は既定で枠に全体が収まる（上の --img-scale で拡大した分は切り抜かれる） */
.character-standing img,
.costume-thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* 立ち絵の切り替えは opacity のクロスフェードにする（js/standing-preview.js と組み合わせて使う）。
   拡大率・位置の調整が transform を使うため、遷移させるのは opacity だけにする。
   切り替え時間はこの1箇所だけで変えられる（JS は transitionend で片付ける側に回しているので、
   JS 側に時間は持たせていない）。0s にすれば即時切り替え */
.character-standing img {
  transition: opacity 420ms ease;
}

/* 画像を差し替えている間だけ、遷移を使わずに透明化する */
.character-standing img.is-standing-swap {
  transition: none;
}

.character-standing img.is-standing-hidden {
  opacity: 0;
}

/* 消えゆく側の一時的なレイヤー。フェードアウトしきったら JS が削除する */
.character-standing img.is-standing-out {
  opacity: 0;
  pointer-events: none;
}

/* 動きを抑える設定ではフェードしない（即時切り替え） */
@media (prefers-reduced-motion: reduce) {
  .character-standing img {
    transition: none;
  }
}

/* 立ち絵の画像はフローから外す。
   枠の高さは右カラム（コスチューム選択）に合わせに行くが、画像をフローに残したままだと
   縦長PNGの実寸比率（高さ1159px）で行高が決まってしまい、左カラムが途方もなく大きくなる。
   absolute にすれば枠のサイズに影響しないので、画像を入れる前と同じ高さになる */
.character-standing img {
  position: absolute;
  inset: 0;
}

/* 立ち絵枠全体を拡大表示のトリガーにする透過ボタン（js/standing-lightbox.js）。
   画像の上:absolute にするのでレイアウトには影響しない。
   中身の文字は使わず aria-label で名前を付ける */
.standing-zoom {
  position: absolute;
  inset: 0;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: zoom-in;
  font-size: 0;
  color: transparent;
}

.standing-zoom:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: -3px;
}

/* 初期画像（枠に書いた立ち絵）に戻すボタン。枠の左上（js/standing-preview.js）。
   初期画像が表示されている間は hidden 属性が付くので表示されない。
   HTML 側で .standing-zoom より後に書かないと押せない（同じ枠の中で重なるため） */
.standing-reset {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(27, 24, 23, 0.82);
  color: var(--ink);
  font-size: 12px;
  letter-spacing: 0.06em;
  cursor: pointer;
}

.standing-reset[hidden] {
  display: none;
}

.standing-reset:hover {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--on-brand);
}

.standing-reset:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* 拡大表示できることの案内（枠の下部中央、角丸の枠で囲む）。
   押下は .standing-zoom に通したいので pointer-events: none にしている
   角を少し丸めるだけの四角い枠にしたい場合は border-radius を 6px にする */
.standing-hint {
  position: absolute;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  margin: 0;
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(27, 24, 23, 0.82);
  color: var(--ink-soft);
  font-size: 12px;
  letter-spacing: 0.06em;
  white-space: nowrap;
  pointer-events: none;
}

/* ===== 立ち絵の拡大表示（ライトボックス） =====
   js/standing-lightbox.js が body 直下に生成する。
   開くときは .lightbox と中の画像に is-open が付いてふわっと現れ、
   閉じるときは外れて消える。切り替え時間は下の transition だけ変えればよい */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 5000; /* ヘッダー(900)より上、年齢確認モーダル(9999)より下 */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(12, 10, 10, 0.9);
  opacity: 0;
  transition: opacity 240ms ease;
}

.lightbox.is-open {
  opacity: 1;
}

/* 枠の中では --img-scale などで切り抜いているが、拡大表示では画像全体を見せる。
   .image-slot の外なので切り抜き用の transform は掛からない（ここで使う transform は演出用） */
.lightbox img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  transform: scale(0.94);
  transition: transform 240ms ease;
}

.lightbox.is-open img {
  transform: scale(1);
}

.lightbox-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: rgba(36, 32, 32, 0.8);
  color: var(--ink);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.lightbox-close:hover {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--on-brand);
}

/* 拡大表示中はページ本体をスクロールさせない */
body.is-lightbox-open {
  overflow: hidden;
}

/* 動きを抑える設定ではフェードも拡大もしない */
@media (prefers-reduced-motion: reduce) {
  .lightbox,
  .lightbox img {
    transition: none;
  }

  .lightbox img {
    transform: none;
  }
}

/* ===== 賞品（サイン入り色紙）のサムネイルと拡大表示 =====
   js/prize-lightbox.js が body 直下に生成するのは .lightbox.prize-lightbox。
   fixed にする・フェードする・×ボタン・Esc で閉じる、は上の立ち絵のライトボックスと
   同じ .lightbox をそのまま使い、画像を収める .lightbox-stage と2枚目の案内だけ足している。
   .lightbox-stage img は .lightbox img と特度が同じなので、この位置（後ろ）に書いて勝たせている。
   上の .image-slot img より後ろに置くのがサムネイル側も同じなので、まとめてここに書いている */

/* 賞品の項目が並ぶグリッド。横幅に応じて3→2→1列に自然に積まれる。
   .campaign-rules ul / li に上書きされないよう .campaign-rules を付けている */
.prize-lead {
  margin: 0 0 12px;
  font-size: 13px;
  color: var(--ink-soft);
}

.campaign-rules .prize-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
  max-width: 760px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.campaign-rules .prize-card {
  margin: 0;
  min-width: 0;
}

/* 色紙写真の枠。正方形で、.prize-zoom と .prize-count を重ねる基準にもなる。
   .image-slot を一緒に付けているので、<img> が入ると破線は自動で実線に切り替わる */
.prize-photo {
  position: relative;
  aspect-ratio: 1 / 1;
}

.prize-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* サムネイル枠全体を覆う透過ボタン（js/prize-lightbox.js）。
   中身の文字は使わず aria-label で名前を付ける */
.prize-zoom {
  position: absolute;
  inset: 0;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  cursor: zoom-in;
  font-size: 0;
  color: transparent;
}

.prize-zoom:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: -3px;
}

.prize-card:hover .prize-photo {
  border-color: var(--brand);
}

/* 2枚ある賞品のしるし（サムネイル右上）。
   押下は下の .prize-zoom に通したいので pointer-events: none にしている */
.prize-count {
  position: absolute;
  top: 8px;
  right: 8px;
  padding: 3px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(27, 24, 23, 0.82);
  color: var(--ink);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  pointer-events: none;
}

/* 写真の下に置くキャラクター名と声優名 */
.prize-caption {
  display: block;
  margin-top: 8px;
  line-height: 1.6;
}

.prize-role {
  display: block;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}

.prize-actor {
  display: block;
  font-size: 13px;
  font-weight: 700;
}

/* 賞品の拡大表示は ×ボタン（画面上端 14px + 40px）と画像の右上が重ならない分だけ上をあける。
   .lightbox-stage は画像ぴったりまでのサイズになるので、中の案内は画像の角に張られる */
.prize-lightbox {
  padding: 64px 24px 24px;
}

.lightbox-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 2枚ある時だけ js が is-multi を付ける（画像の上が押せることをカーソルで示す） */
.lightbox-stage.is-multi {
  cursor: pointer;
}

/* 画面いっぱいまで。実寸（735px）より大きくは引き伸ばさない。
   2枚目の切り替えは opacity だけ。transform は現れる時の演出用（上の .lightbox と同じ） */
.lightbox-stage img {
  max-width: calc(100vw - 48px);
  max-height: calc(100vh - 88px);
  transition: opacity 160ms ease, transform 240ms ease;
}

.lightbox-stage img.is-switching {
  opacity: 0;
}

/* 拡大画像の右上に出す案内（2枚ある時だけ js が付ける） */
.lightbox-hint {
  position: absolute;
  top: 10px;
  right: 10px;
  max-width: calc(100% - 20px);
  margin: 0;
  padding: 6px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(27, 24, 23, 0.86);
  color: var(--ink);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.5;
  text-align: center;
}

/* 今どちらを見ているか（拡大画像の左上） */
.lightbox-counter {
  position: absolute;
  top: 10px;
  left: 10px;
  margin: 0;
  padding: 4px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(27, 24, 23, 0.86);
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
}

/* 動きを抑える設定ではフェードしない（JS 側も即時差し替えに切り替わる） */
@media (prefers-reduced-motion: reduce) {
  .lightbox-stage img {
    transition: none;
  }
}

.image-slot-label {
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
}

/* 立ち絵用の縦長枠（背景透過PNGを想定）
   デスクトップでは右カラムの高さに合わせて伸びる。
   position: relative は中の img を absolute で貼るための基準 */
.character-standing {
  flex: 1;
  position: relative;
}

/* ===== コスチューム選択（縦2 x 横2） ===== */
.costume-field {
  grid-column: 2;
  grid-row: 2;
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

/* コスチューム選択の見出し（右カラムの真上・中央寄せ）
   fieldset の legend は読み上げ用のみ */
.costume-hint {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
}

.costume-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.costume-option {
  display: block;
  min-width: 0;
  cursor: pointer;
}

.costume-thumb {
  aspect-ratio: 1 / 1;
}

/* 画像枠の下に置くラジオボタン + コスチューム名 */
.costume-select {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  padding: 8px 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
}

.costume-select input {
  flex: none;
  width: 18px;
  height: 18px;
  accent-color: var(--brand);
}

.costume-name {
  font-size: 13px;
  font-weight: 700;
}

.costume-option:hover .costume-select,
.costume-option:hover .costume-thumb {
  border-color: var(--brand);
}

/* 選択中の枠を強調する（:has() 非対応環境ではラジオボタン自体で判別できる） */
.costume-option:has(input:checked) .costume-select {
  background: var(--brand-bg);
  border-color: var(--brand);
}

.costume-option:has(input:checked) .costume-thumb {
  border-color: var(--brand);
}

.costume-option:has(input:focus-visible) .costume-select {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
}

/* ===== 投票ボタンと結果メッセージ ===== */
.character-actions {
  margin: 22px 0 0;
  text-align: center;
}

.character-feedback {
  margin: 12px 0 0;
  white-space: pre-line;
  font-size: 13px;
  text-align: center;
  color: var(--ink);
}

.character-feedback:empty {
  display: none;
}

.character-feedback.is-error {
  color: var(--brand);
  font-weight: 700;
}

/* ===== フッター ===== */
.site-footer {
  margin-top: 40px;
  padding: 36px 20px 28px;
  background: var(--panel);
  border-top: 6px solid var(--brand);
}

.footer-inner {
  max-width: var(--max-width);
  margin: 0 auto;
  text-align: center;
}

.footer-logo {
  display: inline-block;
}

/* Triangle ロゴ（193x98 の透過画像）。ダーク背景でも白とブランド色が判読できる */
.footer-logo img {
  width: 140px;
  height: auto;
}

.footer-nav ul,
.footer-social {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px;
  margin: 16px 0;
  padding: 0;
  list-style: none;
  font-size: 13px;
}

.footer-nav a,
.footer-social a {
  color: var(--ink);
  text-decoration: none;
}

.footer-nav a:hover,
.footer-social a:hover {
  color: var(--brand);
}

.age-mark {
  margin: 12px 0 6px;
  font-size: 12px;
  color: var(--ink-soft);
}

.copyright_text {
  margin: 8px 0 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--brand);
}

/* ===== フェードイン（js/main.js が .is-visible を付与） ===== */
.fadein {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.fadein.is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .fadein {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ===== レスポンシブ ===== */
@media (max-width: 820px) {
  .hero {
    padding: 20px 14px 28px;
  }

  .brand-title {
    font-size: 18px;
  }

  /* ヘッダーナビは5項目（トップ / 商品紹介 / ユーザー投票 / 受注申込 / 製品情報）。
     sticky ヘッダーなので、モバイルではパディングと文字サイズを詰めて高さを抑える */
  .global-nav ul {
    gap: 2px;
  }

  .global-nav a {
    padding: 7px 9px;
    font-size: 13px;
  }

  .section-title {
    font-size: 19px;
  }

  .spec-table th {
    width: 38%;
  }

  /* キャラクター枠は縦積みに（見出し → 立ち絵 → コスチューム選択） */
  .character-body {
    grid-template-columns: minmax(0, 1fr);
  }

  /* デスクトップ用の明示的な列指定を解除して、文書順に積み直す */
  .costume-hint,
  .character-visual,
  .costume-field {
    grid-column: auto;
    grid-row: auto;
  }

  /* 1列の場合は右カラムの高さに依存できないので、枠自身に比率を持たせる。
     横幅は下のコスチューム選択グリッドと同じ幅に揃える */
  .character-standing {
    width: 100%;
    aspect-ratio: 3 / 4;
  }

  .character-card {
    padding: 14px;
  }

  /* 抱き枕の絵柄はキャラクターごとに1列へ積む。
     フレームの中の表面/裏面は2列のまま（上下に積むと1キャラクターぶんが長すぎる） */
  .design-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .design-card {
    padding: 14px;
  }

  .campaign-period-dates {
    font-size: 15px;
  }
}


