/*!
 * © 2026 Réincarné（レアンカルネ）
 * エアコン室内機の3D。形の数字・見せ方ともに当社が実測・制作したものです。
 * 無断転載・無断利用を禁じます。
 */
/* エアコン室内機の3Dビューア。
 * 分解のようすを見せる画面の、見た目だけをまとめたもの。
 * 動きは assets/js/aircon3d-view.js にある。
 *
 * ⚠ 確認用ページ（_aircon-3d-preview.html）と同じ中身。片方だけ直さないこと
 */

.frame {
  /* アイボリー × チャコール × 控えめなシャンパンゴールド */
  --ink: #2B2926;        /* メイン文字 */
  --ink-70: #575149;     /* サブ文字 */
  --ink-45: #8C8478;     /* さらに薄い文字 */
  --line: #e9e2d8;
  --orange: #f39a01;
  --paper: #F4F1EC;      /* 地 */
  --paper-soft: #F6F2EC;
  --edge: #C8BFB3;       /* ふつうの枠線 */
  /* 差し色はサイトと同じオレンジ。細い線と選択中だけに使う
     （もとはシャンパンゴールド #B89A62 / #9D7C42 / #E4C78F だった） */
  --gold: #f39a01;       /* 細い線・ふち */
  --gold-ink: #cc7f00;   /* ＋− のアイコン */
  --gold-lit: #F5B85A;   /* 濃い地の上に置く文字 */
  --char: #292825;       /* 選択中・押せる地のチャコール */
  --font: "Hiragino Sans", "ヒラギノ角ゴシック", "Hiragino Kaku Gothic ProN",
          "Noto Sans JP", "Yu Gothic Medium", "游ゴシック Medium", Meiryo, sans-serif;
}
.frame *, .frame *::before, .frame *::after { box-sizing: border-box; }
.frame [hidden] { display: none !important; }

/* ------- 3Dの枠 ------- */
.frame {
  padding: 22px; display: flex; justify-content: center;
  font-family: var(--font); color: var(--ink);
}
.frame.is-phone { padding: 22px 0; }

.viewer {
  position: relative; width: 100%; max-width: 1000px; aspect-ratio: 16 / 10;
  border-radius: 18px; overflow: hidden; isolation: isolate;
  background: var(--paper);
  border: 1px solid rgba(80,70,60,.08);
  box-shadow: 0 12px 35px rgba(40,30,20,.08);
  user-select: none; -webkit-user-select: none; touch-action: none;
}
.frame.is-phone .viewer { max-width: 390px; aspect-ratio: 390 / 760; border-radius: 26px; }

