
  /* The shader is the hero's paper. It's anchored to the top of the page
     (absolute, not fixed) so it scrolls AWAY with the hero — the names ride up
     out of view instead of hanging pinned while the next section slides over
     them (that pinned-while-scrolling look was the "parallax"). Every section
     below is opaque, so nothing relies on seeing it through them. */
  #gl{
    position: absolute;
    top: 0; left: 0;
    width: 100%;
    height: 100vh;                /* fallback: iOS Safari < 15.4 lacks svh — full height, never a 0-height collapse */
    height: 100svh;
    display: block;
    z-index: 0;
    opacity: 0;                   /* faded + focused in once the typed intro resolves */
    filter: blur(16px);
    transition: opacity 1.15s ease .3s, filter 1.2s ease .3s;
  }
  body.revealed #gl{ opacity: 1; filter: blur(0); }

  .hero{
    position: relative;
    z-index: 1;
    height: 100vh;                /* fallback: iOS Safari < 15.4 lacks svh */
    height: 100svh;
    width: 100%;
    pointer-events: none;         /* let the canvas feel every move; links opt back in */
  }

  /* ── top navigation ───────────────────────────────── */
  .nav{
    position: absolute;
    /* clear the notch in portrait + landscape (viewport-fit=cover lets content
       slide under it); env() is 0 on non-notched screens, so desktop is unchanged */
    top: max(clamp(26px, 4vh, 42px), env(safe-area-inset-top));
    left: 0; right: 0;
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
    display: flex;
    flex-wrap: wrap;
    gap: clamp(10px, 1.4vw, 18px);
    justify-content: center;
    align-items: baseline;
    font-size: clamp(8.51px, 0.805vw, 10.35px);
    font-weight: 600;
    letter-spacing: .09em;
    text-transform: uppercase;
  }
  .nav a{
    color: var(--ink);
    text-decoration: none;
    pointer-events: auto;
    position: relative;
    padding-bottom: 3px;
    transition: opacity .35s ease;
  }
  .nav a::after{
    content:"";
    position:absolute; left:0; right:100%; bottom:0;
    height:1.5px; background: currentColor;
    transition: right .4s cubic-bezier(.2,.7,.2,1);
  }
  .nav a:hover{ opacity:1; }
  .nav a:hover::after{ right:0; }
  .nav a:active{ opacity:.5; }            /* touch has no hover — give the tap a clear press response */
  /* keyboard focus ring — the nav links were the one interactive element without
     one (every other control has :focus-visible); matches the site's outline style */
  .nav a:focus-visible{ outline: 2px solid var(--ink); outline-offset: 3px; border-radius: 1px; }
  .nav .sep{ opacity:.32; font-weight:400; }
  /* touch: grow each link into a comfortable ≥44px hit box on every side WITHOUT
     touching the flex layout (padding/margin shifted the row + wrapped "RSVP").
     An absolutely-positioned, transparent ::before overhangs the bare text by
     ~16px vertically and ~9px each side — a tap on it counts as a tap on the link
     — so the visual nav is byte-identical to before, only the target is bigger.
     (.nav a is position:relative; ::after still draws the hover underline.) */
  @media (pointer: coarse){
    .nav a::before{
      content:""; position:absolute;
      top:-16px; bottom:-16px; left:-9px; right:-9px;
    }
  }

  /* ── centered invitation block ────────────────────── */
  .center{
    position:absolute; inset:0;
    display:flex; flex-direction:column;
    align-items:center; justify-content:center;
    text-align:center;
    padding: 0 24px;
    transform: translateY(-2.2vh);
  }

  .names{
    font-family: 'LF Serif', 'Fraunces', Georgia, 'Times New Roman', serif;
    font-weight: 440;
    font-optical-sizing: auto;
    /* Fluid: the full line "Khurshed & Nilufar" is ~8.7× the font-size wide, so
       it only fits on one line above ~920px. Below that it wraps to two lines
       ("Khurshed" / "& Nilufar" — bound by the &nbsp; in the markup) and the
       clamp keeps each line inside the viewport instead of overflowing. The
       shader bakes the names from their ACTUAL wrapped line-boxes (see
       stampText), so the two-line phone layout reveals correctly in the cloth. */
    font-size: clamp(40px, 16vw, 100px);
    line-height: .94;
    letter-spacing: -0.022em;
    margin: clamp(22px, 3.4vh, 40px) 0;
    color: var(--ink);
    /* soft halo keeps names crisp when colour bleeds in behind */
    text-shadow: 0 0 36px rgba(255,255,255,.55), 0 0 12px rgba(255,255,255,.5);
  }
  .names .amp{ font-weight: 360; padding: 0 .04em; }

  .meta{
    font-size: clamp(9.9px, 1.24vw, 13.2px);
    font-weight: 500;
    letter-spacing: .16em;
    text-transform: uppercase;
    text-shadow: 0 0 22px rgba(255,255,255,.7);
  }
  .meta .arrow{ margin: 0 .55em; opacity:.75; }
