/* ヒーロー演出
   元は sw-staging.net のフルスクリーン404ページ。
   スクロールに応じて「画像が縮んで暗くなり、白地の上にロゴが描かれていく」構成に作り替えてある。

   仕組み：JS は進捗 0→1 を --p に入れるだけ。見た目の補間はすべてここで行う。 */

.hero{
  /* スクロールの舞台。この高さぶんスクロールする間、中の画面が固定される。
     値は style.css の --hero-stage（ヘッダーの切り替えタイミングも同じ値を見ている）。 */
  height:var(--hero-stage, 220vh);
  background:var(--paper, #fff);
  --p:0;                 /* 進捗 0（先頭）→ 1（演出の終わり） */
  /* ロゴの幅。縮小後の画像幅（58vw）より狭くして、左右に余白を残す。 */
  --mark-w:min(480px, 46vw);
}

.hero__pin{
  position:sticky;
  top:var(--admin-bar-h, 0px);
  /* ログイン中は管理バーが文書を押し下げているぶんを引く */
  height:calc(100dvh - var(--admin-bar-doc, 0px));
  overflow:hidden;
  isolation:isolate;   /* difference 合成をヒーロー内に閉じ込める */
}

/* ===== 縮んで暗くなる領域 ===== */
.hero__visual{
  position:absolute;inset:0;
  background:var(--paper-tint, #eaf3f6);
  transform-origin:50% 50%;
  /* 1 → 0.58 まで縮み、少し下へ寄って上に余白を作る */
  transform:scale(calc(1 - 0.42 * var(--p))) translateY(calc(8vh * var(--p)));

  overflow:hidden;
  /* 暗くするのではなく、白地に溶かしていく。
     残すのは 0.3。完全に消すと縮んでいることが読み取れなくなるため。 */
  opacity:calc(1 - 0.7 * var(--p));
  will-change:transform, opacity;
}

.hero__stage{
  position:absolute;inset:0;display:block;width:100%;height:100%;
  opacity:0;transition:opacity 1.1s ease;
}
.hero__stage.on{opacity:1}

/* キャンバスへ転送するためだけの動画。表示はしないが、display:none にすると
   ブラウザによっては再生が止まるので、極小・透明で置いておく。 */
.hero__video{position:absolute;left:0;top:0;width:2px;height:2px;opacity:0;pointer-events:none;z-index:-1}

.hero__vignette{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 100% at 50% 45%,rgba(0,0,0,0) 45%,rgba(0,0,0,.18) 100%);
}

/* ===== 最初に見えているコピー =====
   画像の上に乗るので difference で合成する。地の明暗によらず読める。
   スクロールし始めたら退場する。 */
.hero__tagline{
  position:absolute;left:0;right:0;top:50%;
  margin:0;padding-inline:var(--gap,24px);
  transform:translateY(calc(-50% - 6vh * var(--p)));
  text-align:center;
  pointer-events:none;user-select:none;
  mix-blend-mode:difference;color:#fff;
  /* 幅に対する占有率で決めたいので vmin ではなく vw で刻む。
     実測: 描画幅 ≒ フォントサイズ × 11.4（字送り 0.14em 込み・17文字）。
     6.2vw なら 375px 幅で約 23px → 画面幅の約 70%。
     下限 21px は 320px 幅でも余白に収まる値。 */
  font-family:var(--font-display);
  /* 「Create Different.」（17字）を基準に決めた大きさ。
     長いフレーズはこの値を字数で割って縮める（下の --n を参照）。 */
  --phrase-size:clamp(21px,6.2vw,42px);
  font-size:var(--phrase-size);font-weight:300;line-height:1.5;
  letter-spacing:.14em;text-indent:.14em;
  /* 0 → 0.28 の間で消える */
  opacity:clamp(0, calc(1 - var(--p) / 0.28), 1);
}

/* ===== フレーズの入れ替え =====
   複数のフレーズを同じ場所に重ねて置き、1つずつ見せる。
   grid で重ねるので、いちばん背の高いものに合わせて場所が確保される。 */
.hero__tagline{display:grid;justify-items:center}
.hero__phrase{
  grid-area:1 / 1;
  visibility:hidden;            /* 出ていないものは読み上げ・タブ移動からも外れる */
  /* 幅 ≒ 字数 × 級数。字数で割れば、どのフレーズでもほぼ同じ幅に収まる。
     基準は17字（Create Different.）。下限を切って、極端に長い文でも読める大きさは残す。 */
  font-size:calc(var(--phrase-size) * clamp(.38, calc(17 / var(--n, 17)), 1));
}
.hero__phrase.is-in,
.hero__phrase.is-out,
.hero__phrase.is-shown{visibility:visible}

.hero__phrase .ch{display:inline-block;will-change:transform, opacity}

/* 右から入る。1文字ずつ、左の字から順に。 */
.hero__phrase.is-in .ch{
  animation:phrase-in .62s cubic-bezier(.16,1.1,.3,1) backwards;
  /* 長い文でも送りが伸びすぎないよう、20字目で頭打ちにする */
  animation-delay:calc(min(var(--i, 0), 20) * 30ms);
}
@keyframes phrase-in{
  from{opacity:0;transform:translate3d(.85em, 0, 0)}
  to  {opacity:1;transform:none}
}

/* 左へ抜ける。こちらも左の字から先に消えるので、文がほどけていくように見える。 */
.hero__phrase.is-out .ch{
  animation:phrase-out .48s cubic-bezier(.45,0,.7,0) forwards;
  animation-delay:calc(min(var(--i, 0), 18) * 22ms);
}
@keyframes phrase-out{
  from{opacity:1;transform:none}
  to  {opacity:0;transform:translate3d(-.85em, 0, 0)}
}

/* ===== 少しずつ描かれるロゴ =====
   画像が縮んで空いた上部の白地に置くため、difference は使わずブランド色で塗る。 */
.hero__mark{
  position:absolute;left:50%;
  /* 画像の中心に重ねる。
     画像は中心を軸に縮んだあと、縮んだ座標系の中で translateY されるので、
     実際のずれは (1 - 0.42p) * 8vh * p になる。 */
  top:calc(50% + 8vh * var(--p) * (1 - 0.42 * var(--p)));
  width:var(--mark-w);margin:0;
  /* ロゴの viewBox は下に 33% の余白を持つ（ヘッダーで業種表記と目線を揃えるため）。
     箱の中心ではなく、実際に描かれている部分の中心（34.43%）を接点に合わせる。 */
  transform:translate(-50%, -34.43%);
  z-index:2;
  color:var(--brand,#3D4E64);
  pointer-events:none;user-select:none;
}
.hero__mark svg,.hero__mark img{display:block;width:100%;height:auto}

/* 1文字ずつの描画。JS が各パスに --d（0→1）を入れる。 */
.hero__mark svg > g > path,
.hero__mark svg > path{
  opacity:var(--d,0);
  transform:translateY(calc(14px * (1 - var(--d))));
  transform-box:fill-box;
  transform-origin:50% 100%;
}
/* ラスターロゴでは1文字ずつ描けないので、全体をフェードさせる */
.hero__mark img{opacity:var(--d,0)}

/* ===== スクロールを促す目印 ===== */
.hero__scroll-hint{
  position:absolute;left:50%;bottom:4vh;translate:-50% 0;
  width:1px;height:56px;overflow:hidden;
  mix-blend-mode:difference;
  opacity:clamp(0, calc(1 - var(--p) / 0.2), 1);
}
.hero__scroll-hint span{
  display:block;width:100%;height:40%;background:#fff;
  animation:arianode-hint 2.2s ease-in-out infinite;
}
@keyframes arianode-hint{
  0%   {transform:translateY(-100%)}
  60%  {transform:translateY(250%)}
  100% {transform:translateY(250%)}
}

/* ===== 演出を切っている環境 =====
   スクロールの舞台をやめ、ロゴも最初から出しておく。 */
@media (prefers-reduced-motion: reduce){
  .hero{height:auto}
  .hero__mark{top:50%;transform:translate(-50%,-34.43%)}
  .hero__pin{position:static;height:calc(100dvh - var(--admin-bar-doc, 0px))}
  .hero__visual{transform:none;opacity:1}
  .hero__stage{transition:none}
  .hero__mark svg > g > path,
  .hero__mark svg > path,
  .hero__mark img{opacity:1;transform:none}
  .hero__scroll-hint span{animation:none}
  .hero__phrase .ch{animation:none}
}
