/* ============================================================
   SPLIT HERO — the two-column, left-aligned product hero.
   ------------------------------------------------------------
   A page-hero variant shared by Professional Email and Website
   Builder, and a deliberate break from the centred product hero:
   copy on the left, the product's devices on the right, and a
   mint shape that runs off the bottom of the band.

   The shape is the point of the layout. The centred heroes end on
   a ruled edge; this one ends on a curve that spills into the band
   below, so the page reads as one continuous surface rather than
   as stacked slabs. It is drawn on a pseudo-element taller than
   the hero and painted AFTER the next section's background (the
   hero is its own stacking context via `isolation`, so the shape
   cannot reach anything further down the page than that one
   band). The hero's own overflow is `clip` horizontally and
   `visible` vertically, so the spill is the only thing that
   escapes.

   The devices are transparent cut-outs (the WebP ships with an
   alpha channel), so the shape reads through them rather than
   around a white rectangle — which is why the old white shot
   card is not wanted here.
   ============================================================ */

.page-hero--split {
  /* The hero itself is transparent: the mint shape lives on the
     pseudo-element below and must show through, so it can bleed
     past the bottom edge of the band and tuck behind the content.

     Two token hooks, so a page can vary its wallpaper without
     restating the whole `::after` recipe:
       --hero-geo       the faceted-mesh SVG
       --hero-geo-base  the flat colour behind it, which doubles as
                        the fallback if the SVG never loads.
     The default is the Professional Email mint; `.page-hero--teal`
     below swaps in the Email Marketing variant. */
  --hero-geo: url("../img/hero/email-geo-facets.svg");
  --hero-geo-base: #c4f0d5;
  /* Artwork scale, mirroring the product hero's `--product-dash-scale` /
     `--product-dash-shift`. Without it the email art rendered at 100% of
     its column (~672px) while cPanel's dashboard renders at 1.4x of a
     same-width column (~971px) — so the email heroes read a third smaller
     beside the hosting ones. 1.45 / -10% is the cPanel pairing. */
  --hero-art-scale: 1.45;
  --hero-art-shift: -10%;
  background: transparent;
  border-bottom: 0;
  overflow-x: clip;
  overflow-y: visible;
  /* The bottom step is generous on purpose. The shape runs a little past
     the band's lower edge and its bottom corners carry a radius of up to
     320px, so the last ~90px at each side of the band is CURVE, not flat
     paper. The trust strip (components.css) is the last thing in this
     band, so it needs to clear that: at 32px of foot the strip's outer
     cells landed on the arc and read as falling off the surface. */
  padding-block: clamp(3rem, 6vw, 5.5rem) clamp(2.5rem, 5vw, 4.5rem);
}

/* The shape: one wallpaper slab with heavy bottom radii, running a
   little past the band's lower edge so the curve is what the eye
   reads instead of a ruled boundary. Painted at z-index -1 inside the
   hero's own stacking context, so it stays behind the copy but still
   spills below.

   The inherited `::before` wash and `::after` dot grid both come
   from `.page-hero` in components.css and would paint over this
   shape — the wash is a white-to-brand gradient that would flatten
   the wallpaper, and the dot grid would fight the facets. Both are
   switched off here; this shape is the whole surface. */
.page-hero--split::before {
  content: none;
}

