@charset "UTF-8";
/* ============================================================
   月替わり工房シーズン：軽量パーティクル演出
   ------------------------------------------------------------
   ・DOM + CSS transform のみ（Canvas/Three.js は使わない）
   ・全ページ常時表示のため、合成レイヤーだけで動くよう transform/opacity に限定
   ・ガチャ開封演出のページでは PHP 側（WorkshopSeasonService）で描画自体を止めている
   ============================================================ */

.season-particles {
  position: fixed;
  inset: 0;
  /* header(999) / gray-layer(1001) / toggle(1002) の下、コンテンツの上 */
  z-index: 998;
  pointer-events: none;
  overflow: hidden;
  /* 中の要素がページ全体の再レイアウトを誘発しないよう封じ込める。
     size は含めない（inset:0 での高さ決定に size 封じ込めを絡ませないため） */
  contain: layout paint style;
}

.season-particle {
  position: absolute;
  top: -10vh;
  left: var(--x, 50%);
  width: var(--size, 12px);
  height: var(--size, 12px);
  animation: season-fall var(--dur, 14s) linear var(--delay, 0s) infinite;
  will-change: transform;
}

/* 内側で横揺れ＋回転。落下(親)と分けることで両方とも合成のみで済む */
.season-particle > span {
  display: block;
  width: 100%;
  height: 100%;
  opacity: var(--op, 0.85);
  animation: season-sway var(--sway, 5s) ease-in-out var(--delay, 0s) infinite alternate;
  will-change: transform;
}

@keyframes season-fall {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, 120vh, 0); }
}

@keyframes season-rise {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, -120vh, 0); }
}

@keyframes season-sway {
  from { transform: translate3d(-20px, 0, 0) rotate(-45deg); }
  to   { transform: translate3d(20px, 0, 0) rotate(45deg); }
}

/* ------------------------------------------------------------
   種別ごとの見た目（画像素材なし。すべてCSS図形）
   ------------------------------------------------------------ */

