/* Shared flowing-edge hat scene with a diffuse inward spill and a clean reveal. */
.homepage { --home-content-max-width: 1180px; --home-content-padding: 28px; --home-carousel-inset: 48px; }
.home-worlds { max-width: var(--home-content-max-width); padding-inline: var(--home-content-padding); }
.homepage main { padding-top: 0; }
#homeHero {
 --home-scene-play-state: paused;
 --home-subtitle-space: clamp(64px, 6vw, 80px);
 --svg-hat-top: calc(clamp(216px, 18vw, 240px) + var(--home-subtitle-space));
 --svg-hat-width: clamp(374px, 50vw, 600px);
 --svg-panel-height: calc(var(--svg-hat-top) + var(--svg-hat-width) * .56);
 --svg-composition-height: var(--svg-panel-height);
 position: relative;
 isolation: isolate;
 height: var(--svg-panel-height);
 min-height: 0;
 padding: 0;
 overflow: clip;
  /* Mirror the ambient palette across the scene. The uneven intensity within
     each form keeps the result atmospheric rather than uniformly lit. */
  background:
    radial-gradient(ellipse 42% 85% at 18% -8%, rgba(var(--accent-1-rgb), .2), transparent 100%),
    radial-gradient(ellipse 42% 85% at 82% -8%, rgba(var(--accent-1-rgb), .17), transparent 100%),
    radial-gradient(ellipse 36% 60% at 14% 98%, rgba(var(--accent-3-rgb), .055), transparent 100%),
    radial-gradient(ellipse 36% 60% at 86% 98%, rgba(var(--accent-3-rgb), .047), transparent 100%),
    #09080d;
}
#homeHero[data-motion="running"] { --home-scene-play-state: running; }
/* Scroll lock spans opening, open and closing. Pause the existing timelines
   beneath the menu's blur, then resume in place once the drawer is fully closed. */
body.homepage.drawer-scroll-locked #homeHero { --home-scene-play-state: paused; }
.home-scene-composition { position: relative; width: 100%; height: var(--svg-composition-height); }
.svg-light-scene {
 position: absolute;
 /* The opaque SVG silhouette naturally conceals the wording as it passes behind. */
 z-index: 2;
 left: 50%;
 top: var(--svg-hat-top);
 width: var(--svg-hat-width);
 aspect-ratio: 860 / 566;
 transform: translateX(-50%);
 pointer-events: none;
}
.svg-light-scene svg { display: block; position: absolute; width: 100%; height: 100%; inset: 0; overflow: visible; }
.inner-hat-base { z-index: 0; }
/* An opaque, continuous surface takes over at full reveal. Painting above the
   wide edge profile removes its dark inner block, not merely brightens it. */