.page-hero--split::after {
  content: "";
  position: absolute;
  inset: 0 -2% -7% -2%;
  z-index: -1;
  border-radius: 0 0 clamp(120px, 20vw, 320px) clamp(120px, 20vw, 320px);
  /* A faceted "mesh-gradient" wallpaper: the SVG bakes the aurora into
     ~500 jittered crystal triangles, so the band reads as one low-poly
     surface instead of a flat wash. `cover` + `center top` keep the
     copy-side colour and the bloom on screen and crop only the pale
     foot, which is exactly what the curve is about to meet anyway.
     Both the file and the flat colour come from the tokens above. */
  background-color: var(--hero-geo-base, #c4f0d5); /* fallback if the SVG cannot load */
  background-image: var(--hero-geo);
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center top;
}

/* The TEAL sibling — Email Marketing.
   Same family, deliberately not the same surface: a cooler, more teal
   base, a deeper teal bloom, finer facets (86px vs 105px) and stronger
   jitter, so the two product pages read as siblings rather than as one
   page repeated. Only the two tokens are overridden; the curve, the
   inset, the z-index and the crop all carry over from the base rule. */
.page-hero--teal {
  --hero-geo: url("../img/hero/email-marketing-geo.svg");
  --hero-geo-base: #bfeee4;
  /* The headline accent rides the teal ramp instead of the house emerald,
     so the gradient agrees with the wallpaper behind it. Both stops are
     measured on the teal base: #0C8C8C is 3.22 and #0B6E6E is 4.77. The
     old #0EA5A5 stop measured 2.39 and is gone. */
  --product-accent-from: #0C8C8C;
  --product-accent-to: #0B6E6E;
}

/* The BLUE sibling — SSL Certificates.
   The third colourway in the split family and the first one that is not
   some shade of green. Nothing else changes: the two wallpaper tokens and
   three accent tokens below are the entire override, so the curve, the
   inset, the z-index, the crop, the 5.5/6.5 column split and the 900px
   stack all carry over from the rules above.

   The surface is still a PALE blue (#C7E0FA) for the same reason every
   other base is pale: the band's dark headline and grey lead are read
   against this colour, so the base is a background and not a brand
   statement. The bloom is the half that is allowed to be loud — the
   wallpaper's #2A76E8 burst sits behind the artwork, where nothing is
   ever read against it. Pale copy column, saturated far column.

   The accent stops are lifted from `[data-product="vps"]` rather than
   invented, so the SSL page and the VPS page agree on what "our blue"
   is. Both are measured against this base: #175CD3 is 4.41 and #102F6E
   is 9.36, clear of the 3:1 floor display type needs. */
.page-hero--blue {
  --hero-geo: url("../img/hero/ssl-geo.svg");
  --hero-geo-base: #C7E0FA;
  /* The feature strip is ruled with the PRODUCT's colour, not the
     component's — see the `--product-accent-rgb` note in tokens.css. */
  --product-accent-rgb: 23, 92, 211;
  --product-accent-from: #175CD3;
  --product-accent-to: #102F6E;
}

/* The CYAN sibling — Managed SSL Service.
   Same family, same two-token override as `.page-hero--teal` and
   `.page-hero--blue`, so the curve, the inset, the z-index, the crop,
   the 5.5/6.5 split and the 900px stack all carry over untouched.

   Deliberately NOT a copy of `.page-hero--blue`: the SSL page is the
   "buy a certificate" page and reads blue; this is the "we do it for
   you" page and reads green-to-cyan, which is the colour of the monitor
   artwork the owner supplied (a green dashboard glow on a cyan field).
   Reading the two pages side by side should tell you they are siblings
   without telling you they are the same offer.

   The base stays PALE (#CBEFE7) for the same reason every other base
   is pale: the band's dark headline and grey lead are read against it,
   so it is a background and not a brand statement. The bloom — the
   saturated emerald-cyan #10B9A6 burst in the wallpaper — sits behind
   the artwork, where nothing is ever read against it.

   Accent stops measured against this base: #0B7A63 is 4.41 and
   #065F52 is 6.99, both clear of the 3:1 floor display type needs. */
.page-hero--cyan {
  --hero-geo: url("../img/hero/ssl-managed-geo.svg");
  --hero-geo-base: #CBEFE7;
  --product-accent-rgb: 11, 122, 99;
  --product-accent-from: #0B7A63;
  --product-accent-to: #065F52;
}

/* The ICE sibling — Website Security.
   Same family, same two-token override as the three above, so the curve,
   the inset, the z-index, the crop, the 5.5/6.5 split and the 900px stack
   all carry over untouched.

   Deliberately NOT a copy of `.page-hero--blue` or `.page-hero--cyan`: the
   SSL page is the "buy a certificate" page and reads blue, Managed SSL reads
   green-to-cyan, and this is the cyan-leaning blue that sits between the two
   blues on the site — the colour of a firewall status light rather than a
   padlock or a monitor.

   The base stays PALE (#D3EBFA) for the same reason every other base is
   pale: the band's dark headline and grey lead are read against it, so it
   is a background and not a brand statement. The bloom — the saturated sky
   #0EA5E9 burst in the wallpaper — sits behind the artwork, where nothing
   is ever read against it.

   Accent stops measured against this base: #0369A1 is 4.81 and #075985 is
   6.13, both clear of the 4.5:1 the small bold strip text needs and well
   clear of the 3:1 floor display type needs. The slate-600 lead measures
   6.15 and the slate-900 headline 14.48, so the whole copy column is legible
   on the pale base. */
.page-hero--ice {
  --hero-geo: url("../img/hero/website-security-geo.svg");
  --hero-geo-base: #D3EBFA;
  --product-accent-rgb: 3, 105, 161;
  --product-accent-from: #0369A1;
  --product-accent-to: #075985;
}

/* The SEARCH sibling — SEO Tools.
   Same family, same two-token override as the four above, so the curve, the
   inset, the z-index, the crop, the 5.5/6.5 split and the 900px stack all
   carry over untouched.

   Deliberately NOT a copy of application .page-hero--blue or its cyan
   siblings. The four colourways already on the site all sit on the BLUE-CYAN
   half of the wheel — SSL is a broad sky blue, Managed SSL is emerald-cyan,
   Website Security is a cyan-leaning sky, VPS is a deep true blue — so this
   one takes the VIOLET side of blue (#1D4ED8) to read as its own surface. It
   is the page's own surface, consumed by the wallpaper above.

   The base stays PALE (#DBE5FC) for the same reason every other base is
   pale: the band's dark headline and grey lead are read against it, so it is
   a background and not a brand statement. The bloom — the saturated indigo
   #1D4ED8 burst in the wallpaper — sits behind the artwork, where nothing is
   ever read against it.

   Accent stops measured against this base: #1D4ED8 is 5.31 and #1E3A8A is
   8.20, both clear of the 4.5:1 the small bold strip text needs and well
   clear of the 3:1 floor display type needs. The slate-600 lead measures
   6.00 and the slate-900 headline 14.13, so the whole copy column is legible
   on the pale base (measured with a one-off WCAG checker; see the colourway
   notes in PROJECT-BRIEF.md §3.13). */
.page-hero--search {
  --hero-geo: url("../img/hero/seo-geo.svg");
  --hero-geo-base: #DBE5FC;
  --product-accent-rgb: 29, 78, 216;
  --product-accent-from: #1D4ED8;
  --product-accent-to: #1E3A8A;
}

/* The HUB sibling — the Security category page.
   The last colourway in the split family and the only one that is not a
   product: it is the house emerald, shared with hosting/index's
   `[data-product="hub"]` block (tokens.css) so the two category pages
   read as one tier above the per-product surfaces. Only the two wallpaper
   tokens and three accent tokens are overridden — same contract as the
   five colourways above, so the curve, the inset, the z-index, the crop,
   the 5.5/6.5 split and the 900px stack all carry over untouched.

   The base is the shared pale emerald #F0F8F4 (measured on the hubs-geo
   wallpaper's own base): brand-700 label 6.05:1, slate-500 strip text
   4.60:1, slate-600 lead 7.12:1, slate-900 headline 17.35:1. The accent
   stops are the house emerald ramp: #0A8158 is 4.53 and #06553A is 8.21
   on this base — clear of the 4.5:1 the small bold strip text needs and
   well clear of the 3:1 display floor. The saturated emerald bloom in
   the wallpaper sits behind the artwork, where nothing is read. */
.page-hero--hub {
  --hero-geo: url("../img/hero/hubs-geo.svg");
  --hero-geo-base: #F0F8F4;
  --product-accent-rgb: 10, 129, 88;
  --product-accent-from: #0A8158;
  --product-accent-to: #06553A;
}


/* The 5/7 split: the copy gets the measure it can hold, the
   devices get the rest. Below 900px it stacks, copy first. */
.page-hero--split .page-hero__inner {
  position: relative;
  z-index: 1;
  grid-template-columns: minmax(0, 5.5fr) minmax(0, 6.5fr);
  gap: clamp(2rem, 4vw, 3.5rem);
  /* Top, not centre: the devices column is taller than the copy,
     and centring would leave a hole under the buttons. The tops
     line up and the extra height collects at the foot of the copy. */
  align-items: start;
}

/* The artwork is scaled to the same visual weight as the hosting heroes'
   dashboards, via the tokens on `.page-hero--split`. The email art is the
   same 1536x1024 source in the same `container--wide`, so without this it
   rendered at 100% of its column (~672px) while cPanel's renders at 1.4x
   of an identically wide column (~971px) — the email heroes read a third
   smaller beside the hosting ones.

   Deliberately scoped to `--float`: the Website Builder also uses
   `.page-hero--split`, but its art is a `div.page-hero__shot` browser
   frame with no `--float`, so it keeps its own 92% treatment.

   ORDER MATTERS. This rule and the stacked override inside the 900px
   media query below are the same single-class specificity, so the LATER
   one wins. The base rule has to come first or it would override the
   phone's dial-back at every narrow width. */
.page-hero--split .hero-visual--float > img {
  width: calc(var(--hero-art-scale, 1.45) * 100%);
  margin-left: var(--hero-art-shift, -10%);
}

@media (max-width: 900px) {
  .page-hero--split .page-hero__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-8);
  }

  /* MOBILE FOLD — the same treatment `.page-hero--shot` (components.css)
     and the product heroes (product.css) already apply, and for the same
     reason: on a phone the copy column sits between the visitor and the
     product. Here the grey lead alone owns most of the first screen, so a
     visitor scrolls past the headline, four lines of lead, two buttons and
     the trust row before seeing the mailbox at all.

     Dissolving the copy wrapper lets its children interleave with the
     artwork, so the fold becomes headline → devices → lead → buttons →
     trust. DOM order is untouched, so assistive tech still reads the copy
     straight through and tab order is unchanged. */
  .page-hero--split .page-hero__copy {
    display: contents;
  }

  .page-hero--split .page-hero__copy > * {
    min-width: 0;
  }

  .page-hero--split .hero-visual {
    order: 1;
    justify-self: center;
    /* Matches `.product-hero__dash`'s cap on the stack. */
    max-width: 680px;
  }

  /* The bob and the scale are BOTH wide-screen polish, so both come off
     on the stack — the same call the product heroes make for their bob.

     The scale reset is a deliberate deviation from `.product-hero__dash`,
     which keeps 112% on its stack because a dashboard is designed to
     bleed off-edge. This artwork is a two-device composition, and at 112%
     a phone-width box crops the laptop's left edge and the phone's right
     edge — the two things the picture is about. Full width instead, so a
     phone gets the whole scene. */
  .page-hero--split .hero-visual--float > img {
    animation: none;
    width: 100%;
    margin-left: 0;
  }

  /* `.page-hero__price` is only used by a page that is not otherwise
     `--split` (SSL Certificates), so it needs an explicit seat here.
     Without it the price inherits order 0 and lands between the headline
     and the artwork, ahead of the lead and buttons it belongs after. */
  .page-hero--split .lead,
  .page-hero--split .btn-row,
  .page-hero--split .hero-trust,
  .page-hero--split .product-hero__checks,
  .page-hero--split .page-hero__price {
    order: 2;
  }
}