/* 紅葉：葉っぱ型（対角の角丸で葉の輪郭を作る） */
.season-particles--leaves .season-particle > span {
  border-radius: 0 100% 0 100%;
  background: #c0431a;
}
.season-particles--leaves .season-particle:nth-child(3n+1) > i { background: #e08b21; }
.season-particles--leaves .season-particle:nth-child(3n+2) > i { background: #9c2f14; }

/* 雪：白い円＋淡い発光 */
.season-particles--snow .season-particle > span {
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 6px rgba(255, 255, 255, 0.9);
}
.season-particles--snow .season-particle > span { opacity: var(--op, 0.75); }

/* 桜：花びら型 */
.season-particles--petals .season-particle > span {
  border-radius: 100% 0 100% 0;
  background: #ffb7c5;
}
.season-particles--petals .season-particle:nth-child(3n+1) > i { background: #ffd0dc; }
.season-particles--petals .season-particle:nth-child(3n+2) > i { background: #f79ab0; }

/* 気泡：下から昇る。中空の円
   位置は落下と同じく vh 基準で置く（bottom だと親ボックスの高さに依存してしまう） */
.season-particles--bubbles .season-particle {
  top: 110vh;
  animation-name: season-rise;
}
.season-particles--bubbles .season-particle > span {
  border-radius: 50%;
  background: radial-gradient(circle at 32% 30%, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.1) 62%);
  /* 白いフチだけだと明るい背景の夏テーマで気泡が消える。
     外側に淡い水色のリングを重ね、暗い背景でも明るい背景でも輪郭が残るようにする */
  border: 1px solid rgba(255, 255, 255, 0.7);
  box-shadow: 0 0 0 1px rgba(13, 90, 125, 0.28), inset 0 0 5px rgba(255, 255, 255, 0.55);
  opacity: var(--op, 0.7);
  /* 気泡は回転させず、横揺れだけにする */
  animation-name: season-sway-soft;
}
@keyframes season-sway-soft {
  from { transform: translate3d(-12px, 0, 0); }
  to   { transform: translate3d(12px, 0, 0); }
}

/* ------------------------------------------------------------
   負荷・アクセシビリティ対策
   ------------------------------------------------------------ */

/* スマホは要素数を約半分に間引く（PHP側の数はPC基準） */
@media only screen and (max-width: 768px) {
  .season-particles .season-particle:nth-child(2n) { display: none; }
}

/* タブが裏に回っている間はアニメーションを止める（バッテリー対策） */
.season-particles.is-paused .season-particle,
.season-particles.is-paused .season-particle > span {
  animation-play-state: paused;
}

/* 視差過敏の設定をしているユーザーには一切動かさない */
@media (prefers-reduced-motion: reduce) {
  .season-particles { display: none; }
}

/* ------------------------------------------------------------
   光の演出（パーティクルとは別レイヤー。併用できる）
   ------------------------------------------------------------ */

/* --- キラキラ（光の粒）--- */
.season-sparkles {
  position: fixed;
  inset: 0;
  z-index: 998;
  pointer-events: none;
  overflow: hidden;
  contain: layout paint style;
}

.season-sparkle {
  position: absolute;
  left: var(--x, 50%);
  top: var(--y, 50%);
  /* にじみの分を見込んで箱を大きめに取り、光は箱の内側で完全に消しきる。
     箱の縁にアルファが残っていると、スマホのGPUではその縁が
     四角い枠として浮いて見えることがある（--size は光の芯の直径として扱う） */
  width: calc(var(--size, 18px) * 1.6);
  height: calc(var(--size, 18px) * 1.6);
  margin: calc(var(--size, 18px) * -0.8) 0 0 calc(var(--size, 18px) * -0.8);
  /* 白い芯 → 金色 → 琥珀色のにじみまで、まとめて1枚のグラデーションで描く。
     真っ白だと明るい背景や白いカードの上で完全に消えるので、太陽の色味を持たせている。
     外周のにじみは以前 filter: drop-shadow() で足していたが、後述の理由で畳んである。
     停止位置は箱の対角基準（farthest-corner ＝ --size*1.13）。
     50% ＝ 中心から --size*0.56 で、箱の半幅 --size*0.8 より内側で 0 になるので
     縁にアルファが残らない。見た目の大きさは drop-shadow 版とほぼ同じ */
  background: radial-gradient(circle,
      rgba(255, 255, 255, 1) 0%,
      rgba(255, 226, 150, 0.85) 16%,
      rgba(255, 198, 92, 0.5) 26%,
      rgba(255, 176, 60, 0.28) 34%,
      rgba(255, 150, 40, 0.12) 41%,
      rgba(255, 150, 40, 0) 50%);
  animation: season-twinkle var(--dur, 3.5s) ease-in-out var(--delay, 0s) infinite;
  will-change: transform, opacity;
}

/* 十字の光条で「キラッ」を作る（画像なし） */
.season-sparkle::before,
.season-sparkle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: linear-gradient(to right, rgba(255, 214, 130, 0) 0%, rgba(255, 255, 255, 1) 50%, rgba(255, 214, 130, 0) 100%);
}
/* 箱を 1.6 倍に広げたぶん、光条の長さは % で絞って元の見た目に合わせる */
.season-sparkle::before {
  width: 75%;
  height: 2px;
  transform: translate(-50%, -50%);
}
.season-sparkle::after {
  width: 2px;
  height: 75%;
  transform: translate(-50%, -50%);
  background: linear-gradient(to bottom, rgba(255, 214, 130, 0) 0%, rgba(255, 255, 255, 1) 50%, rgba(255, 214, 130, 0) 100%);
}

/* 【スマホで四角い縁が見えた件】
   白い背景の上でも輪郭が残るよう、以前はここで
     filter: drop-shadow(0 0 4px ...) drop-shadow(0 0 10px ...)
   を掛けて琥珀色のにじみを外側に回していた。
   ただし drop-shadow は「合成済みレイヤーのアルファ」を種にして影を作るため、
   transform/opacity アニメーションで合成レイヤーに載っているこの粒では、
   端末によってグラデーションの端に残るわずかなアルファ（ディザリングの誤差）まで
   拾ってしまい、粒の周りに四角い枠が浮いて見えることがあった。
   にじみは上の radial-gradient に畳んであるので、ここでは filter を使わない。
   同じ理由で、この粒には box-shadow（四角い箱の形に出る）も付けないこと。 */

/* 光っている時間を長めに取る。ピークだけ一瞬だと、常時ほとんどの粒が
   opacity:0 になり「キラキラしていない」ように見えてしまう */
@keyframes season-twinkle {
  0%       { transform: scale(0.15) rotate(0deg);   opacity: 0; }
  18%      { transform: scale(1) rotate(20deg);     opacity: 1; }
  46%      { transform: scale(0.78) rotate(38deg);  opacity: 0.85; }
  68%      { transform: scale(1) rotate(52deg);     opacity: 1; }
  100%     { transform: scale(0.15) rotate(70deg);  opacity: 0; }
}

/* --- 光条（水面から差し込む光）--- */
.season-sunbeams {
  position: fixed;
  inset: 0;
  /* パーティクルより奥。ただし #wrapper の背景よりは手前に来る */
  z-index: 997;
  pointer-events: none;
  overflow: hidden;
  contain: layout paint style;
}

.season-sunbeam {
  position: absolute;
  top: -30%;
  left: var(--x, 20%);
  width: var(--w, 90px);
  height: 160%;
  /* 左右にぼかした帯。blur() は広い面積だとモバイルで重いので使わない */
  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 248, 225, 0.5) 50%, rgba(255, 255, 255, 0) 100%);
  /* 下にいくほど消える。未対応ブラウザでは帯が下まで届くだけで破綻しない */
  -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 78%);
  mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0) 78%);
  transform: rotate(var(--tilt, 14deg));
  transform-origin: top center;
  opacity: var(--op, 0.5);
  animation: season-beam var(--dur, 9s) ease-in-out var(--delay, 0s) infinite alternate;
  will-change: transform, opacity;
}

@keyframes season-beam {
  from { transform: rotate(calc(var(--tilt, 14deg) - 2deg)) translateX(-14px); opacity: calc(var(--op, 0.5) * 0.55); }
  to   { transform: rotate(calc(var(--tilt, 14deg) + 2deg)) translateX(14px);  opacity: var(--op, 0.5); }
}

/* スマホは光の粒も間引く */
@media only screen and (max-width: 768px) {
  .season-sparkles .season-sparkle:nth-child(2n) { display: none; }
  .season-sunbeam:nth-child(n+4) { display: none; }
}

/* タブ非表示中は止める */
.season-sparkles.is-paused .season-sparkle,
.season-sunbeams.is-paused .season-sunbeam {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  .season-sparkles,
  .season-sunbeams { display: none; }
}

/* ------------------------------------------------------------
   シーズンバナー（トップ最上部・任意）
   ------------------------------------------------------------ */
.season-banner {
  display: block;
  width: 100%;
  margin: 0 0 4px;
  line-height: 0;
}
.season-banner img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 0;
}
