/* Hero backgrounds ==========================================================
   Abstract patterns, pure CSS (no image files), fitted to the Figma exports:

     homepage                   .hero          dark purple, with fine grain
     Burger King                .cs-hero--bk   orange
     Hungarian State Treasury   .cs-hero--mak  teal

   Each one starts at the very top of the page, covers the full width of its
   hero and fades into the hero's own colour at the bottom. On page load it
   fades in together with the headline (see "Page-load fade-in" below).

   Loaded after hero.css on the homepage and after case-study.css on the case
   study pages. It adds to the existing rules; the one override is the
   homepage nav background, at the end of this file.
   ========================================================================== */

/* --- Shared --------------------------------------------------------------- */

.hero,
.cs-hero--bk,
.cs-hero--mak {
  /* How much of the hero the pattern covers, measured from the top. The
     pattern fades out into the section's own colour over the last stretch of
     that height, so the hero's lower edge is always flat colour. */
  --hero-bg-height: 75%;

  /* The same treatment at the TOP edge, as a share of the layer's height.
     The layer starts at y=0 with its own base colour (#1c1613 on the
     homepage) plus whatever blobs reach up there, while the page behind it is
     #1F1F1F — so the first row of pixels is a hard edge. Nothing shows it on
     a desktop, where that row sits under the browser's own chrome, but iOS
     Safari puts it on screen twice over: the rubber-band overscroll pulls the
     page down and reveals the body colour above the hero, and the translucent
     chrome samples the strip underneath it.

     All three heroes use it. On the case studies it pairs with the canvas
     colour that js/main.js keeps in step with the section on screen (see
     css/case-study.css): the canvas puts the hero's colour behind the
     rubber-band strip, and this fade makes the pattern meet it without an
     edge. */
  --hero-fade-top: 20%;

  /* Page-load fade-in. The headline's first word starts rising at 650 ms
     (introCurtainMask with hold: 0 - see js/animations.js), so the pattern
     starts with it and builds up underneath the text. Duration and curve
     follow motion.js (EASE.inOut). */
  --hero-bg-delay: 650ms;
  --hero-bg-duration: 1800ms;

  /* Grain against banding — the same speckle on all three heroes, which is
     why it lives here rather than being pasted into each one. Two knobs, and
     they are independent: baseFrequency sets the SIZE, inversely (feature
     size goes as 1/frequency, so 0.45 is about twice as coarse as the 0.85
     this started at), and the rect's opacity sets the STRENGTH. One octave,
     not three: in fractalNoise each further octave adds FINER detail at half
     the amplitude, so more octaves would not coarsen anything. */
  --hero-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.45' numOctaves='1' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.08'/%3E%3C/svg%3E");

  /* Own stacking context, so the pattern's z-index: -1 lands above the
     hero's own colour but below its content - no z-index needed on the
     children. */
  isolation: isolate;
}

.hero::before,
.cs-hero--bk::before,
.cs-hero--mak::before {
  content: "";
  position: absolute;
  top: 0;
  inset-inline: 0;
  height: var(--hero-bg-height);
  z-index: -1;
  pointer-events: none;

  /* The base state is invisible, and the animation fills in BOTH directions.

     Why the base matters: js/animations.js grabs this animation, lets
     introCurtainMask() cancel it, then replays it so its delay counts from
     the same moment as the headline's. A cancelled animation falls back to
     the element's own style — and while that was the default opacity of 1,
     the pattern snapped to fully visible for the rest of that task before the
     replay put it back to 0. Measured on a warm return from a case study:
     opacity went 0 → 1 → 0 inside one module run. Locally that never reaches
     a paint, but the slower the device, the later the module runs and the
     more of the fade is already on screen when it gets rewound.

     With the base at 0 the worst case is invisible rather than a flash. */
  opacity: 0;
  animation: hero-bg-in var(--hero-bg-duration) cubic-bezier(.65, 0, .35, 1)
             var(--hero-bg-delay) both;
}