/* The lead takes the same measure as `.product-hero .lead` (product.css).
   At base.css's full 62ch a hero lead reads wider and looser than the
   hosting heroes' and makes the copy column look soft beside them.
   NOTE the order: this rule must stay ABOVE the phone block below.
   Both are single-class selectors, so at equal specificity the later
   one wins; putting this after would override the phone's tighter 46ch. */
.page-hero--split .lead {
  max-width: 52ch;
}

/* Phone: the grey lead is the tallest single thing in the fold, so it
   drops one type step and tightens its measure. Still a lead — just not a
   wall the product has to sit behind. */
@media (max-width: 640px) {
  .page-hero--split .lead {
    font-size: var(--fs-md);
    max-width: 46ch;
    margin-top: var(--sp-3);
  }
}

/* The marketing line is the h1 now, so it has to outgrow the
   22ch the product-name title was measured for. Two to three
   lines at this width, matching the other product heroes. */
.page-hero--split h1 {
  /* The marketing line runs longer than a product name. A measure
     sized in ch is treacherous here — the display face runs wide, so
     even 22ch breaks "A real website by Thursday," across two rows
     and the headline stacks into four lines, taller than the devices
     beside it. Two lines at the column's own width is the target. */
  max-width: 28ch;
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 3.2vw + 1.25rem, 4.25rem);
  font-weight: 700;
  letter-spacing: -0.022em;
  /* No `text-wrap: balance` here. It evens the lines out into more
     rows than the text needs, and the extra rows are what made the
     copy column taller than the devices beside it. */
}

