/* =========================================================================
   electric.css — the home page's text motion, and the preload that starts it.

   THE WEIGHTING (boss 2026-07-17: 電流 is for two places only; everything else is a plain
   awwwards-grade reveal, and the page must not end up shouting everywhere). Loudest first:

     ① 電流   [data-hero-title] / [data-electric]   the reference site's color-blink-in.
              ONLY on 「Security Starts at cero.」and 「サーバーに残さないという、…」.
     ② 中     [data-char-rise]                      characters rise + fade, one after another.
              Section headings only — short, hand-broken lines that can carry it.
     ③ 静     [data-rise="text"] / [data-rise="line"]  the block rises + unblurs, once, quietly.
              Eyebrows, body copy, news rows, buttons, and the hero's sub + logo.

   ①  is cloned verbatim from the reference (参考技法ラボ/titan-gate/src/tge_main.css).
   ②③ are cero-side, built on KAGVYA's reveal system (KAGVYA/kagvya-site/style.css) — the same
       opacity + translateY + blur idiom, with its per-type intensities dialled DOWN: KAGVYA's
       loud tiers (large/media: 90px + 22px blur + scale) are deliberately not ported. cero's
       tone is 「静かで洗練」, and the 電流 only reads as an event if nothing else competes.
   ========================================================================= */

:root{
  /* ⚠️🔒 要クライアント確認 — the reference's lightning colour is #8898e7, a FOURTH colour.
     The client's spec is a strict 3 (navy #08153F / white #FFFFFF / lime #CDE02E), so this
     is a 🔒 touch. Kept verbatim by default (boss: 「完璧にそのまま」); flipping the whole
     effect to the brand's lime is this one line — `?lightning=lime` does it live for an A/B. */
  --lightning-color:#8898e7;
  --ease-in-out-power2:cubic-bezier(.645,.045,.355,1);   /* verbatim */
  --ease-out-power2:cubic-bezier(.215,.61,.355,1);       /* verbatim */
  --ease-out-expo:cubic-bezier(.19,1,.22,1);             /* the rise easing */
}
html[data-lightning="lime"]{ --lightning-color:var(--green); }   /* the 3-colour-compliant version */

/* =========================================================================
   preload — one quiet bar, nothing else (boss: 超簡素)
   ========================================================================= */
/* navy = the site's own base, so lifting it is a cut, not a reveal of something else */
.loader{
  position:fixed; inset:0; z-index:100; display:grid; place-items:center;
  background:var(--navy);
}
html:not(.js) .loader{ display:none; }        /* never trap a no-JS reader behind it */
.loader__bar{
  width:min(220px,50vw); height:2px; background:rgba(255,255,255,.14); overflow:hidden;
}
/* scaleX, not width: a width transition runs on the MAIN thread, and this page's main thread is
   busy driving the WebGL background — measured, the bar stalled mid-climb. transform is
   composited, so the fill stays smooth no matter what the background is doing. */
.loader__bar i{
  display:block; width:100%; height:100%; background:var(--lightning-color);
  transform:scaleX(0); transform-origin:0 50%;
  transition:transform .45s var(--ease-out-power2);
}
/* The loader is CUT, not faded — verbatim: 「is-ready 付与 → 黒コンテナ即時 hide（transition無し）」.
   It is the same navy as the site's base, so the cut is seamless; a fade would have left the title
   animating behind a half-transparent overlay. */

/* =========================================================================
   ① 電流 — VERBATIM CLONE. Source rule, unchanged:
       [data-hero-title] .split-word{opacity:0}
       html.is-ready.fonts-loaded [data-hero-title] .split-word{
         animation:color-blink-in .41s var(--ease-in-out-power2) both;
         animation-delay:calc((var(--word) - 1) * 98ms)}

   ★ ZERO MOVEMENT: color-blink-in touches ONLY `color` and `opacity` — no transform anywhere.
     The reference has other text animations that DO move; this is not one of them, and the lab
     already made that mistake once and corrected it. Do not add movement here.
   ★ The gate `html.is-ready.fonts-loaded` IS the reference's own preload handoff.
   ========================================================================= */
[data-hero-title] .split-word{ opacity:0; }

@media (prefers-reduced-motion:no-preference){
  html.is-ready.fonts-loaded [data-hero-title] .split-word{
    animation:color-blink-in .41s var(--ease-in-out-power2) both;
    animation-delay:calc((var(--word) - 1) * 98ms);
  }
}
@media (prefers-reduced-motion:reduce){
  html.is-ready.fonts-loaded [data-hero-title] .split-word{ opacity:1; }
}

@keyframes color-blink-in{
  0%{ color:var(--lightning-color); opacity:0 }
  20%{ opacity:1 }
  35%{ color:var(--lightning-color) }
  55%{ opacity:.6 }
  70%{ color:inherit }
  85%{ opacity:1 }
  to{ opacity:1 }
}