@keyframes hero-bg-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Reduced motion: no fade and no wait - the pattern is simply there.
   (base.css only shortens durations, so the delay would still apply.) */
@media (prefers-reduced-motion: reduce) {
  .hero::before,
  .cs-hero--bk::before,
  .cs-hero--mak::before {
    animation: none;
    opacity: 1;   /* the base is 0 now, so make it visible without the fade */
  }
}

/* Grey noise reads weaker the lighter the surface under it, so each hero
   carries its own strength. Only the opacity differs between these URIs;
   everything else is the shared definition above.

   Measured as the luminance spread of the composite — homepage 0.08 on
   #1F1F1F gives 1.50, which is the reference the other two are tuned to. */

/* #16545A is dark enough that 0.10 already matches the homepage. */
.cs-hero--mak {
  --hero-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.45' numOctaves='1' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.10'/%3E%3C/svg%3E");
}

/* #EE8C48 is the lightest of the three and needs roughly twice the opacity
   to land in the same place. */
.cs-hero--bk {
  --hero-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.45' numOctaves='1' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.17'/%3E%3C/svg%3E");
}

/* --- Homepage: dark purple ------------------------------------------------ */

.hero::before {
  background:
    /* Both edges fade into #1F1F1F, and one gradient does both: it is the top
       layer of the stack, so it covers the grain and the blobs alike.

       The head of it is the top fade — the same ramp as the tail, mirrored
       (1 / 0.86 / 0.6 / 0.3 / 0.1 / 0 across evenly spaced stops), so the two
       edges of the pattern run out the same way. Expressed as fractions of
       --hero-fade-top, which keeps the shape when that is tuned. */
    linear-gradient(to bottom,
      #1f1f1f 0,
      rgb(31 31 31 / 0.86) calc(var(--hero-fade-top) * 0.2),
      rgb(31 31 31 / 0.6)  calc(var(--hero-fade-top) * 0.4),
      rgb(31 31 31 / 0.3)  calc(var(--hero-fade-top) * 0.6),
      rgb(31 31 31 / 0.1)  calc(var(--hero-fade-top) * 0.8),
      rgb(31 31 31 / 0)    var(--hero-fade-top),
      rgb(31 31 31 / 0) 50%, rgb(31 31 31 / 0.1) 60%, rgb(31 31 31 / 0.3) 70%,
      rgb(31 31 31 / 0.6) 80%, rgb(31 31 31 / 0.86) 90%, #1f1f1f 100%),
    var(--hero-grain),
    radial-gradient(ellipse 12.7% 8.0% at 29.7% 64.1%,
      rgb(59 61 54 / 0.450) 0%, rgb(59 61 54 / 0.428) 20%, rgb(59 61 54 / 0.366) 35%, rgb(59 61 54 / 0.302) 45%, rgb(59 61 54 / 0.231) 55%, rgb(59 61 54 / 0.161) 65%, rgb(59 61 54 / 0.101) 75%, rgb(59 61 54 / 0.057) 85%, rgb(59 61 54 / 0.000) 100%),
    radial-gradient(ellipse 12.9% 8.0% at 23.2% 68.3%,
      rgb(59 61 54 / 0.631) 0%, rgb(59 61 54 / 0.601) 20%, rgb(59 61 54 / 0.512) 35%, rgb(59 61 54 / 0.424) 45%, rgb(59 61 54 / 0.323) 55%, rgb(59 61 54 / 0.225) 65%, rgb(59 61 54 / 0.142) 75%, rgb(59 61 54 / 0.080) 85%, rgb(59 61 54 / 0.000) 100%),
    radial-gradient(ellipse 5.8% 5.9% at 17.1% 72.4%,
      rgb(59 61 54 / 0.364) 0%, rgb(59 61 54 / 0.347) 20%, rgb(59 61 54 / 0.296) 35%, rgb(59 61 54 / 0.245) 45%, rgb(59 61 54 / 0.187) 55%, rgb(59 61 54 / 0.130) 65%, rgb(59 61 54 / 0.082) 75%, rgb(59 61 54 / 0.046) 85%, rgb(59 61 54 / 0.000) 100%),
    radial-gradient(ellipse 5.1% 9.3% at 84.0% 40.4%,
      rgb(64 68 63 / 0.480) 0%, rgb(64 68 63 / 0.442) 20%, rgb(64 68 63 / 0.366) 35%, rgb(64 68 63 / 0.301) 45%, rgb(64 68 63 / 0.235) 55%, rgb(64 68 63 / 0.172) 65%, rgb(64 68 63 / 0.119) 75%, rgb(64 68 63 / 0.077) 85%, rgb(64 68 63 / 0.000) 100%),
    radial-gradient(ellipse 8.1% 11.6% at 79.1% 38.5%,
      rgb(64 68 63 / 0.476) 0%, rgb(64 68 63 / 0.439) 20%, rgb(64 68 63 / 0.363) 35%, rgb(64 68 63 / 0.299) 45%, rgb(64 68 63 / 0.233) 55%, rgb(64 68 63 / 0.171) 65%, rgb(64 68 63 / 0.118) 75%, rgb(64 68 63 / 0.077) 85%, rgb(64 68 63 / 0.000) 100%),
    radial-gradient(ellipse 13.4% 12.9% at 71.7% 37.1%,
      rgb(64 68 63 / 0.414) 0%, rgb(64 68 63 / 0.382) 20%, rgb(64 68 63 / 0.316) 35%, rgb(64 68 63 / 0.260) 45%, rgb(64 68 63 / 0.202) 55%, rgb(64 68 63 / 0.149) 65%, rgb(64 68 63 / 0.103) 75%, rgb(64 68 63 / 0.067) 85%, rgb(64 68 63 / 0.000) 100%),
    radial-gradient(ellipse 62.7% 30.1% at 28.2% 56.8%,
      rgb(41 26 48 / 1.000) 0%, rgb(41 26 48 / 0.904) 15%, rgb(41 26 48 / 0.667) 30%, rgb(41 26 48 / 0.402) 45%, rgb(41 26 48 / 0.198) 60%, rgb(41 26 48 / 0.080) 75%, rgb(41 26 48 / 0.000) 100%),
    radial-gradient(ellipse 27.6% 23.4% at 5.1% 14.0%,
      rgb(42 27 49 / 0.693) 0%, rgb(42 27 49 / 0.626) 15%, rgb(42 27 49 / 0.462) 30%, rgb(42 27 49 / 0.279) 45%, rgb(42 27 49 / 0.137) 60%, rgb(42 27 49 / 0.055) 75%, rgb(42 27 49 / 0.000) 100%),
    radial-gradient(ellipse 19.0% 29.3% at 15.6% 55.5%,
      rgb(136 115 255 / 0.230) 0%, rgb(136 115 255 / 0.208) 15%, rgb(136 115 255 / 0.153) 30%, rgb(136 115 255 / 0.092) 45%, rgb(136 115 255 / 0.045) 60%, rgb(136 115 255 / 0.018) 75%, rgb(136 115 255 / 0.000) 100%),
    radial-gradient(ellipse 111.5% 88.2% at 75.9% 8.1%,
      rgb(38 27 41 / 0.763) 0%, rgb(38 27 41 / 0.689) 15%, rgb(38 27 41 / 0.509) 30%, rgb(38 27 41 / 0.307) 45%, rgb(38 27 41 / 0.151) 60%, rgb(38 27 41 / 0.061) 75%, rgb(38 27 41 / 0.000) 100%),
    radial-gradient(ellipse 74.9% 35.4% at 45.3% 35.6%,
      rgb(134 81 255 / 0.213) 0%, rgb(134 81 255 / 0.192) 15%, rgb(134 81 255 / 0.142) 30%, rgb(134 81 255 / 0.086) 45%, rgb(134 81 255 / 0.042) 60%, rgb(134 81 255 / 0.017) 75%, rgb(134 81 255 / 0.000) 100%),
    radial-gradient(ellipse 75.3% 43.2% at 39.1% 87.9%,
      rgb(136 81 255 / 0.168) 0%, rgb(136 81 255 / 0.152) 15%, rgb(136 81 255 / 0.112) 30%, rgb(136 81 255 / 0.068) 45%, rgb(136 81 255 / 0.033) 60%, rgb(136 81 255 / 0.013) 75%, rgb(136 81 255 / 0.000) 100%),
    radial-gradient(ellipse 59.4% 66.9% at 87.8% 72.7%,
      rgb(36 26 37 / 0.913) 0%, rgb(36 26 37 / 0.825) 15%, rgb(36 26 37 / 0.609) 30%, rgb(36 26 37 / 0.367) 45%, rgb(36 26 37 / 0.181) 60%, rgb(36 26 37 / 0.073) 75%, rgb(36 26 37 / 0.000) 100%),
    radial-gradient(ellipse 40.8% 36.1% at 87.4% 103.5%,
      rgb(100 73 176 / 0.712) 0%, rgb(100 73 176 / 0.643) 15%, rgb(100 73 176 / 0.475) 30%, rgb(100 73 176 / 0.286) 45%, rgb(100 73 176 / 0.141) 60%, rgb(100 73 176 / 0.057) 75%, rgb(100 73 176 / 0.000) 100%),
    radial-gradient(ellipse 113.2% 20.0% at -8.4% 4.3%,
      rgb(57 36 82 / 0.527) 0%, rgb(57 36 82 / 0.477) 15%, rgb(57 36 82 / 0.352) 30%, rgb(57 36 82 / 0.212) 45%, rgb(57 36 82 / 0.104) 60%, rgb(57 36 82 / 0.042) 75%, rgb(57 36 82 / 0.000) 100%),
    #1c1613;
}

/* The nav floats over the hero with the same dark fill, which would cover the
   top 96px of the pattern. Over the hero it can be transparent: the nav is
   position: absolute, so it scrolls away with the hero and never sits on
   another section. */
.site-nav {
  background: transparent;
}

/* --- Burger King: orange, fading into --accent-bk #EE8C48 ---------------- */

.cs-hero--bk::before {
  background:
    /* Fade into the hero colour #EE8C48 — always the top layer, at both ends.
       The tail runs from 40% to the full height, about 356px of the 594px
       layer, rather than the 91-98.5% it started at: across 45px the eye
       finds the edge where the pattern stops, across the bottom 60% there is
       no edge to find. The head is the same ramp mirrored, over
       --hero-fade-top — see the homepage for why the top edge needs it. */
    linear-gradient(to bottom,
      rgb(238 140 72 / 1) 0,
      rgb(238 140 72 / 0.86) calc(var(--hero-fade-top) * 0.2),
      rgb(238 140 72 / 0.6)  calc(var(--hero-fade-top) * 0.4),
      rgb(238 140 72 / 0.3)  calc(var(--hero-fade-top) * 0.6),
      rgb(238 140 72 / 0.1)  calc(var(--hero-fade-top) * 0.8),
      rgb(238 140 72 / 0)    var(--hero-fade-top),
      rgb(238 140 72 / 0) 40%, rgb(238 140 72 / 0.06) 52%,
      rgb(238 140 72 / 0.20) 64%, rgb(238 140 72 / 0.42) 76%,
      rgb(238 140 72 / 0.68) 86%, rgb(238 140 72 / 0.89) 94%,
      rgb(238 140 72 / 1) 100%),
    var(--hero-grain),
    radial-gradient(ellipse 45.9% 108.4% at 51.8% 35.6%,
      rgb(124 0 9 / 0.066) 0%, rgb(124 0 9 / 0.059) 15%, rgb(124 0 9 / 0.044) 30%, rgb(124 0 9 / 0.026) 45%, rgb(124 0 9 / 0.013) 60%, rgb(124 0 9 / 0.005) 75%, rgb(124 0 9 / 0.000) 100%),
    radial-gradient(ellipse 48.3% 53.7% at 90.0% 3.2%,
      rgb(210 116 64 / 0.724) 0%, rgb(210 116 64 / 0.654) 15%, rgb(210 116 64 / 0.483) 30%, rgb(210 116 64 / 0.291) 45%, rgb(210 116 64 / 0.143) 60%, rgb(210 116 64 / 0.058) 75%, rgb(210 116 64 / 0.000) 100%),
    radial-gradient(ellipse 21.9% 104.9% at 34.5% -20.0%,
      rgb(251 175 93 / 0.268) 0%, rgb(251 175 93 / 0.243) 15%, rgb(251 175 93 / 0.179) 30%, rgb(251 175 93 / 0.108) 45%, rgb(251 175 93 / 0.053) 60%, rgb(251 175 93 / 0.021) 75%, rgb(251 175 93 / 0.000) 100%),
    radial-gradient(ellipse 14.1% 38.5% at 4.3% 95.0%,
      rgb(189 81 45 / 0.220) 0%, rgb(189 81 45 / 0.199) 15%, rgb(189 81 45 / 0.147) 30%, rgb(189 81 45 / 0.089) 45%, rgb(189 81 45 / 0.044) 60%, rgb(189 81 45 / 0.018) 75%, rgb(189 81 45 / 0.000) 100%),
    radial-gradient(ellipse 166.2% 67.3% at 49.0% 93.4%,
      rgb(171 60 36 / 0.281) 0%, rgb(171 60 36 / 0.254) 15%, rgb(171 60 36 / 0.187) 30%, rgb(171 60 36 / 0.113) 45%, rgb(171 60 36 / 0.056) 60%, rgb(171 60 36 / 0.022) 75%, rgb(171 60 36 / 0.000) 100%),
    radial-gradient(ellipse 15.0% 56.7% at 95.9% 104.5%,
      rgb(218 125 68 / 0.644) 0%, rgb(218 125 68 / 0.582) 15%, rgb(218 125 68 / 0.429) 30%, rgb(218 125 68 / 0.259) 45%, rgb(218 125 68 / 0.127) 60%, rgb(218 125 68 / 0.051) 75%, rgb(218 125 68 / 0.000) 100%),
    radial-gradient(ellipse 89.9% 50.2% at 19.3% 9.6%,
      rgb(219 128 70 / 0.899) 0%, rgb(219 128 70 / 0.812) 15%, rgb(219 128 70 / 0.599) 30%, rgb(219 128 70 / 0.361) 45%, rgb(219 128 70 / 0.178) 60%, rgb(219 128 70 / 0.071) 75%, rgb(219 128 70 / 0.000) 100%),
    radial-gradient(ellipse 66.6% 15.2% at 25.7% 5.2%,
      rgb(187 78 43 / 0.714) 0%, rgb(187 78 43 / 0.645) 15%, rgb(187 78 43 / 0.476) 30%, rgb(187 78 43 / 0.287) 45%, rgb(187 78 43 / 0.141) 60%, rgb(187 78 43 / 0.057) 75%, rgb(187 78 43 / 0.000) 100%),
    #eb9852;
}

/* --- Hungarian State Treasury: teal, fading into --accent-mak #16545A ---- */

.cs-hero--mak::before {
  background:
    /* Fade into the hero colour #16545A — always the top layer, at both ends.
       Same geometry as Burger King's: the tail from 40% to the full height,
       about 356px of the 594px layer, so there is no short run where the
       pattern visibly stops, and the same mirrored head over --hero-fade-top.
       This hero needs the head most of the three: the layer's own base is
       #32716b against a #16545A section, so its first row is the furthest
       from the colour behind it. */
    linear-gradient(to bottom,
      rgb(22 84 90 / 1) 0,
      rgb(22 84 90 / 0.86) calc(var(--hero-fade-top) * 0.2),
      rgb(22 84 90 / 0.6)  calc(var(--hero-fade-top) * 0.4),
      rgb(22 84 90 / 0.3)  calc(var(--hero-fade-top) * 0.6),
      rgb(22 84 90 / 0.1)  calc(var(--hero-fade-top) * 0.8),
      rgb(22 84 90 / 0)    var(--hero-fade-top),
      rgb(22 84 90 / 0) 40%, rgb(22 84 90 / 0.06) 52%,
      rgb(22 84 90 / 0.20) 64%, rgb(22 84 90 / 0.42) 76%,
      rgb(22 84 90 / 0.68) 86%, rgb(22 84 90 / 0.89) 94%,
      rgb(22 84 90 / 1) 100%),
    var(--hero-grain),
    radial-gradient(ellipse 44.0% 22.8% at 59.3% 43.9%,
      rgb(98 180 157 / 0.298) 0%, rgb(98 180 157 / 0.269) 15%, rgb(98 180 157 / 0.199) 30%, rgb(98 180 157 / 0.120) 45%, rgb(98 180 157 / 0.059) 60%, rgb(98 180 157 / 0.024) 75%, rgb(98 180 157 / 0.000) 100%),
    radial-gradient(ellipse 225.6% 38.3% at 105.1% 18.7%,
      rgb(26 82 83 / 1.000) 0%, rgb(26 82 83 / 0.904) 15%, rgb(26 82 83 / 0.667) 30%, rgb(26 82 83 / 0.402) 45%, rgb(26 82 83 / 0.198) 60%, rgb(26 82 83 / 0.080) 75%, rgb(26 82 83 / 0.000) 100%),
    radial-gradient(ellipse 68.3% 31.2% at 61.8% 42.8%,
      rgb(0 46 57 / 1.000) 0%, rgb(0 46 57 / 0.904) 15%, rgb(0 46 57 / 0.667) 30%, rgb(0 46 57 / 0.402) 45%, rgb(0 46 57 / 0.198) 60%, rgb(0 46 57 / 0.080) 75%, rgb(0 46 57 / 0.000) 100%),
    radial-gradient(ellipse 240.0% 57.6% at -14.5% 87.6%,
      rgb(0 47 58 / 0.490) 0%, rgb(0 47 58 / 0.443) 15%, rgb(0 47 58 / 0.327) 30%, rgb(0 47 58 / 0.197) 45%, rgb(0 47 58 / 0.097) 60%, rgb(0 47 58 / 0.039) 75%, rgb(0 47 58 / 0.000) 100%),
    radial-gradient(ellipse 83.2% 33.5% at 68.5% 48.7%,
      rgb(160 255 212 / 0.386) 0%, rgb(160 255 212 / 0.348) 15%, rgb(160 255 212 / 0.257) 30%, rgb(160 255 212 / 0.155) 45%, rgb(160 255 212 / 0.076) 60%, rgb(160 255 212 / 0.031) 75%, rgb(160 255 212 / 0.000) 100%),
    radial-gradient(ellipse 96.4% 162.3% at 91.5% 55.2%,
      rgb(8 58 67 / 0.448) 0%, rgb(8 58 67 / 0.405) 15%, rgb(8 58 67 / 0.299) 30%, rgb(8 58 67 / 0.180) 45%, rgb(8 58 67 / 0.089) 60%, rgb(8 58 67 / 0.036) 75%, rgb(8 58 67 / 0.000) 100%),
    radial-gradient(ellipse 131.9% 64.9% at -4.3% -16.4%,
      rgb(27 85 87 / 0.975) 0%, rgb(27 85 87 / 0.881) 15%, rgb(27 85 87 / 0.651) 30%, rgb(27 85 87 / 0.392) 45%, rgb(27 85 87 / 0.193) 60%, rgb(27 85 87 / 0.078) 75%, rgb(27 85 87 / 0.000) 100%),
    radial-gradient(ellipse 223.9% 28.6% at 27.7% 35.1%,
      rgb(15 68 73 / 0.701) 0%, rgb(15 68 73 / 0.633) 15%, rgb(15 68 73 / 0.467) 30%, rgb(15 68 73 / 0.282) 45%, rgb(15 68 73 / 0.139) 60%, rgb(15 68 73 / 0.056) 75%, rgb(15 68 73 / 0.000) 100%),
    #32716b;
}