@media (max-width: 640px) {
  .page-hero--split h1 {
    font-size: clamp(2.15rem, 8.5vw, 2.75rem);
  }
}

/* The headline accent MOVED to components.css on 2026-10-08 and is now
   shared by every product hero, not just the split ones — see "The headline
   accent" there. Two things it fixed on the way out: the old stops opened at
   `--brand-500` (2.5:1 on the mint band) and the teal page's at #0EA5A5
   (2.39:1), both under the 3:1 floor for display type.

   `.page-hero--teal` used to carry a `.accent` override of its own. It now
   just supplies the two tokens instead, so there is one rule and one
   mechanism rather than a base plus a special case. */

/* A small credential chip — the platform behind this product.
   Glassy rather than solid so the shape behind it still reads. It
   sits top-right of the band and clears the breadcrumb by giving
   the breadcrumb a right-hand measure to stop short of it. */
.page-hero--split .breadcrumb {
  max-width: calc(100% - 190px);
}

.hero-chip {
  position: absolute;
  top: clamp(1.25rem, 3vw, 2.25rem);
  right: clamp(1.25rem, 3vw, 2.5rem);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  padding: 7px 14px;
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  font-weight: 650;
  letter-spacing: -0.005em;
  color: var(--ink-800);
  background: rgba(255, 255, 255, 0.82);
  border: 1px solid rgba(10, 18, 32, 0.1);
  border-radius: var(--r-full);
  box-shadow: 0 8px 22px -12px rgba(10, 18, 32, 0.35);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* The Titan wordmark inside the "Powered by" chip. Inline SVG so it
   inherits the chip's own ink colour and needs no request; sized in the
   markup (74x18 at a 150x36 viewBox) so the box is reserved. */
.hero-chip__logo {
  display: block;
  width: 74px;
  height: 18px;
  color: var(--ink-900);
  flex: none;
}

/* A reading measure for the body copy that follows this hero. The
   old body kept its two-up grid with a screenshot beside it; with
   the devices promoted into the hero there is nothing to sit in
   the second column, and a full-width run of checklist text is
   about 100 characters too wide. Same measure as the hero lead. */
.measure {
  max-width: 62ch;
}

/* The hero checklist wraps to two rows in a narrow copy column.
   The house gap is tuned for a one-row strip on a full-width hero;
   at this measure it leaves each row floating. Pulled in so the
   rows read as a block and the column does not run taller than the
   devices beside it. Three across, two down — the six checks land
   as a tidy block instead of three ragged rows. */
.page-hero--split .product-hero__checks {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-2) var(--sp-5);
}