.edge-light-wash {
 position: absolute;
 inset: -10%;
 z-index: 2;
 /* Give the brim its own soft reflection and curve the crown's lower shadow.
    The opaque violet base keeps the full surface lit beneath the moving sheen. */
 background:
  radial-gradient(ellipse 52% 11% at 39% 69%,
   rgb(var(--hat-rgb-d5afff, 213 175 255) / .38),
   rgb(var(--hat-rgb-b93eff, 185 62 255) / .22) 38%,
   rgb(var(--hat-rgb-b93eff, 185 62 255) / 0) 94%),
  radial-gradient(ellipse 52% 19% at 64% 59%,
   rgb(var(--hat-rgb-250750, 37 7 80) / .76),
   rgb(var(--hat-rgb-250750, 37 7 80) / .36) 42%,
   rgb(var(--hat-rgb-250750, 37 7 80) / 0) 96%),
  radial-gradient(ellipse 23% 55% at 87% 37%,
   rgb(var(--hat-rgb-b93eff, 185 62 255) / .36),
   rgb(var(--hat-rgb-b93eff, 185 62 255) / 0) 92%),
  linear-gradient(142deg,
   color-mix(in srgb, var(--hat-colour-8b1ef0, #8b1ef0) 25%, var(--hat-colour-250750, #250750)) 0%,
   color-mix(in srgb, var(--hat-colour-8b1ef0, #8b1ef0) 76%, var(--hat-colour-410985, #410985)) 30%,
   var(--hat-colour-410985, #410985) 65%,
   var(--hat-colour-250750, #250750) 100%);
 -webkit-mask-image: var(--edge-surface-mask);
 mask-image: var(--edge-surface-mask);
 -webkit-mask-size: 100% 100%;
 mask-size: 100% 100%;
 -webkit-mask-repeat: no-repeat;
 mask-repeat: no-repeat;
 opacity: 0;
 animation: hat-surface-exposure var(--hat-cycle-duration) linear infinite;
 animation-play-state: var(--home-scene-play-state, paused);
}
/* One broad reflection rolls across the crown while the surface is exposed.
   Padded paint stays beneath the existing silhouette mask and shares its fade. */
.edge-light-wash::before {
 content: "";
 position: absolute;
 inset: -25%;
 background: radial-gradient(ellipse 18% 38% at 40% 26%,
  rgb(var(--hat-rgb-d5afff, 213 175 255) / .8) 0%,
  rgb(var(--hat-rgb-d5afff, 213 175 255) / .4) 34%,
  rgb(var(--hat-rgb-b856ff, 184 86 255) / .22) 62%,
  rgb(var(--hat-rgb-b856ff, 184 86 255) / 0) 100%);
 transform: translate3d(-6%, 0, 0);
 animation: hat-surface-sheen var(--hat-cycle-duration) linear infinite;
 animation-play-state: var(--home-scene-play-state, paused);
}
/* A tiny static grain softens the colour sweeps. It is painted once and fades
   with the surface: no new animation, filter updates or per-frame work. */
.edge-light-wash::after {
 content: "";
 position: absolute;
 inset: 0;
 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='192' height='192'%3E%3Cfilter id='grain'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Cpath d='M0 0h192v192H0z' filter='url%28%23grain%29'/%3E%3C/svg%3E");
 opacity: .085;
 mix-blend-mode: soft-light;
}
/* The exact hat mask is stationary. Soft elliptical light pools translate
   through it; there are no angular gradients or rotating centre points. */
.edge-light-envelope {
 position: absolute;
 inset: -10%;
 z-index: 1;
 overflow: hidden;
 background: none;
 -webkit-mask-image: var(--edge-light-mask);
 mask-image: var(--edge-light-mask);
 -webkit-mask-size: 100% 100%;
 mask-size: 100% 100%;
 -webkit-mask-repeat: no-repeat;
 mask-repeat: no-repeat;
}
.edge-light-pool {
 --light-adjust-x: 0%;
 --light-adjust-y: 0%;
 --swell-small: 1;
 --swell-large: 1;
 --light-min-opacity: 1;
 position: absolute;
 left: -10%;
 top: -10%;
 width: 120%;
 height: 120%;
 opacity: 0;
 animation: hat-light-drift var(--hat-cycle-duration) linear infinite;
 animation-play-state: var(--home-scene-play-state, paused);
 transform: translate3d(0, -32.5%, 0);
}
.edge-light-violet, .edge-light-crown-sweep {
 background: radial-gradient(ellipse 34% 43% at 50% 50%,
  var(--hat-colour-f0dfff, #f0dfff) 0%,
  var(--hat-colour-d5afff, #d5afff) 20%,
  var(--hat-colour-b856ff, #b856ff) 38%,
  rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .85) 64%,
  rgb(var(--hat-rgb-250750, 37 7 80) / 0) 100%);
}
/* An extra localised sweep follows the crown during the middle of the tease.
   It reuses the fine edge mask and shares the scene's pause/reduced-motion rules. */
.edge-light-crown-sweep { animation-name: hat-crown-drift; }
.edge-light-lilac, .edge-light-spill {
 --light-adjust-x: 10%;
 --light-adjust-y: 8%;
 --swell-small: .44;
 --swell-large: 1.85;
 /* Suppress only this pool's compact, orb-like phase. All other lighting,
    the route, and the broad bloom keep their existing appearance and timing. */
 --light-min-opacity: 0;
 transform-origin: 40% 42%;
 /* Its route offset is baked into the shared time map, not a delay: all lights
    accelerate together, preserving the approved pattern at every point. */
 animation-name: hat-bloom-drift;
}
.edge-light-lilac {
 --light-min-opacity: 0;
 /* This uneven pool is edge-only. The centre uses a separate, diffuse exposure
    so shrinking the pool cannot reveal individual light-source discs. */
 background: radial-gradient(ellipse 30% 40% at 40% 42%,
  var(--hat-colour-b93eff, #b93eff) 0%,
  var(--hat-colour-b93eff, #b93eff) 24%,
  var(--hat-colour-8b1ef0, #8b1ef0) 48%,
  rgb(var(--hat-rgb-410985, 65 9 133) / .75) 70%,
  rgb(var(--hat-rgb-250750, 37 7 80) / 0) 100%);
}
/* No permanent colour band. The purple pool can briefly wash across the surface
   when it expands; its quiet phases let both the edge and centre disappear. */
.edge-light-bloom {
 background: none;
 -webkit-mask-image: var(--edge-bloom-mask);
 mask-image: var(--edge-bloom-mask);
}
/* This quiet spill shares the bloom's route and fade, but has no bright core
   and no inner-edge mask. Colour can reach inward from the illuminated side. */
.edge-light-surface {
 -webkit-mask-image: var(--edge-surface-mask);
 mask-image: var(--edge-surface-mask);
}
.edge-light-spill::before {
 content: "";
 position: absolute;
 inset: -50%;
 /* Paint the spill on a padded surface so its tail reaches transparency
    before the surface ends. These halved radii and adjusted centre preserve
    the original glow size and position inside the unchanged moving layer. */
 background: radial-gradient(ellipse 21% 28% at 45% 46%,
  rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .42) 0%,
  rgb(var(--hat-rgb-410985, 65 9 133) / .22) 42%,
  rgb(var(--hat-rgb-250750, 37 7 80) / 0) 100%);
}
/* Keep the delicate highlight above the smooth fill, and the broad ring below. */
.edge-light-highlight { z-index: 3; }
/* All light layers share the same dark opening and timeline on every viewport. */
.edge-light-pool, .edge-light-wash {
 animation-delay: var(--hat-entry-offset, 0s);
 animation-fill-mode: both;
}
/* The panel's bottom fade stays stationary while the hat moves with parallax. */
.home-scene-composition::after {
 content: "";
 position: absolute;
 z-index: 3;
 inset: calc(var(--svg-hat-top) + var(--svg-hat-width) * .38) 0 0;
 background: linear-gradient(180deg, rgb(9 8 13 / 0), rgb(9 8 13 / .32) 36%, rgb(9 8 13 / .88) 78%, #09080d 100%);
 pointer-events: none;
}
/* Generated hat motion is loaded after the initial page paint. */
#homeHero .home-brand-copy {
 position: absolute;
 /* The word is a background plane now: its lower edge disappears behind the
    crown instead of floating in the clear space above it. */
 top: calc(var(--svg-hat-top) - clamp(22px, 2vw, 32px));
 left: 0; right: 0; margin-inline: auto;
 width: min(1240px, 88vw);
 max-width: none;
 transform: translateY(-50%);
 text-align: center;
 z-index: 1;
}
.home-wordmark {
 position: relative;
 isolation: isolate;
 margin: 0;
 white-space: nowrap;
 font: 400 clamp(58px, 14.5vw, 205px)/.86 Bungee, sans-serif;
 letter-spacing: -.018em;
 color: transparent;
 /* The unlit letter colour is independent of the hat palette. Its clipped
    lighting layers still move and reveal over this solid base. */
 background: var(--home-wordmark-base-colour, #250750);
 -webkit-background-clip: text;
 background-clip: text;
 -webkit-text-fill-color: transparent;
 -webkit-text-stroke: 0;
 filter: none;
}
/* Once the font is ready, the word becomes one cached alpha mask. The base and
   every reflection are rectangular paint layers clipped by that parent mask;
   moving them now changes only transform and opacity on the compositor. */
.home-wordmark.home-wordmark-composited {
 -webkit-mask-image: var(--home-wordmark-mask);
 mask-image: var(--home-wordmark-mask);
 -webkit-mask-position: center;
 mask-position: center;
 -webkit-mask-size: 100% 100%;
 mask-size: 100% 100%;
 -webkit-mask-repeat: no-repeat;
 mask-repeat: no-repeat;
 -webkit-background-clip: border-box;
 background-clip: border-box;
 -webkit-text-stroke: 0;
 contain: layout paint style;
 transform: translateZ(0);
 /* Do not blur the whole changing wordmark to draw its barely visible outer
    shadows. Chrome otherwise filters that full surface on every frame.
    The individual light layers retain their smoothing and colour filters. */
 filter: none;
}
.home-wordmark.home-wordmark-composited::before,
.home-wordmark.home-wordmark-composited::after,
.home-wordmark-composited .home-wordmark-light {
 /* Outrank the text-clipped fallback below: zero-size fallback glyphs would
    otherwise hide both the full reveal and the extra crown reflection. */
 content: "";
 -webkit-background-clip: border-box;
 background-clip: border-box;
 font-size: 0;
 will-change: transform, opacity;
 backface-visibility: hidden;
}
/* The full reveal lifts a broad violet refraction through the entire word. It
   borrows the hat surface's exact exposure curve, so it cannot drift out of
   sync with the animation the user already approved. */
.home-wordmark::before,
.home-wordmark::after {
 content: attr(data-wordmark);
 position: absolute;
 inset: 0;
 pointer-events: none;
 color: transparent;
 -webkit-background-clip: text;
 background-clip: text;
 -webkit-text-fill-color: transparent;
 opacity: 0;
 animation-delay: var(--hat-entry-offset, 0s);
 animation-fill-mode: both;
 animation-play-state: var(--home-scene-play-state, paused);
 mix-blend-mode: screen;
 filter: blur(.55px) saturate(1.05);
}
.home-wordmark::before {
 z-index: 1;
 /* Reflect the exposed purple crown into the glass above it. The light is a
    filled arc: brightest nearest the hat, with a smooth upward falloff and
    no dark inner ring. An opaque violet foundation lights even the upper and
    outer facets at full exposure. Only opacity animates, on the hat timeline. */
 background-image:
  radial-gradient(ellipse 46% 110% at 46% 142% in oklab,
   rgb(var(--hat-rgb-d5afff, 213 175 255) / .36) 0%,
   rgb(var(--hat-rgb-d5afff, 213 175 255) / .36) 35%,
   rgb(var(--hat-rgb-b856ff, 184 86 255) / .24) 55%,
   rgb(var(--hat-rgb-b856ff, 184 86 255) / .08) 75%,
   rgb(var(--hat-rgb-b856ff, 184 86 255) / 0) 100%),
  radial-gradient(ellipse 78% 130% at 50% 145% in oklab,
   rgb(var(--hat-rgb-b856ff, 184 86 255) / .92) 0%,
   rgb(var(--hat-rgb-b856ff, 184 86 255) / .92) 35%,
   rgb(var(--hat-rgb-b93eff, 185 62 255) / .85) 48%,
   rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .72) 60%,
   rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .52) 70%,
   rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .3) 80%,
   rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .12) 90%,
   rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .03) 100%,
   rgb(var(--hat-rgb-8b1ef0, 139 30 240) / 0) 112%),
  radial-gradient(ellipse 88% 155% at 50% 150% in oklab,
   rgb(var(--hat-rgb-8b1ef0, 139 30 240) / 1) 0%,
   rgb(var(--hat-rgb-8b1ef0, 139 30 240) / 1) 55%,
   rgb(var(--hat-rgb-410985, 65 9 133) / 1) 75%,
   rgb(var(--hat-rgb-250750, 37 7 80) / 1) 125%);
 filter: blur(.65px) saturate(1.05);
 animation-name: hat-surface-exposure;
 animation-duration: var(--hat-cycle-duration, 59.4992s);
 animation-timing-function: linear;
 animation-iteration-count: infinite;
}
/* The pale and violet pools each get their own clipped glass layer. Their
   generated keyframes illuminate these only while the source is near the
   crown, including passes outside the two dedicated crown sweeps. */
.home-wordmark-light {
 position: absolute;
 inset: 0;
 z-index: 2;
 display: block;
 pointer-events: none;
 color: transparent;
 -webkit-background-clip: text;
 background-clip: text;
 -webkit-text-fill-color: transparent;
 background-repeat: no-repeat;
 opacity: 0;
 animation-duration: var(--hat-cycle-duration, 59.4992s);
 animation-timing-function: linear;
 animation-iteration-count: infinite;
 animation-delay: var(--hat-entry-offset, 0s);
 animation-fill-mode: both;
 animation-play-state: var(--home-scene-play-state, paused);
 mix-blend-mode: screen;
}
.home-wordmark-light-pale {
 background-image: radial-gradient(ellipse 72% 125% at 50% 150% in oklab,
  rgb(255 255 255 / .94) 0%,
  rgb(255 255 255 / .94) 44%,
  rgb(var(--hat-rgb-f0dfff, 240 223 255) / .88) 50%,
  rgb(var(--hat-rgb-d5afff, 213 175 255) / .76) 55%,
  rgb(var(--hat-rgb-b856ff, 184 86 255) / .55) 60%,
  rgb(var(--hat-rgb-b856ff, 184 86 255) / .36) 65%,
  rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .2) 70%,
  rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .08) 76%,
  rgb(var(--hat-rgb-410985, 65 9 133) / 0) 83%);
 background-size: 44% 190%;
 animation-name: home-wordmark-pale-light;
 filter: blur(.8px) saturate(1.05);
}
.home-wordmark-light-bloom {
 background-image: radial-gradient(ellipse 76% 128% at 50% 150% in oklab,
  rgb(var(--hat-rgb-d5afff, 213 175 255) / .68) 0%,
  rgb(var(--hat-rgb-d5afff, 213 175 255) / .68) 42%,
  rgb(var(--hat-rgb-d5afff, 213 175 255) / .64) 48%,
  rgb(var(--hat-rgb-b856ff, 184 86 255) / .52) 54%,
  rgb(var(--hat-rgb-b856ff, 184 86 255) / .39) 60%,
  rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .26) 66%,
  rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .13) 72%,
  rgb(var(--hat-rgb-410985, 65 9 133) / .06) 77%,
  rgb(var(--hat-rgb-410985, 65 9 133) / 0) 84%);
 background-size: 54% 195%;
 animation-name: home-wordmark-bloom-light;
 filter: blur(1px) saturate(1.06);
}
/* During the tease, two compact caustics travel across only the lower facets
   of the letters as the existing crown light passes behind them. */
.home-wordmark::after {
 z-index: 3;
 background-image: radial-gradient(ellipse 72% 124% at 50% 150% in oklab,
  rgb(var(--hat-rgb-f0dfff, 240 223 255) / .92) 0%,
  rgb(var(--hat-rgb-f0dfff, 240 223 255) / .92) 43%,
  rgb(var(--hat-rgb-f0dfff, 240 223 255) / .88) 49%,
  rgb(var(--hat-rgb-d5afff, 213 175 255) / .78) 54%,
  rgb(var(--hat-rgb-b856ff, 184 86 255) / .58) 59%,
  rgb(var(--hat-rgb-b856ff, 184 86 255) / .4) 64%,
  rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .22) 69%,
  rgb(var(--hat-rgb-8b1ef0, 139 30 240) / .09) 75%,
  rgb(var(--hat-rgb-410985, 65 9 133) / 0) 82%);
 background-repeat: no-repeat;
 background-size: 46% 190%;
 background-position: -28% 108%;
 animation-name: home-wordmark-reflection;
 animation-duration: var(--hat-cycle-duration, 59.4992s);
 animation-timing-function: linear;
 animation-iteration-count: infinite;
}
.home-wordmark-composited .home-wordmark-light-pale {
 inset: auto;
 left: 0;
 top: 0;
 width: 44%;
 height: 190%;
 background-size: 100% 100%;
 background-position: 0 0;
}
.home-wordmark-composited .home-wordmark-light-bloom {
 inset: auto;
 left: 0;
 top: 0;
 width: 54%;
 height: 195%;
 background-size: 100% 100%;
 background-position: 0 0;
}
.home-wordmark-composited::after {
 inset: auto;
 left: 0;
 top: 0;
 width: 46%;
 height: 190%;
 background-size: 100% 100%;
 background-position: 0 0;
}
#homeHero #homeSubtitle {
 /* A plain-text sibling stays outside the wordmark's lighting mask. Reserve
    room through the shared hat anchor, preserving the approved crown overlap. */
 position: absolute;
 bottom: calc(100% + clamp(24px, 2.3vw, 32px));
 left: 0;
 right: 0;
 margin: 0 auto;
 max-width: 40ch;
 color: var(--muted);
 font-size: clamp(14px, 1.1vw, 17px);
 line-height: 1.65;
 text-wrap: balance;
}
.home-hero::after, .home-area + .home-area::before {
 content: ""; height: 1px; position: absolute; left: 50%; width: 80vw;
 transform: translateX(-50%);
 background: linear-gradient(90deg, transparent, var(--line), transparent);
 pointer-events: none;
}
/* Keep the divider above the artwork and its bottom-fade layer. */
.home-hero::after { bottom: 0; z-index: 4; }
.home-area + .home-area::before { top: calc(var(--home-section-gap) * -.5); }
@media (max-width: 640px) {
 .homepage { --home-carousel-inset: 0px; }
}
@media (max-width: 620px) {
 .homepage { --home-content-padding: 14px; }
 #homeHero {
  /* Give the larger wordmark breathing room below the mobile menu. Moving
     the shared anchor preserves its crown overlap and grows the hero with it. */
  --svg-hat-top: calc(clamp(182px, calc(49vw - 88px), 216px) + var(--home-subtitle-space));
  --svg-hat-width: min(374px, 88vw);
 }
 /* The mobile purple bloom reaches deeper as it swells. The compact white
    highlight and desktop lighting retain their existing profiles. */
 .edge-light-bloom {
  -webkit-mask-image: var(--edge-mobile-bloom-mask);
  mask-image: var(--edge-mobile-bloom-mask);
 }
 .edge-light-lilac, .edge-light-spill {
  --swell-large: 2.1;
 }
 #homeHero .home-brand-copy {
  width: calc(100% - 22px);
  /* Lift the larger letters above the crown while retaining a shallow overlap.
     This matches the desktop offset at the mobile breakpoint. */
  top: calc(var(--svg-hat-top) - 22px);
 }
 .home-wordmark {
  /* Fill more of a phone's width, then meet the desktop size smoothly. */
  font-size: min(25vw, calc(110px - 3.25vw));
  letter-spacing: -.024em;
  -webkit-text-stroke-width: .6px;
 }
 #homeHero #homeSubtitle { font-size: 14px; }
}
@media (prefers-reduced-motion: reduce) {
 .edge-light-pool, .edge-light-wash { animation: none; }
 .edge-light-wash::before { animation: none; }
 .edge-light-pool { opacity: 1; }
 .home-wordmark::before { animation: none; opacity: .18; }
 .home-wordmark::after { animation: none; }
 .home-wordmark-light { animation: none; opacity: 0; }
}
