/*
 * Page head — one opening for every page except `/`.
 *
 * WHY THIS FILE EXISTS
 * Six pages had six heroes. Pricing opened with a one-line Fraunces display
 * over a dot lattice and four floating glass glyphs; docs opened with a
 * two-line display; explore, download, blog, about and product each had their
 * own padding and type scale. Same brand, six different first impressions.
 * Pricing is the one we kept, so this sheet lifts its opening into a shared
 * layer and every other page adopts it.
 *
 * Both pricing and the pages that copied it also opened with a small pill
 * eyebrow. It has been removed everywhere: the display carries the page on
 * its own, and one less element above it is one less thing between the
 * reader and the first line that says something.
 *
 * WHAT IT OWNS
 *   rhythm      hero padding, display size, lead size and measure
 *   band        the closing call to action every page ends on
 *   lattice     `.fgh-lattice` — the masked dot grid under the aurora
 *   floats      `.fgh-floats` — four decorative glass glyph chips
 *   entrance    a staggered fade-up, mirroring pricing's CSS fallback
 *
 * WHAT IT DOES NOT OWN
 * Colour and surface treatment (that is `_fluttergo-nightfall.css`), the
 * page's own controls below the lead (search field, plan toggle, filters,
 * download buttons) and the homepage, which is where this language came from
 * and which carries its own sheet.
 *
 * PRICING KEEPS ITS OWN MARKUP. `.pr-*` hero classes are mapped here rather
 * than replaced, because pricing's GSAP timeline animates them by name.
 *
 * LOAD ORDER: last, after `_fluttergo-nightfall.css`. Rules are written at
 * `html.nf-page` specificity so they tie with nightfall and win on order.
 */

html.nf-page {
  --fgh-top: clamp(22px, 2.8vw, 40px);
  --fgh-bottom: clamp(30px, 3.8vw, 48px);
  --fgh-display: clamp(36px, 5.2vw, 60px);
  --fgh-lead: clamp(15px, 1.4vw, 17px);
  --fgh-measure: 620px;
  --fgh-ease: cubic-bezier(0.23, 1, 0.32, 1);
}

/* ====================================================================== */
/* 1. Rhythm                                                              */
/* ====================================================================== */
/* Only padding is shared. Each hero keeps its own header offset — some
   pages bleed under the fixed chrome with a negative margin, others zero a
   wrapper's padding — and unifying that would be a layout change, not a
   skin change. */
html.nf-page :is(.pr-hero, .dl-hero, .blog-hero, .fgx-hero, .fgd-hero, .fgs-hero--page) {
  padding-top: calc(var(--chrome-h, 84px) + var(--fgh-top));
  padding-bottom: var(--fgh-bottom);
  position: relative;
  overflow: hidden;
}
/* Two kinds of hero live in that list. Docs, explore, pricing, download and
   the blog bleed up under the fixed header — a negative margin or a zeroed
   wrapper — so their own padding has to clear it, which is what the rule
   above does. About and Product do not bleed: `body.fgs` already carries
   `padding-top: var(--chrome-h)`, so counting the chrome again here would
   open a second header-sized gap above the headline. */
html.nf-page .fgs-hero--page { padding-top: var(--fgh-top); }

/* One display size, one measure for the lead. A page whose headline fits on
   one line at this size gets to keep it — that single line is most of what
   makes the pricing opening feel calm — so the cap is 15em: wide enough for
   a short headline like "Everything you need to ship." to stay on one line
   at every display size, tight enough that About's 58-character sentence
   wraps to two centred lines instead of running the full width of a 27"
   monitor. Being in em rather than px, it wraps at the same word on a phone
   as on a desktop. */
html.nf-page :is(
  .pr-title, .dl-title, .blog-hero-title, .fgx-title, .fgd-hero-title
),
html.nf-page .fgs-hero--page .fgs-h1 {
  font-size: var(--fgh-display);
  line-height: 1.04;
  /* -0.01em is what every one of these headlines was already rendering at:
     nightfall's `html.nf-page h1` outranked each page's own tracking. Keeping
     it means this sheet changes the size of the display and nothing else. */
  letter-spacing: -0.01em;
  margin: 0 auto 14px;
  max-width: 15em;
  text-wrap: balance;
}