/* ---------- The feature cards under the hero ----------
   The hero no longer ends in a trust strip, so the four things it
   used to say live here as cards. White on the band, left-aligned
   like the hero copy above them, and the shadow arrives on hover
   rather than sitting there at rest. */
.split-hero-cards {
  text-align: left;
}

.split-hero-cards .card__icon {
  margin-inline: 0;
}

.split-hero-cards h3,
.split-hero-cards p {
  text-align: left;
}

/* ---------- The device column ---------- */
.hero-visual {
  position: relative;
  z-index: 1;
  perspective: 1000px;
}

.hero-visual > img,
.hero-visual .page-hero__shot {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 32px 52px rgba(10, 18, 32, 0.2));
}

/* A browser mockup is a dense rectangle, and at full column width
   it runs taller than the copy beside it — which leaves a hole
   under the buttons. Pulled back a touch and pushed right, so it
   keeps the off-the-edge crop the composition wants without the
   extra height. */
.hero-visual .page-hero__shot {
  width: 92%;
  margin-left: auto;
  margin-right: -2.5%;
}

/* Two tempos on purpose. The main art bobs slowly so the column
   feels alive; the panels drift on a faster, smaller cycle so the
   set reads as layered rather than as one moving block. Both are
   transform-only, and both are taken off the page under
   prefers-reduced-motion below. */
.hero-visual--float > img {
  animation: heroFloatSlow 6s ease-in-out infinite alternate;
}

.float-fast {
  animation: heroFloatFast 4.5s ease-in-out infinite alternate;
}

.float-fast--delayed {
  animation-delay: -2.2s;
}

@keyframes heroFloatSlow {
  from { transform: translateY(0) rotate(-0.25deg); }
  to   { transform: translateY(-10px) rotate(0.35deg); }
}

@keyframes heroFloatFast {
  from { transform: translate3d(0, 0, 0) rotate(1.2deg); }
  to   { transform: translate3d(0, -14px, 0) rotate(-0.8deg); }
}

/* ---------- Floating panels, cut from the mockup ----------
   Small chips that carry one line of the builder's own UI out of
   the browser window and onto the shape. Live type rather than
   pixels, so they stay sharp at any zoom. */
.hero-float {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--white);
  border: 1px solid var(--slate-200);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-lg);
}

.hero-float__dot {
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: var(--r-md);
  background: linear-gradient(140deg, var(--brand-100) 0%, var(--brand-50) 60%, var(--white) 100%);
  border: 1px solid var(--brand-100);
  color: var(--brand-600);
}

.hero-float__dot svg {
  width: 17px;
  height: 17px;
}

.hero-float strong {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 650;
  letter-spacing: -0.005em;
  color: var(--ink-900);
}

.hero-float span {
  display: block;
  font-size: var(--fs-xs);
  color: var(--slate-500);
}

.hero-float--tr {
  top: -3%;
  right: -4%;
}

.hero-float--bl {
  bottom: 4%;
  left: -5%;
}

@media (max-width: 900px) {
  .hero-float {
    display: none;
  }
}

/* ---------- Framed photograph (the "Why it matters" split) ----------
   The Titan inbox is a stock photo, not a transparent cut-out, so it keeps
   the rounded frame and gains a soft ambient shadow — it reads as a
   photograph sitting ON the section rather than a screenshot clipped to it. */
.split__media--framed {
  padding: 0;
  background: var(--white);
  box-shadow: var(--sh-xl);
}

.split__media--framed img {
  display: block;
  width: 100%;
  height: auto;
}

/* ============================================================
   MAIL IN FLIGHT — the ambient "mail being sent" layer.
   ------------------------------------------------------------
   Soft envelopes drifting up-and-right at ~45° across the hero,
   fading in, cruising, and fading out before they reach the band's
   edge. Pure CSS: no canvas, no JS, no layout thrash — each mail is
   one element animating only transform + opacity (compositor-only).

   The field is self-steady because every mail carries a negative
   animation-delay, so the instant the hero paints the envelopes are
   already mid-flight and the composition reads as continuous rather
   than as a sequence of launches.

   LAYERING: the wallpaper lives on `.page-hero--split::after` at
   z-index -1 and the copy/devices sit at z-index 1, so this layer at
   z-index 0 slides cleanly between them — visible in the negative
   space, never competing with the headline. `overflow: hidden` is the
   backstop for the fade-out; the keyframes fade to zero before the
   path reaches the top/right boundary anyway. */
