/* ======================================================================
     HERO SECTION — APPROVED & LOCKED (do not modify without explicit sign-off)
     Covers: hero layout, the D image/backdrop/floor/prism/sweep, the
     mascot (jump/squash/shake), the impact + evolution shout bubbles, the
     rainbow mascot swarm, and all related keyframes/media queries — down
     to the closing marker before "Placeholder-page toast" below.
     WordPress migration: move this entire block, verbatim, into
     assets/css/hero.css and enqueue it only on the front page template.
     ====================================================================== */
  .hero{
    position:relative;
    min-height:100svh;
    display:grid;
    grid-template-columns: 1.1fr 1fr;
    align-items:center;
    padding: calc(var(--pad-y) + 30px) var(--pad-x) var(--pad-y);
    gap:40px;
    background:
      radial-gradient(60% 50% at 82% 40%, var(--mint), transparent 70%),
      var(--paper);
    overflow:hidden;
  }
  .hero h1{
    font-size: clamp(2.6rem, 5.6vw, 4.6rem);
    line-height:1.28;
  }
  .hero h1 .line{ white-space:nowrap; }
  .hero .lead{
    margin-top: clamp(20px,2.4vw,28px);
    font-size: clamp(15px,1.2vw,17px);
    color:#3E4B45;
    max-width:38ch;
  }
  .hero .actions{ margin-top: clamp(34px,4vw,44px); }
  .hero-copy{ max-width:500px; }

  .hero-visual{ position:relative; display:flex; align-items:center; justify-content:center; height:100%; }
  .glass-d-wrap{ position:relative; width:min(50vw, 520px); }

  /* Decorative layers only — entirely separate from the D image itself.
     These are the only animated elements here; the D image never moves.
     Colors are set per-variant via JS (see D_VARIANTS); the values below
     are just the pre-JS / no-JS default (green). */
  .glass-d-backdrop{
    position:absolute; inset:-32%;
    z-index:0;
    background: radial-gradient(closest-side, rgba(33,181,115,.18), rgba(33,181,115,0) 70%);
    filter: blur(20px);
    animation: dBackdropDrift 19s linear infinite;
    pointer-events:none;
  }
  .glass-d-floor{
    position:absolute; left:6%; right:6%; bottom:-8%; height:24%;
    z-index:0;
    background: radial-gradient(ellipse at 35% 50%, rgba(33,181,115,.16), rgba(33,181,115,0) 74%);
    filter: blur(12px);
    animation: dFloorDrift 16s ease-in-out infinite;
    pointer-events:none;
  }
  /* Rainbow-only prism accent: a soft white base (set on backdrop/floor
     above) plus this faint rotating conic spectrum, capped low so it never
     reads as a strong effect. Hidden unless the rainbow variant is active. */
  .glass-d-prism{
    position:absolute; inset:-32%;
    z-index:0;
    display:none;
    background: conic-gradient(from 0deg,
      rgba(255,80,80,.12), rgba(255,190,80,.12), rgba(255,240,110,.12),
      rgba(120,220,150,.12), rgba(110,180,255,.12), rgba(180,130,255,.12),
      rgba(255,80,80,.12));
    filter: blur(22px);
    animation: dBackdropDrift 19s linear infinite reverse;
    pointer-events:none;
  }
  .glass-d-wrap.is-rainbow .glass-d-prism{ display:block; }
  .glass-d-prism.is-flashing{ animation: dBackdropDrift 19s linear infinite reverse, prismFlash .5s ease; }
  @keyframes prismFlash{
    0%{ filter: blur(22px) brightness(1); }
    40%{ filter: blur(13px) brightness(1.6); }
    100%{ filter: blur(22px) brightness(1); }
  }

  /* ---------- Gold -> Rainbow evolution cutscene ----------
     A temporary "ghost" clone of the gold D plays the exit (jump up,
     360deg spin, fade out). The real .glass-d element (already swapped to
     the rainbow src underneath) plays the entrance (fades in from below,
     settles into its normal — unchanged — position). */
  .glass-d-evolve-ghost{
    position:absolute; inset:0; z-index:4;
    width:100%; pointer-events:none;
  }
  .glass-d-evolve-ghost.is-exiting{
    animation: evolveGoldExit .8s cubic-bezier(.45,0,.2,1) forwards;
  }
  @keyframes evolveGoldExit{
    0%{ transform: translateY(0) rotate(0deg); opacity:1; }
    100%{ transform: translateY(-85%) rotate(360deg); opacity:0; }
  }
  .glass-d.is-entering{
    animation: evolveRainbowEnter .7s cubic-bezier(.2,.75,.3,1) forwards;
  }
  @keyframes evolveRainbowEnter{
    0%{ transform: translateY(70%); opacity:0; }
    100%{ transform: translateY(0); opacity:1; }
  }

  /* ---------- Rainbow mascot burst ---------- */
  .mascot-burst-layer{ position:absolute; inset:0; z-index:6; pointer-events:none; overflow:visible; }
  .mascot-burst-item{
    position:absolute;
    width:clamp(34px, 5.6vw, 60px);
    transform: translate(-50%,-50%) scale(.2);
    opacity:0;
    pointer-events:none;
    will-change: transform, opacity;
  }
  .mascot-burst-item img{ display:block; width:100%; height:auto; }
  .mascot-burst-item__label{
    position:absolute;
    left:50%; top:-13px;
    transform:translateX(-50%);
    background:#fff;
    color:#15201B;
    font-family:var(--sans);
    font-weight:700;
    font-size:9px;
    line-height:1;
    padding:3px 6px;
    border-radius:999px;
    white-space:nowrap;
    box-shadow:0 2px 5px rgba(0,0,0,.18);
  }
  .mascot-burst-layer.is-bursting .mascot-burst-item{
    animation-name: mascotBurstOut;
    animation-timing-function: cubic-bezier(.2,.7,.3,1);
    animation-fill-mode: forwards;
  }
  @keyframes mascotBurstOut{
    0%{ transform: translate(-50%,-50%) scale(.2); opacity:0; }
    18%{ opacity:1; }
    72%{ transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1); opacity:1; }
    100%{ transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1.08); opacity:0; }
  }

  @keyframes dBackdropDrift{
    0%{ transform: rotate(0deg) scale(1); }
    50%{ transform: rotate(180deg) scale(1.06); }
    100%{ transform: rotate(360deg) scale(1); }
  }
  @keyframes dFloorDrift{
    0%,100%{ transform: translateX(-4%) scaleX(1); opacity:.85; }
    50%{ transform: translateX(4%) scaleX(1.05); opacity:1; }
  }

  /* The D image: fixed in place, no transform/animation of any kind.
     Starts invisible and fades in once the correct colour variant has
     finished loading, so switching colours never flashes the wrong one.
     If JS never runs, <noscript> CSS keeps it shown (default = green). */
  .glass-d{
    position:relative; width:100%; z-index:1;
    filter: drop-shadow(0 30px 40px rgba(15,143,88,.14));
    opacity:0;
    transition: opacity .25s ease;
  }
  .glass-d.is-ready{ opacity:1; }

  @media (prefers-reduced-motion: reduce){
    .glass-d-backdrop, .glass-d-floor, .glass-d-prism{ animation:none !important; }
  }

  /* Character sits inside the D's own wrapper, anchored to its bottom-right
     corner with a slight overlap — so D and character read as one visual,
     not two separately-placed elements. Sized well under 1/3 of D's width. */
  /* Wrapper anchors the mascot to the D's bottom-right corner (with a
     slight overlap). The <img> itself can't have rendered children, so
     the shout bubble is appended to this wrapper instead, positioned to
     sit near the mascot's head. */
  .mascot-anchor{
    position:absolute;
    right: -6%;
    bottom: 0%;
    width: min(28%, var(--mascot-native-w));
    z-index:3;
  }
  .mascot{
    display:block;
    width:100%;
    height:auto;
    filter: drop-shadow(0 14px 18px rgba(21,32,27,.18));
    cursor:pointer;
    transition: transform .4s var(--ease);
  }
  .mascot:hover{ transform: rotate(-6deg) scale(1.06); }
  .js-mascot-hit{ cursor:pointer; transition: transform .07s ease-out; }
  .js-mascot-hit.is-pressed{ transform: scale(.95) translateY(2px); }

  /* Jump: starts at +50ms (JS-timed), peaks toward D around impact
     (~180-200ms from click), lands back at ~450-480ms. Moves toward D
     (mascot sits at the D's lower-right, so "toward D" = leftward). */
  .js-mascot-hit.is-jumping{
    animation: mascotJumpV2 .4s cubic-bezier(.3,1.15,.4,1);
    transition:none;
  }
  @keyframes mascotJumpV2{
    0%{ transform: translate(0,0) rotate(0deg); }
    38%{ transform: translate(-8px,-27px) rotate(-8deg); }
    100%{ transform: translate(0,0) rotate(0deg); }
  }

  .glass-d.is-shaking{ animation: dMicroShake .35s ease; }
  @keyframes dMicroShake{
    0%,100%{ transform: translateX(0) rotate(0deg); }
    20%{ transform: translateX(-3px) rotate(-.6deg); }
    40%{ transform: translateX(3px) rotate(.6deg); }
    60%{ transform: translateX(-2px) rotate(-.4deg); }
    80%{ transform: translateX(2px) rotate(.4deg); }
  }

  /* ---------- Impact shout (hero mascot only) ----------
     Two sizes: a small "ダッ" for ordinary hits, and a larger
     "ダスラー！" for the hit that triggers evolution.

     Structure: .mascot-shout (outer, black, clipped to the starburst) >
     .mascot-shout__bg (yellow, clipped to the same starburst, inset — this
     is the decorative "border" layer only) + .mascot-shout__inner (the
     text — deliberately NOT clip-path'd, so it can never be cut off by the
     jagged shape; it's sized to stay within the starburst's inner "waist"
     so it never visually overlaps the points either). */
  .mascot-shout{
    position:absolute;
    top:-30px; left:-4px;
    width:72px; height:72px;
    background:#111111;
    clip-path: polygon(50.0% 0.0%, 58.0% 14.9%, 71.7% 5.0%, 72.4% 21.9%, 89.1% 18.8%, 82.4% 34.4%, 98.7% 38.9%, 86.0% 50.0%, 98.7% 61.1%, 82.4% 65.6%, 89.1% 81.2%, 72.4% 78.1%, 71.7% 95.0%, 58.0% 85.1%, 50.0% 100.0%, 42.0% 85.1%, 28.3% 95.0%, 27.6% 78.1%, 10.9% 81.2%, 17.6% 65.6%, 1.3% 61.1%, 14.0% 50.0%, 1.3% 38.9%, 17.6% 34.4%, 10.9% 18.8%, 27.6% 21.9%, 28.3% 5.0%, 42.0% 14.9%);
    display:flex; align-items:center; justify-content:center;
    pointer-events:none;
    z-index:7;
    opacity:0;
    transform: scale(.3);
    transform-origin:center;
    filter: drop-shadow(1.5px 2.5px 2px rgba(0,0,0,.35));
    overflow:visible;
  }
  .mascot-shout__bg{
    position:absolute;
    inset:5px;
    background:#FFD83D;
    clip-path: polygon(50.0% 0.0%, 58.0% 14.9%, 71.7% 5.0%, 72.4% 21.9%, 89.1% 18.8%, 82.4% 34.4%, 98.7% 38.9%, 86.0% 50.0%, 98.7% 61.1%, 82.4% 65.6%, 89.1% 81.2%, 72.4% 78.1%, 71.7% 95.0%, 58.0% 85.1%, 50.0% 100.0%, 42.0% 85.1%, 28.3% 95.0%, 27.6% 78.1%, 10.9% 81.2%, 17.6% 65.6%, 1.3% 61.1%, 14.0% 50.0%, 1.3% 38.9%, 17.6% 34.4%, 10.9% 18.8%, 27.6% 21.9%, 28.3% 5.0%, 42.0% 14.9%);
    z-index:0;
  }
  .mascot-shout__inner{
    position:relative;
    z-index:1;
    width:66%; height:66%;
    display:flex; align-items:center; justify-content:center;
    color:#111111;
    font-family: var(--sans);
    font-weight:700;
    font-size:17px;
    line-height:1;
    text-align:center;
    white-space:pre-line;
    overflow:visible;
  }
  /* Evolution variant: larger box reserved for the evolution message
     (currently "ダスラー！"). Box size intentionally unchanged even
     though the text is shorter now — do not resize without instruction. */
  .mascot-shout.is-evolution{
    width:144px; height:88px;
    top:-46px; left:-58px;
  }
  .mascot-shout.is-evolution .mascot-shout__inner{
    width:70%; height:74%;
    font-size:13px;
    line-height:1.3;
    white-space:pre-line;
  }
  @media (max-width:600px){
    .mascot-shout{ width:58px; height:58px; top:-25px; left:-5px; }
    .mascot-shout__inner{ font-size:13px; }
    .mascot-shout.is-evolution{ width:120px; height:74px; top:-38px; left:-45px; }
    .mascot-shout.is-evolution .mascot-shout__inner{ width:70%; height:74%; font-size:11px; line-height:1.3; }
  }
  .mascot-shout.is-active{
    animation: mascotShoutPop .43s cubic-bezier(.22,.85,.3,1) forwards;
  }
  .mascot-shout.is-evolution.is-active{
    animation: mascotShoutPop .95s cubic-bezier(.22,.85,.3,1) forwards;
  }
  @keyframes mascotShoutPop{
    0%{ transform: scale(.3) translateY(0); opacity:0; }
    17%{ transform: scale(1.1) translateY(0); opacity:1; }
    30%{ transform: scale(1) translateY(0); opacity:1; }
    78%{ transform: scale(1) translateY(0); opacity:1; }
    100%{ transform: scale(1) translateY(-7px); opacity:0; }
  }

  @media (prefers-reduced-motion: reduce){
    .js-mascot-hit.is-jumping, .glass-d.is-shaking, .glass-d-prism.is-flashing, .glass-d-evolve-ghost.is-exiting, .glass-d.is-entering, .mascot-burst-layer.is-bursting .mascot-burst-item{ animation:none !important; }
    .mascot-shout.is-active{ animation: mascotShoutFadeOnly .3s ease forwards; }
  }
  @keyframes mascotShoutFadeOnly{
    0%{ opacity:0; transform:scale(1); }
    15%{ opacity:1; }
    75%{ opacity:1; }
    100%{ opacity:0; transform:scale(1); }
  }

  .scroll-cue{
    position:absolute; left:var(--pad-x); bottom:36px;
    display:flex; align-items:center; gap:12px;
    font-family:var(--mono); font-size:11px; letter-spacing:.22em; color:var(--steel);
  }
  .scroll-cue .line{ width:1px; height:36px; background:linear-gradient(var(--green), transparent); animation:scrollLine 2.2s var(--ease) infinite; }
  @keyframes scrollLine{ 0%{transform:scaleY(0);transform-origin:top;} 50%{transform:scaleY(1);transform-origin:top;} 50.1%{transform-origin:bottom;} 100%{transform:scaleY(0);transform-origin:bottom;} }

  @media (max-width:900px){
    .hero{ grid-template-columns:1fr; padding-top:140px; }
    .hero-d-anchor{ order:-1; }
    .hero-visual{ height:auto; padding:20px 0 40px; }
  }

  @media (min-width:901px){
    /* Desktop: D is centered on the hero — it's the main visual, not a
       side element. hero-d-anchor (unlike hero-visual/glass-d-wrap) has no
       transform of its own, so it reliably uses .hero as its containing
       block for this percentage. The D image itself is never animated —
       only this static placement.
       top is offset by half the fixed header's height so D's vertical
       centre accounts for the header instead of the raw viewport — this
       keeps it clear of the nav even on short/laptop-height windows. */
    .hero-d-anchor{
      position:absolute;
      top: calc(50% + var(--nav-h) / 2);
      left:50%;
      transform: translate(-50%, -50%);
      width:min(47vw, 485px);
    }
    .hero-visual{ height:auto; }

    /* Headline stays clear of the centred D with a 30-40px margin. Two
       stages only: a compact one for narrower desktop widths (less room
       beside D), and a full-size one from 1280px up where there's space
       for a proper hero headline. Never wraps beyond 2 lines
       (.hero h1 .line{white-space:nowrap}). */
    .hero h1{ font-size: clamp(1.15rem, 2vw, 2.26rem); }
  }
  @media (min-width:1280px){
    .hero h1{ font-size: clamp(2.2rem, 2.8vw, 4.4rem); }
  }
  /* ====================== END HERO SECTION (CSS) ====================== */