/* The 15em display cap only governs if the column around it is at least as
   wide — otherwise each page's own hero column decides where the headline
   breaks, and the same length of sentence wraps on download (720px column)
   while it stays on one line on pricing (780px). 900px is 15em at the
   display's 60px ceiling, so from here the cap is the only thing that wraps
   a headline. Nothing else in these columns is affected: every lead is
   capped at `--fgh-measure` and the controls under them are centred. */
html.nf-page :is(.pr-hero-inner, .dl-hero-inner, .blog-hero-inner),
html.nf-page .fgs-hero--page .fgs-hero__inner {
  max-width: min(900px, 100%);
  margin-inline: auto;
}

html.nf-page :is(
  .pr-lead, .dl-lead, .blog-hero-sub, .fgx-lead, .fgd-hero-lead
),
html.nf-page .fgs-hero--page .fgs-lead {
  margin: 0 auto;
  max-width: var(--fgh-measure);
  font-size: var(--fgh-lead);
  line-height: 1.55;
  color: var(--nf-muted);
  text-wrap: pretty;
}

/* ====================================================================== */
/* 2. Lattice                                                             */
/* ====================================================================== */
/* Pricing's `.pr-hero-grid`: a faint dot grid masked to an ellipse under the
   headline, so the opening reads as a lit stage rather than flat ink. */