.mail-stream {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.mail-stream__mail {
  --peak: 0.6;
  position: absolute;
  left: var(--x);
  bottom: var(--y);
  /* A 52px box carrying a 40px glyph — deliberately generous. At the
     previous 26px the envelopes read as specks at arm's length; the field
     is sparse enough to carry the extra size without crowding the copy. */
  width: 52px;
  height: 52px;
  color: #ffffff;
  /* A soft DARK-teal shadow, not a white glow: on the bright mint/white
     surface a white glyph needs a darker edge to read, so the envelopes
     pop as little "envelopes of light" instead of vanishing into it. */
  filter: drop-shadow(0 4px 12px rgba(11, 94, 80, 0.38));
  opacity: 0;
  will-change: transform, opacity;
  animation: mailRise var(--dur) var(--ease-out) var(--delay) infinite;
}

.mail-stream__mail svg {
  display: block;
  width: 40px;
  height: 40px;
  margin: 6px;
}

/* Fade in fast (a letter launched), hold through the middle, fade out
   BEFORE 100% so the glyph never visually collides with the hero edge.
   The trajectory is up and right: --drift ≈ --rise reads as ~45°. The
   icon itself only tilts a few degrees — a letter in a draft, not a
   hard rotation, which would read as a rendering glitch.

   THE FADE FINISHES AT 88%, NOT 100%. This is the difference between a
   glyph dissolving mid-flight and a glyph being switched off at the
   layer's clip edge. Every layer is clipped by an `overflow: hidden`
   box, and the travel ends on the frame at 100%, so a fade that only
   reaches zero *there* means the glyph spends its last ~12% of travel
   at full `--peak` and is guillotined by the clip boundary — a hard
   straight cut in the middle of the band. Retuning the fall to 88%
   leaves a 12% tail at `opacity: 0`: the glyph is already invisible by
   the time it would touch the edge, so the boundary is never seen. The
   `80%` -> `88%` fall is an 8-point band, wide enough that the fade
   reads as a dissolve rather than a blink at every `--dur` in use
   (11s-15s), and the icon is held invisible through the final frame so
   the loop restart is a clean pop-in at 0%, not a flash. */
@keyframes mailRise {
  0% {
    transform: translate3d(0, 0, 0) rotate(var(--angle)) scale(var(--scale));
    opacity: 0;
  }
  12% {
    opacity: var(--peak);
  }
  80% {
    opacity: var(--peak);
  }
  88% {
    opacity: 0;
  }
  100% {
    transform: translate3d(var(--drift), calc(var(--rise) * -1), 0)
      rotate(var(--angle)) scale(var(--scale));
    opacity: 0;
  }
}

/* Tablet keeps twelve of the eighteen; the trailing six drop away so the
   field doesn't crowd a narrower hero. */
@media (max-width: 900px) {
  .mail-stream__mail:nth-child(n + 13) {
    display: none;
  }
}

/* The teal hero runs twelve envelopes rather than eighteen, so its
   tablet cutoff steps in earlier — same intent, tuned to the count. */
@media (max-width: 900px) {
  .page-hero--teal .mail-stream__mail:nth-child(n + 9) {
    display: none;
  }
}

/* Phone: no mail at all. The layer is pure ambience, and a 390px
   viewport gets its read from the copy, not the texture. */
@media (max-width: 719px) {
  .mail-stream {
    display: none;
  }
}

/* Reduced motion: the flight is what moves, so the loop stops — but the
   envelopes remain as a faint static field (same principle as the dot
   matrix, which keeps its texture and only drops the drift). */
@media (prefers-reduced-motion: reduce) {
  .mail-stream__mail {
    animation: none;
    opacity: 0.35;
  }
}

/* ============================================================
   LOCKS IN FLIGHT — Managed SSL / SSL Certificates.
   ------------------------------------------------------------
   The same ambient layer as MAIL IN FLIGHT above: glyphs drifting
   up-and-right at ~45°, fading in, cruising, fading out before the
   band's edge. Pure CSS, transform + opacity only, negative delays
   so the field is self-steady from the first paint.

   It reuses `@keyframes mailRise` VERBATIM rather than restating it.
   The motion is the site-wide "things in flight" signature and the two
   layers should be indistinguishable in behaviour; duplicating the
   keyframes would let them drift apart on the next tune. Only the
   class name, the glyph size and the shadow colour are new.

   WHY A SEPARATE CLASS AND NOT `.mail-stream` ON THE SSL PAGES: the
   mail layer hardcodes `color: #ffffff` plus a DARK-TEAL drop shadow
   (`rgba(11, 94, 80, 0.38)`) tuned for the mint band. A padlock on the
   blue SSL band or the green/cyan Managed SSL band needs a different
   dark edge to read, and the shadow is a `filter`, not an inherited
   colour — so it cannot be overridden sensibly from the page. Hence
   one rule here plus one shadow override per colourway below.

   GLYPH SIZE: 40px like the envelope would read heavy — a padlock is a
   denser, more solid silhouette than a thin envelope outline, and at 40px
   a field of them competes with the copy instead of sitting behind it.
   32px keeps the same visual weight as the envelopes. The 48px box
   (down from 52px) preserves the generous hit area the original
   comment argues for, scaled to the smaller glyph. ---------------------- */
.lock-stream {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.lock-stream__lock {
  --peak: 0.6;
  position: absolute;
  left: var(--x);
  bottom: var(--y);
  width: 48px;
  height: 48px;
  color: #ffffff;
  /* Default edge, matching the mail layer's teal, so the class is still
     sane if it is ever dropped on a mint band without an override. */
  filter: drop-shadow(0 4px 12px rgba(11, 94, 80, 0.38));
  opacity: 0;
  will-change: transform, opacity;
  animation: mailRise var(--dur) var(--ease-out) var(--delay) infinite;
}

.lock-stream__lock svg {
  display: block;
  width: 32px;
  height: 32px;
  margin: 8px;
}

/* Per-colourway edges, matching the accent each band already uses so the
   padlocks look like part of the page rather than pasted on.

   SSL Certificates (blue #C7E0FA band, accent #175CD3): a deep navy edge.
   Managed SSL (cyan #CBEFE7 band, accent #0B7A63): the house emerald-teal. */
.page-hero--blue .lock-stream__lock {
  filter: drop-shadow(0 4px 12px rgba(16, 47, 110, 0.40));
}

.page-hero--cyan .lock-stream__lock {
  filter: drop-shadow(0 4px 12px rgba(6, 95, 82, 0.40));
}

/* Tablet: keep twelve of the eighteen, same tier as the mail layer. */
@media (max-width: 900px) {
  .lock-stream__lock:nth-child(n + 13) {
    display: none;
  }
}

/* Phone: no locks at all — pure ambience, and a 390px viewport gets its
   read from the copy. Matches the mail layer's cutoff exactly. */
@media (max-width: 719px) {
  .lock-stream {
    display: none;
  }
}

/* Reduced motion: the flight is what moves, so the loop stops but the
   glyphs remain as a faint static field — the same call the mail layer
   and the dot matrix make. */
@media (prefers-reduced-motion: reduce) {
  .lock-stream__lock {
    animation: none;
    opacity: 0.35;
  }
}

/* The hero art float (heroFloatSlow / heroFloatFast) is also taken off
   the page under reduced motion — a still, complete image, not a frozen
   frame of a loop. */
@media (prefers-reduced-motion: reduce) {
  .hero-visual--float > img,
  .float-fast {
    animation: none;
  }
}

/* ============================================================
   SNAPSHOTS IN FLIGHT — Website Backup.
   ------------------------------------------------------------
   The third ambient layer, the same flight as MAIL IN FLIGHT and
   LOCKS IN FLIGHT above: glyphs drifting up-and-right at ~45°,
   fading in, cruising, fading out before the band's edge. Pure
   CSS, transform + opacity only, negative delays so the field is
   self-steady from the first paint. It reuses `@keyframes
   mailRise` VERBATIM for the same reason the locks do — the
   motion is the site-wide "things in flight" signature and the
   three layers must be indistinguishable in behaviour.

   TWO GLYPHS, NOT ONE. This is the only flying field on the site
   that alternates shapes, and it is deliberate: the page makes
   exactly two promises — a CLOCK (the daily snapshot, the
   point-in-time you can return to) and a FILE/DOCUMENT (the
   files and database that were captured). Alternating them makes
   the layer say the product's own two nouns instead of being a
   decorative texture that could sit on any page.

   THE SHADOW is a deep cyan (`rgba(4, 88, 112, 0.42)`), for the
   same reason the mail layer carries a dark teal on its mint
   band: the glyphs are white and the surface behind them is a
   pale cyan, so a WHITE glow would vanish. The dark cyan edge
   makes them read as little "snapshots of light" and ties them
   to the page's own accent rather than to the house emerald the
   `strong` default would have implied.

   GLYPH SIZE: 34px, between the envelope (40) and the padlock
   (32). A clock is a dense, closed ring — heavier than an
   envelope outline — and a document is a mid-weight solid, so
   34px averages the two shapes to the same visual weight the
   other fields carry. The 50px box preserves the generous hit
   area (and the artwork-clearance the negative `--x`s rely on)
   scaled to the smaller glyph.

   WHY THE LAYER BLEEDS PAST ITS GRID SLOT. The stream is a child
   of `.product-hero__inner`, which lives inside `.product-hero
   .container--wide` — a max-width-1440px, padded-inline box. Its
   `inset: 0` therefore clips at the CONTAINER's content edge, not
   the BAND's, leaving ~48px of dead band to the right of every
   glyph. The two right-most columns (`--x: 83%` and `88%`) push
   their boxes past that edge mid-flight, so their `overflow:
   hidden` boundary cuts them — a hard vertical guillotine in open
   band, ~48px inside the page edge. The fix is one line: pull the
   inline edges outward past the container's padding
   (`calc(-1 * clamp(...))`, the same function `product.css` uses
   for `padding-inline`) so the clip boundary moves out to the band
   and a glyph travels the full visible width before it fades. The
   extra `--backup-stream-bleed` gives a little more headroom so
   the outermost glyphs' `--drift` clears the edge on the frame
   before the 88% fade completes. `.page-hero`'s own `overflow:
   hidden` is still the scrollbar backstop, so the bleed can never
   cost a horizontal scroll. ----------------------------- */
.backup-stream {
  position: absolute;
  inset: 0 calc(-1 * (clamp(1.25rem, 3.4vw, 3rem) + var(--backup-stream-bleed, 3rem)));
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.backup-stream__icon {
  --peak: 0.6;
  position: absolute;
  left: var(--x);
  bottom: var(--y);
  width: 50px;
  height: 50px;
  color: #ffffff;
  filter: drop-shadow(0 4px 12px rgba(4, 88, 112, 0.42));
  opacity: 0;
  will-change: transform, opacity;
  animation: mailRise var(--dur) var(--ease-out) var(--delay) infinite;
}

.backup-stream__icon svg {
  display: block;
  width: 34px;
  height: 34px;
  margin: 8px;
}

/* Tablet: keep twelve of the eighteen, the same tier the mail and lock
   layers step down to. */
@media (max-width: 900px) {
  .backup-stream__icon:nth-child(n + 13) {
    display: none;
  }
}

/* Phone: no glyphs at all — pure ambience, and a 390px viewport gets its
   read from the copy. Matches the other two layers' cutoff exactly. */
@media (max-width: 719px) {
  .backup-stream {
    display: none;
  }
}

/* Reduced motion: the flight is what moves, so the loop stops but the
   glyphs remain as a faint static field — the same call the mail layer,
   the lock layer and the dot matrix all make. */
@media (prefers-reduced-motion: reduce) {
  .backup-stream__icon {
    animation: none;
    opacity: 0.35;
  }
  .backup-stream__icon {
    animation: none;
    opacity: 0.35;
  }
}

/* ============================================================
   ENTRANCE — the split hero's choreographed arrival
   ------------------------------------------------------------
   The product heroes (`product.css`) and the domains hero
   (`domains-hero.css`) tag each copy block with `data-hero-enter`
   plus an inline `--enter-delay` and step them in with a blur +
   22px rise. The split hero's copy carries none of that, so the
   whole column used to just appear while the artwork faded in
   beside it — the "loads flat" difference between these pages and
   the hosting heroes.

   The copy has a fixed, known shape (label, h1, lead, button row,
   then an optional price) and it is the SAME shape on all seven
   `.page-hero--split` pages, so the same arrival is driven here
   structurally, with no markup change: each direct child rises on
   the product pages' own cadence (0 / 80 / 220 / 320 / 420 / 520
   ms). CSS-only, `both` fill so nothing flashes, keyed off
   `html.js` (content is never hidden if scripts fail) and only
   under no-preference for motion. The artwork column and the strip
   keep their existing `data-reveal`.
   ============================================================ */
@keyframes splitHeroEnter {
  from { opacity: 0; transform: translate3d(0, 22px, 0); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: none; }
}

/* The artwork arrives with the copy (the product hero's productRise), not a bare
   scroll-reveal fade, so the split hero reads as one choreography. */
@keyframes splitHeroRise {
  from { opacity: 0; transform: translate3d(0, 60px, 0) scale(0.96); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: no-preference) {
  html.js .page-hero--split .page-hero__copy > * {
    animation: splitHeroEnter 900ms var(--ease-out) both;
  }
  html.js .page-hero--split .page-hero__copy > *:nth-child(2) { animation-delay: 80ms; }
  html.js .page-hero--split .page-hero__copy > *:nth-child(3) { animation-delay: 220ms; }
  html.js .page-hero--split .page-hero__copy > *:nth-child(4) { animation-delay: 320ms; }
  html.js .page-hero--split .page-hero__copy > *:nth-child(5) { animation-delay: 420ms; }
  html.js .page-hero--split .page-hero__copy > *:nth-child(6) { animation-delay: 520ms; }

  /* The hero artwork and the trust strip step in too, matching the product
     hero's productRise + strip productEnter, instead of sitting on the
     scroll-reveal fade while only the text column animates. */
  html.js .page-hero--split .hero-visual {
    animation: splitHeroRise 1300ms var(--ease-out) 150ms both;
  }
  html.js .page-hero--split .product-hero__strip {
    animation: splitHeroEnter 900ms var(--ease-out) 620ms both;
  }
}