/* 背景は、通常の地の上に分解表示の地を重ねて、濃度で切り替える */
.viewer__bg, .viewer__bg--dark { position: absolute; inset: 0; }
.viewer__bg { background: radial-gradient(120% 100% at 50% 18%, var(--paper-soft) 0%, var(--paper) 62%, #EFEBE3 100%); }
.viewer__bg--dark {
  opacity: 0;
  background: radial-gradient(120% 100% at 46% 26%, var(--paper) 0%, var(--paper) 46%, #EDE8DF 100%);
}
.stage { position: absolute; inset: 0; }
.stage canvas { display: block; width: 100%; height: 100%; }

/* にじむ光。線だけを描いた面をぼかして、下の絵に重ねる */
.bloom {
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: none; pointer-events: none;
  mix-blend-mode: screen;
  filter: blur(6px);
  opacity: .95;
}
.bloom.is-on { display: block; }

/* ------- 外れた部品の印 ------- */
.marks { position: absolute; inset: 0; pointer-events: none; }
.mark {
  position: absolute; transform: translate(8px, -50%);
  display: flex; align-items: center;
  padding: 0; border: 0; background: none; cursor: pointer; pointer-events: none;
  font: inherit; color: var(--ink); white-space: nowrap;
  opacity: 0; transition: opacity .5s ease;
}
.mark.is-in { opacity: 1; pointer-events: auto; }
/* 右のふちに近い印は、名前を左側に出す */
.mark.is-left { transform: translate(calc(-100% - 8px), -50%); }
.mark__t {
  font-size: 12px; letter-spacing: .04em; padding: 4px 11px; border-radius: 999px;
  background: rgba(244, 241, 236, .9); border: 1px solid var(--gold); color: #403A32;
}
.mark:hover .mark__t, .mark:focus-visible .mark__t { background: var(--paper); }
/* 外れない場合がある部品の札。枠はほかと同じで、※ だけオレンジにする */
.mark__x { font-style: normal; color: var(--orange); }
/* 札から部品へ下ろす、細い吹き出し線 */
.mark__lead {
  position: absolute; top: 100%; left: 2px; width: 1px; height: 24px;
  background: linear-gradient(180deg, rgba(184,154,98,.8), rgba(184,154,98,.12));
}
.mark.is-left .mark__lead { left: auto; right: 2px; }

/* ------- 画面の上に置くもの ------- */
.hud { position: absolute; inset: 0; pointer-events: none; padding: 16px; display: flex; flex-direction: column; }
.hud > * { pointer-events: auto; }

.courses { display: flex; flex-wrap: wrap; gap: 6px; }
.courses button {
  font: inherit; font-size: 12.5px; line-height: 1; padding: 8px 14px; letter-spacing: .04em;
  border-radius: 999px; border: 1px solid var(--edge);
  background: transparent; color: #37332E; cursor: pointer;
  transition: background .35s ease, color .35s ease, border-color .35s ease;
}
.courses button.is-on { background: var(--char); border-color: var(--gold); color: var(--gold-lit); }

/* 選んでいるコースの料金。ボタンの下に左詰めで1行だけ */
.course-info {
  align-self: flex-start; margin: 11px 0 0 4px;
  display: flex; align-items: center; gap: 11px;
  font-size: 20px; line-height: 1.2; letter-spacing: .02em; color: var(--ink);
}
.course-info small { font-size: 12.5px; color: var(--ink-70); letter-spacing: .04em; }
.course-info i { width: 1px; height: 15px; flex: none; background: var(--gold); }

.hint {
  /* ただの案内なので、**押せないようにする**。
     透明になっても当たり判定が残り、その場所の部品が押せなくなる */
  pointer-events: none;
  margin: auto auto 0; padding: 9px 17px; border-radius: 999px; letter-spacing: .04em;
  font-size: 13px; color: var(--ink-70);
  /* 折るのは「、」のようなところだけ。単語の途中で切らせない */
  word-break: keep-all; text-align: center; max-width: calc(100% - 32px);
  background: rgba(244,241,236,.9); border: 1px solid var(--edge);
  transition: opacity .4s ease;
}

/* 分解が終わったあとに**一度だけ**出す案内。押してほしいので目立たせる。
   濃さ（opacity）は JS が持っているので、ここでは形と影だけ動かす */
.hint--pop {
  /* 画面のど真ん中に出す。下は「取り外す部品」の大きな文字と
     戻すボタンで埋まっていて、重なると読めない */
  position: absolute; left: 50%; top: 50%; margin: 0;
  transform: translate(-50%, -50%);
  font-size: 14px; font-weight: 700; letter-spacing: .03em;
  color: #fff; background: var(--char); border-color: var(--char);
  box-shadow: 0 8px 22px rgba(40, 30, 20, .26);
  animation: hint-pop .45s cubic-bezier(.2, .9, .3, 1.2) both,
             hint-beat 1.7s ease-in-out .45s 3;
}
@keyframes hint-pop {
  from { transform: translate(-50%, calc(-50% + 10px)) scale(.94); }
  to { transform: translate(-50%, -50%); }
}
@keyframes hint-beat {
  0%, 100% { transform: translate(-50%, -50%); }
  50% { transform: translate(-50%, -50%) scale(1.06); }
}

/* アップ・縮小 */
.zoom { position: absolute; right: 16px; top: 16px; display: grid; gap: 6px; }
.zoom button {
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  font: inherit; font-size: 15px; line-height: 1;
  border: 1px solid var(--gold); background: transparent; color: var(--gold-ink);
  transition: background .35s ease, color .35s ease, border-color .35s ease;
}

/* 下のボタン列。分解したあとに出る */
.foot {
  position: absolute; right: 16px; bottom: 16px; left: 16px;
  display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; align-items: center;
  opacity: 0; pointer-events: none; transition: opacity .4s ease;
}
.foot.is-in { opacity: 1; pointer-events: auto; }
.sides { display: flex; gap: 8px; }

/* 「外れない場合がある」の断り */
.note {
  margin: 0 auto 0 0; max-width: 52%;
  font-size: 11.5px; line-height: 1.6; letter-spacing: .04em; color: var(--ink-70);
}
/* 文章のあたまの ※。3Dの印と同じオレンジ */
.note__x { font-style: normal; color: var(--orange); }
.side, .reset {
  font: inherit; font-size: 12.5px; line-height: 1; padding: 9px 17px; border-radius: 999px;
  letter-spacing: .04em; cursor: pointer;
  border: 1px solid var(--gold); background: transparent; color: #403A32;
  transition: background .3s ease, color .3s ease, border-color .3s ease;
}
.reset { background: var(--char); border-color: var(--char); color: var(--paper); }
/* 選ばれた側は、枠が消えて**文字だけ**が上へ飛び出し、大きくなる。下に金の線を引く */
.side { position: relative; overflow: visible; }
.side__t {
  display: inline-block; white-space: nowrap;
  transition: transform .3s cubic-bezier(.22,.7,.25,1), color .3s ease;
}
.side.is-on { background: transparent; border-color: transparent; }
.side.is-on .side__t {
  transform: translateY(-65px) scale(3);
  color: var(--ink);
}
/* 見出しの下に引く、細いアクセントの線 */
.side.is-on::after {
  content: ""; position: absolute; left: 50%; transform: translateX(-50%);
  top: -26px; height: 1px; background: var(--gold);
  width: var(--rule, 120px); /* 文字より少し長く。長さは中身に合わせて出す */
}

/* ------- 汚れの写真を大きく見る ------- */
.lens {
  position: absolute; inset: 0; z-index: 5; overflow: hidden;
  background: rgba(244, 241, 236, .97);
  display: flex; align-items: center; justify-content: center;
  touch-action: none; cursor: grab;
}
.lens.is-drag { cursor: grabbing; }
.lens img {
  max-width: 100%; max-height: 100%; display: block;
  transform-origin: center center;
  user-select: none; -webkit-user-drag: none; pointer-events: none;
}
.lens__x {
  position: absolute; left: 16px; top: 16px;
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  font: inherit; font-size: 15px; line-height: 1;
  border: 1px solid var(--gold); background: transparent; color: var(--gold-ink);
}

/* ------- 部品の説明 ------- */
.panel {
  position: absolute; top: 0; right: 0; bottom: 0; width: 356px;
  background: #fbfaf8; color: var(--ink);
  box-shadow: -18px 0 44px rgba(4,12,22,.30);
  display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform .42s cubic-bezier(.22,.7,.25,1);
}
.panel.is-open { transform: none; }
/* 用意ができるまでは、動きを付けない。
   読み込みの最初は「広い画面」の形（右から出るパネル）で置かれ、
   そのあと「せまい画面」の形（下から出るシート）に切り替わる。
   動きが付いていると、右上から下へ滑るのが見えてしまう */
.viewer:not(.is-ready) .panel { transition: none; }
.panel__head {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 16px 12px; border-bottom: 1px solid var(--line);
}
.panel__name { margin: 0; font-size: 16px; font-weight: 600; letter-spacing: .02em; }
.panel__x {
  margin-left: auto; width: 30px; height: 30px; flex: none; cursor: pointer;
  border: 1px solid var(--line); border-radius: 50%; background: #fff; color: var(--ink-70);
  font-size: 15px; line-height: 1;
}
.panel__body { overflow: auto; padding: 16px; display: grid; gap: 15px; }
/* 項目どうしは細い線で仕切る。見出しは金寄りにして本文と見分ける */
.panel__sec + .panel__sec { border-top: 1px solid var(--line); padding-top: 15px; }
.panel__sec h4 {
  margin: 0 0 8px; font-size: 11.5px; font-weight: 600; letter-spacing: .09em;
  color: var(--gold-ink);
}
/* まだ文章が入っていないところ */
.ph {
  margin: 0; font-size: 13px; line-height: 1.8; color: var(--ink-45);
  border: 1px dashed var(--line); border-radius: 8px; padding: 10px 12px; background: #fff;
}
/* 文章が入ったところ。改行はそのまま行として出す */
.txt { margin: 0; font-size: 13px; line-height: 1.9; color: var(--ink-70); white-space: pre-line; }

.shots { margin: 0; }
.shots__frame {
  position: relative; aspect-ratio: 3 / 2; border-radius: 10px; overflow: hidden;
  border: 1px dashed var(--line); background: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 12.5px; color: var(--ink-45); letter-spacing: .06em;
}
/* 写真が入ったら、枠の破線は外す。押すと大きく見られる */
.shots__frame.has-photo { border: 1px solid var(--line); cursor: zoom-in; }
/* 写真は3:2で用意してもらっているので、切らずにそのまま収める */
.shots__frame img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* ------- スマートフォン ------- */
@media (max-width: 640px) {
  .frame { padding: 0; }
  /* 幅いっぱいに広げる。**高さは縦長の比で決める。**
     親の高さいっぱいに伸ばすと、ページに埋め込んだときに高さが無くて
     つぶれてしまう（.frame--fill を付けた場所だけ伸ばす） */
  .viewer {
    max-width: none; border-radius: 0; aspect-ratio: 3 / 4;
  }
  /* 画面いっぱいで見せる場所（確認用ページ）だけ、親の高さに合わせて伸ばす */
  .frame--fill { flex: 1 1 auto; min-height: 0; }
  .frame--fill .viewer {
    aspect-ratio: auto; flex: 1 1 auto; align-self: stretch;
  }
  .mark__t { font-size: 11.5px; }
}
/* せまい画面では、汚れの写真も**画面いっぱい**に出す。
   ビューアの中だけに出すと、下から出るシート（z-index 200）の裏に隠れてしまう */
.viewer.is-narrow .lens {
  position: fixed; inset: 0; z-index: 300;
}
/* ビューアは isolation: isolate でひとまとまり。中でいくら前に出しても、
   ページ側の要素（ヒーローなど）に負ける。**ビューアごと**前に出す */
.viewer.is-front { z-index: 400; }

/* せまい画面では、**ビューアの外**（画面の下）から出るシートにする。
   position: fixed なので、ビューアの枠に切られない */
.viewer.is-narrow .panel {
  position: fixed; inset: auto 0 0 0; width: auto; max-height: 80vh;
  border-radius: 16px 16px 0 0; transform: translateY(100%);
  box-shadow: 0 -14px 40px rgba(4,12,22,.34);
  z-index: 200;
}
.viewer.is-narrow .panel.is-open { transform: none; }
.viewer.is-narrow .panel__head { padding-top: 18px; }
.viewer.is-narrow .panel__head::before {
  content: ""; position: absolute; top: 7px; left: 50%; transform: translateX(-50%);
  width: 36px; height: 4px; border-radius: 2px; background: var(--line);
}
.viewer.is-narrow .courses button { font-size: 11.5px; padding: 7px 11px; }
/* せまい画面でも1行に収まるよう、少しだけ小さく */
.viewer.is-narrow .course-info { font-size: 17px; gap: 9px; margin-top: 9px; }
.viewer.is-narrow .course-info small { font-size: 11.5px; }
/* せまい画面では、2つのボタンを真ん中に。「組み立てた状態に戻す」はその下の右 */
/* せまい画面では、ボタンを**1行にまとめる**。
   大きな文字とボタン2つで3段になると、3Dの場所がなくなるため */
.viewer.is-narrow .foot {
  flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 6px;
}
/* 大きな文字と下線は、ボタンではなく**枠の真ん中**にそろえる。
   そのために .sides では受け止めない（.foot が受け止める） */
.viewer.is-narrow .sides { position: static; }
/* 2つのボタンが1行に収まるよう、少し小さくする。
   幅は半分ずつにして、左右のつり合いをとる */
.viewer.is-narrow .side,
.viewer.is-narrow .reset { font-size: 11.5px; padding: 8px 10px; }
.viewer.is-narrow .sides,
.viewer.is-narrow .reset { flex: 1 1 0; }
.viewer.is-narrow .side { width: 100%; }
/* せまい画面では、断りは一番下の左に回す（大きな見出しと重ならないように） */
.viewer.is-narrow .note { order: 1; flex: 1 0 100%; max-width: none; margin: 4px 0 0; }
/* せまい画面では、名前の札は出さない。**※ だけ残す**。
   小さい画面では札が3Dに重なって、かえって見えにくいため */
.viewer.is-narrow .mark:not(.is-maybe) { display: none; }
.viewer.is-narrow .mark__t {
  font-size: 0; padding: 3px 8px; /* 名前は消す。中の ※ だけ大きさを戻す */
}
.viewer.is-narrow .mark__x { font-size: 14px; }
/* 飛び出した文字と線は、ボタンの真上ではなく**行の真ん中**に置く（画面からはみ出さないように） */
.viewer.is-narrow .side { position: static; }
.viewer.is-narrow .side.is-on .side__t {
  position: absolute; left: 50%; bottom: 100%;
  transform-origin: center bottom;
  /* 11.5px × 2.6 ＝ 約30px。もとの 12.5px × 3 ＝ 37.5px の2割減 */
  transform: translateX(-50%) translateY(-14px) scale(2.6);
}
.viewer.is-narrow .side.is-on::after {
  left: 50%; top: auto; bottom: calc(100% + 10px);
}