html.nf-page .fgh-lattice {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(rgba(91, 200, 255, 0.14) 1px, transparent 1px);
  background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(ellipse 70% 78% at 50% 12%, #000 0%, transparent 78%);
  mask-image: radial-gradient(ellipse 70% 78% at 50% 12%, #000 0%, transparent 78%);
}

/* ====================================================================== */
/* 3. Floating glyphs                                                     */
/* ====================================================================== */
/* Four glass chips, two per side, bobbing out of phase. Decorative: aria
   hidden, no pointer events, and gone below 880px where they would sit on
   top of the headline instead of beside it. Each page picks its own glyphs
   — a `$` on pricing, a `#` on docs — so the family reads as one system
   without four identical pages. */
html.nf-page .fgh-floats {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
html.nf-page .fgh-float {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--nf-mono);
  font-weight: 500;
  color: var(--nf-sky);
  background: rgba(12, 19, 33, 0.66);
  border: 1px solid rgba(91, 200, 255, 0.22);
  border-radius: 16px;
  box-shadow:
    inset 0 1px 0 rgba(233, 238, 249, 0.06),
    0 12px 32px rgba(0, 0, 0, 0.4);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  animation: fgh-bob var(--bob-dur, 6s) ease-in-out var(--bob-delay, 0s) infinite alternate;
}
html.nf-page .fgh-float svg { width: 22px; height: 22px; fill: currentColor; }

html.nf-page .fgh-float--a { left: 7%; top: 30%; width: 54px; height: 54px; font-size: 20px; --bob-dur: 6.2s; --bob-delay: 0s; }
html.nf-page .fgh-float--b { left: 14%; top: 64%; width: 44px; height: 44px; font-size: 16px; --bob-dur: 5.4s; --bob-delay: -1.8s; }
html.nf-page .fgh-float--c { right: 7%; top: 26%; width: 60px; height: 60px; font-size: 24px; --bob-dur: 6.8s; --bob-delay: -3.1s; }
html.nf-page .fgh-float--d { right: 14%; top: 62%; width: 48px; height: 48px; font-size: 14px; --bob-dur: 5.8s; --bob-delay: -4.4s; }

@keyframes fgh-bob {
  from { transform: translateY(-6px) rotate(-2deg); }
  to { transform: translateY(8px) rotate(2.5deg); }
}

@media (max-width: 1080px) {
  html.nf-page .fgh-float--b,
  html.nf-page .fgh-float--d { display: none; }
}
@media (max-width: 880px) {
  html.nf-page .fgh-floats { display: none; }
}

/* Hero content sits above lattice and glyphs. Nightfall already lifts the
   direct children of the older heroes; docs and explore are namespaced
   differently, so they are named here too. */
html.nf-page :is(.fgd-hero, .fgx-hero) > *:not(.fgh-lattice):not(.fgh-floats) {
  position: relative;
  z-index: 1;
}

/* ====================================================================== */
/* 4. Entrance                                                            */
/* ====================================================================== */
/* Pricing's GSAP timeline reveals its headline word by word; that rig is
   pricing-only. What every page can share is the fallback pacing — display,
   lead, then controls, 80ms apart — so the openings feel like one sequence
   even though only one of them is choreographed.

   No `html.js` gate: `animation-fill-mode: both` means the sequence starts
   from the hidden state and ends visible on its own, so a page that never
   runs a script still finishes with its hero on screen. */
@media (prefers-reduced-motion: no-preference) {
  html.nf-page :is(.fgd-hero, .fgx-hero, .dl-hero, .blog-hero, .fgs-hero--page) .fgh-rise > * {
    animation: fgh-rise 0.62s var(--fgh-ease) both;
  }
  html.nf-page .fgh-rise > *:nth-child(1) { animation-delay: 0.04s; }
  html.nf-page .fgh-rise > *:nth-child(2) { animation-delay: 0.12s; }
  html.nf-page .fgh-rise > *:nth-child(3) { animation-delay: 0.2s; }
  html.nf-page .fgh-rise > *:nth-child(4) { animation-delay: 0.28s; }
  html.nf-page .fgh-rise > *:nth-child(5) { animation-delay: 0.36s; }
}
@keyframes fgh-rise {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}


/* ====================================================================== */
/* 5. Closing band                                                        */
/* ====================================================================== */
/*
 * Pricing's `.pr-cta-banner` is the reference: a rounded box with a hairline
 * around it, the constellation running straight through, two soft glows, and
 * the page's one ember action in the middle. It is left alone here and every
 * other page's closing band is brought to it.
 *
 * They were four different endings before: docs closed on an opaque panel
 * with its text left and its buttons right, explore on a full-bleed band with
 * no edge at all, the blog on a bare centred stack, and about on a filled
 * card. Same job, four shapes.
 *
 * The band is deliberately NOT a surface. A card is a thing sitting on the
 * field; a closing band is the field with an edge drawn around it, which is
 * why there is no fill and nothing here casts a shadow.
 */
html.nf-page :is(.fgd-help, .fga-cta, .dl-cta),
html.nf-page .fgx-cta > .fgx-wrap,
html.nf-page .blog-cta > .container {
  position: relative;
  display: block;
  overflow: hidden;
  box-sizing: border-box;
  padding: clamp(44px, 5.5vw, 72px) clamp(22px, 4vw, 48px);
  /* No frame. The border was drawing a rectangle around mostly empty field:
     the copy is a centred column roughly 54ch wide, so on a 1200px page two
     thirds of the box was edge with nothing in it. The radius stays because
     it still shapes the two glows; with no border there is nothing to see of
     it. The hairline above the copy is what marks the section now. */
  border: 0;
  border-radius: 22px;
  /* Both glows are centred and fade out before they reach the edges. Anchored
     in the corners they were clipped by the container and read as a tinted
     rectangle — the frame we just removed, drawn in light instead of in a
     border. */
  background:
    radial-gradient(58% 90% at 50% 0%, rgba(255, 106, 61, 0.1), transparent 68%),
    radial-gradient(52% 80% at 50% 100%, rgba(91, 200, 255, 0.07), transparent 70%);
  box-shadow: none;
  text-align: center;
}
/* The one ember hairline, on the one ember block, on each page. */
html.nf-page :is(.fgd-help, .fga-cta, .dl-cta)::before,
html.nf-page .fgx-cta > .fgx-wrap::before,
html.nf-page .blog-cta > .container::before {
  content: "";
  position: absolute;
  top: 0;
  left: 30%;
  right: 30%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 106, 61, 0.5), transparent);
}

/* One type scale inside the band, because five pages had five.
   The closing headline measured 56px on explore, 40 on pricing, 38 on about
   and download, 34 on the blog and 32 on docs — the same sentence, doing the
   same job, at five sizes. Docs' label was worse than inconsistent: at (0,1,0)
   the `.fgd-help p` rule outranked `.fgd-label`, so "Still stuck?" rendered at
   the paragraph's 14.5px instead of a label's 10.5px. */