/* cero's 🔒 green dot lives INSIDE the last word ("cero."). The keyframe animates the WORD's
   colour, while .dot keeps its own green — so the dot fades in with the word but never takes
   the lightning colour. That is the spec-correct outcome: the dot is never recoloured. */

/* The second 電流 — 「サーバーに残さないという、…」. Same keyframe, fired per CHARACTER and on
   scroll instead of on preload. Per character because the reference splits on whitespace and
   Japanese has none: as "words" this heading is two lines, i.e. two flashes, not a cascade.
   The characters stay `inline` — color-blink-in only needs colour and opacity, and an
   inline-block per character would hand the line breaker a break opportunity everywhere and
   lose 禁則処理. */
[data-electric]:not(.is-inview) .split-char{ animation:none; animation-delay:0; opacity:0; }
@media (prefers-reduced-motion:no-preference){
  [data-electric].is-inview .split-char{
    animation:color-blink-in .41s var(--ease-in-out-power2) both;
    animation-delay:calc((var(--char) - 1) * 28ms);
  }
}
@media (prefers-reduced-motion:reduce){
  /* must out-specify the :not(.is-inview) rule above (0,3,0), or a reduced-motion reader keeps
     a heading that is invisible until it happens to be observed */
  [data-electric]:not(.is-inview) .split-char,
  [data-electric] .split-char{ opacity:1; animation:none; }
}

/* =========================================================================
   ② 中 — characters rise and fade in, one after another (KAGVYA's .split-char).
   Section headings only. They are short and hand-broken, which matters: this tier needs
   inline-block to move each character, and inline-block per character is what breaks Japanese
   line-breaking. Never put this on a flowing paragraph.
   ========================================================================= */
[data-char-rise] .split-char{
  display:inline-block;
  opacity:0; transform:translateY(.4em);
  transition:opacity .7s var(--ease-out-expo), transform .7s var(--ease-out-expo);
  transition-delay:calc((var(--char) - 1) * var(--char-stride, 16ms));
}
[data-char-rise].is-inview .split-char{ opacity:1; transform:none; }

/* =========================================================================
   ③ 静 — the block rises and unblurs. Once. This is the page's default voice.
   ========================================================================= */
/* scoped to html.js like the site's own .reveal: the hidden state only exists if something can
   un-hide it. (The two tiers above need no guard — their .split-* only exist once JS has run.) */
html.js [data-rise]{
  opacity:.001;
  transform:translateY(var(--rise-y,10px));
  filter:blur(var(--rise-blur,4px));
  transition:opacity .95s var(--ease-out-expo),
             transform .95s var(--ease-out-expo),
             filter .95s var(--ease-out-expo);
  transition-delay:var(--rise-delay,0s);
}
html.js [data-rise].is-inview{ opacity:1; transform:none; filter:blur(0); }
html.js [data-rise="text"]{ --rise-y:20px; --rise-blur:6px; transition-duration:1.1s; }   /* KAGVYA 28/9 → calmer */
html.js [data-rise="line"]{ --rise-y:8px;  --rise-blur:2px; }
/* news rows arrive in order rather than as a slab */
.news-row[data-rise]:nth-child(2){ --rise-delay:.06s; }
.news-row[data-rise]:nth-child(3){ --rise-delay:.12s; }

@media (prefers-reduced-motion:reduce){
  /* must out-specify `html.js [data-rise]` above, or reduced-motion users get a blank page */
  html.js [data-rise], html.js [data-rise].is-inview{ opacity:1; transform:none; filter:none; transition:none; }
  [data-char-rise] .split-char{ opacity:1; transform:none; transition:none; }
}

/* =========================================================================
   HERO — one power-on. Boss: 「電流と同じタイミングで開始＆大体同時に終了」.
   The title's 電流 runs 0 → 704ms (word 4 starts at 3×98ms and lasts .41s). The logo and the
   sub start with it and land at 700ms, so the hero arrives as ONE event.
   Both are ③ 静: the title is the voice here, and the copy under it should not argue with it.
   The logo does not move at all — it is the brand mark, and it sits directly above a title
   whose whole point is that it does not move either.
   ========================================================================= */
html.js body.home .hero__mark,
html.js body.home [data-hero-sub]{ opacity:.001; }
html.js body.home [data-hero-sub]{ transform:translateY(8px); filter:blur(2px); }

@media (prefers-reduced-motion:no-preference){
  html.is-ready.fonts-loaded body.home .hero__mark{
    opacity:1;
    transition:opacity .7s var(--ease-out-expo);
  }
  html.is-ready.fonts-loaded body.home [data-hero-sub]{
    opacity:1; transform:none; filter:blur(0);
    transition:opacity .7s var(--ease-out-expo),
               transform .7s var(--ease-out-expo),
               filter .7s var(--ease-out-expo);
  }
}
@media (prefers-reduced-motion:reduce){
  html.js body.home .hero__mark,
  html.js body.home [data-hero-sub]{ opacity:1; transform:none; filter:none; }
}