html.nf-page :is(.fgd-help, .fga-cta, .dl-cta) h2,
html.nf-page .fgx-cta > .fgx-wrap h2,
html.nf-page .blog-cta > .container .blog-cta-title,
html.nf-page .pr-cta-banner .pr-cta-title {
  margin: 12px 0 0;
  font-family: var(--nf-display);
  font-weight: 300;
  font-size: clamp(26px, 3.2vw, 38px);
  line-height: 1.1;
  letter-spacing: -0.01em;
  max-width: none;
  color: var(--nf-star);
}
html.nf-page :is(.fgd-help, .fga-cta, .dl-cta) h2 em,
html.nf-page .fgx-cta > .fgx-wrap h2 em,
html.nf-page .blog-cta .fg-hl {
  font-style: italic;
  font-weight: 400;
  color: var(--nf-ember);
}
/* The label above it. */
html.nf-page :is(.fgd-help .fgd-label, .fga-cta-label, .dl-cta-label, .fgx-cta .fgx-eyebrow) {
  margin: 0;
  font-family: var(--nf-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--nf-dim);
}
/* And the sentence under it. The `:not()`s matter: every one of these labels
   is also a <p> in the same position, and at equal specificity this rule
   would win and print the label at paragraph size. */
html.nf-page :is(.fgd-help, .fga-cta, .dl-cta) > p:not([class*="-label"]),
html.nf-page :is(.fgd-help, .fga-cta, .dl-cta) div > p:not(.fgd-label),
html.nf-page .fgx-cta > .fgx-wrap > p:not(.fgx-eyebrow),
html.nf-page .blog-cta > .container .blog-cta-sub {
  margin: 12px auto 0;
  max-width: 54ch;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--nf-muted);
}

/* Inline actions are pills across the whole site — the header CTA, docs,
   explore, about, the blog. Pricing's closing button was the one 11px
   rounded rect among them. (Full-width buttons inside a card stay rects:
   that is a different control, and pricing's plans and download's cards
   both use it.) */
html.nf-page .pr-cta-banner .pr-cta {
  border-radius: 999px;
  padding: 12px 24px;
  font-size: 15px;
}

/* Docs' band was a two-column row; centre it like the rest. Its own sheet
   still owns the type, this only owns the shape. */
html.nf-page .fgd-help > div { max-width: 62ch; margin: 0 auto; }
html.nf-page .fgd-help-actions,
html.nf-page .fgx-cta-actions,
html.nf-page .fga-cta-actions,
html.nf-page .dl-cta-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 24px;
}
/* Explore's band carried the section's own padding as well as the box's. */
html.nf-page .fgx-cta { padding: clamp(56px, 7vw, 96px) 0; border-top: 0; }
html.nf-page .fgx-cta::before { content: none; }
html.nf-page .blog-cta { padding: clamp(40px, 5vw, 72px) 0; border-top: 0; }

@media (max-width: 560px) {
  html.nf-page :is(.fgd-help, .fga-cta, .dl-cta),
  html.nf-page .fgx-cta > .fgx-wrap,
  html.nf-page .blog-cta > .container {
    padding: 38px 20px;
  }
}

/* ====================================================================== */
/* 6. Short windows                                                       */
/* ====================================================================== */
/* A 13" laptop with a bookmarks bar is roughly 700px of viewport. The
   opening gives up display size before it gives up the first row of real
   content underneath it. */
@media (min-width: 861px) and (max-height: 820px) {
  html.nf-page {
    --fgh-top: 20px;
    --fgh-bottom: 26px;
    --fgh-display: clamp(32px, 3.6vw, 46px);
    --fgh-lead: 15px;
  }
}

/* Phones: the lead keeps a comfortable measure rather than running to the
   screen edges. */
@media (max-width: 560px) {
  html.nf-page {
    --fgh-top: 18px;
    --fgh-bottom: 24px;
    --fgh-measure: 40ch;
  }
}
