/* ============================================================
   The apex splash. One screen, no scripting: everything here is
   finished CSS — nothing waits on a reveal.

   NOTE: CSS ships to the live site verbatim — comments here are
   public. Keep internal names out of them.
   ============================================================ */
body.sp-body { margin: 0; background: var(--surface-dark); }

/* ---------- vertical rhythm, and the one screen ----------
   This page is a router with no nav: if it scrolls, the legal line falls
   under the fold on a laptop and there is nothing above it worth scrolling
   for. The content stands about 674px tall on a wide window, so anything
   shorter than that overflowed — a 720p screen was losing 41px of it.

   The five values below are the only vertical measurements here that are
   rhythm rather than meaning, so they are the five that give. Each one is
   written as its own value minus a share of the shortfall, and each share
   is that value's own slack over the 80px the taper runs across, so they
   all reach their floor together at 600px and none collapses first.

   The clamp is the gate. Above 680px tall the expression exceeds the
   maximum and every value resolves to exactly what it was, so a normal
   window is untouched and there is no threshold to cross. Below 600px the
   page scrolls again, which by then is the honest answer. */
.sp {
  position: relative; overflow: hidden; box-sizing: border-box;
  min-height: 100vh; min-height: 100dvh;
  display: flex; flex-direction: column;
  align-items: center;
  padding: clamp(24px, calc(48px - (680px - 100vh) * 0.3), 48px) 24px 0;
  font-family: var(--font-sans);
  color: var(--color-warm-50);
}
.sp-inner {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: center;
  text-align: center; width: 100%; max-width: 980px;
  margin: auto 0;
}
/* The mark slot scaled by the lockup/mark width ratio (294.808 / 221.374)
   so the wordmark renders at exactly the size it always had. The lockup is
   the mark's height, so only width moves and the page rhythm does not. */
.sp-mark { width: clamp(199.76px, 22.639vw, 276.99px); height: auto; color: #fff; }
/* The identity stack: three lines, three registers. The title names the
   thing, its sub says what that means, and the tail drops a register — the
   supporting line, not a second lead. One block, so the arrival animation
   and the rhythm taper treat it as the sentence always was: a single beat
   between the mark and the doors. */
.sp-id {
  display: flex; flex-direction: column; align-items: center;
  margin: clamp(16px, calc(24px - (680px - 100vh) * 0.1), 24px) 0
          clamp(28px, calc(48px - (680px - 100vh) * 0.25), 48px);
}
.sp-id p { margin: 0; }
.sp-id-title {
  font-size: clamp(19px, 1.9vw, 23px); font-weight: 800; letter-spacing: -0.01em;
  line-height: 1.25; color: #fff;
}
.sp-id-sub {
  font-size: clamp(16px, 1.5vw, 18px); line-height: 1.6; text-wrap: balance;
  color: rgba(233, 228, 218, 0.7);
  max-width: min(48ch, 100%);
  margin-top: 6px;
}
/* (The connect-once tail line was removed from this page entirely,
   2026-09-02 — its message lives on /us and Global.) */
/* Two doors side by side, and the doc centre spanning them: the surfaces
   are a choice between, documentation is open to whichever you picked. The
   layout says that so the copy does not have to. */
.sp-cards {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  /* Uneven on purpose. The two doors sit close because they are one choice;
     the doc centre sits further off because it is not part of that choice.
     Proximity is the channel that carries grouping, so it does the work
     without demoting the third card by weight — which is how a tertiary
     option ends up looking disabled. */
  column-gap: var(--sp-gutter); row-gap: var(--sp-rowgap);
  width: 100%; max-width: 640px; margin: 0 auto;
  /* The invariant, not the numbers: the gutter stays clearly under the row
     gap. Set them equal and the three cards read as one rank of three
     equivalent options, which is the one thing this layout exists to deny.
     The gutter is 24 rather than 16 because it is no longer empty — the drop
     to the doc centre runs down the middle of it, between two lit inner
     rims, and 16 left a hairline 7.5px off each edge: a seam, not a gap. */
  --sp-gutter: 24px;
  --sp-rowgap: 36px;
  /* A stacking context, so the join can sit behind the cards without
     escaping into the page. */
  position: relative; z-index: 0;
}

/* ---------- the join ----------
   One line under both doors, and a drop from its middle to the doc centre:
   two doors joined, and a third card hanging off that join rather than
   standing beside it. The layout says it so the copy does not have to.

   Held to the width of the cards. It used to run the full viewport and fade
   off both edges, which laid a hairline straight across the horizon glyph's
   silhouette — two ambient marks of the same weight crossing, with no way
   for the eye to tell which edge belonged to which. Ending where the doors
   end keeps the line inside its own subject, and leaves no window shape
   where it can wander back over the glyph.

   It stretches across row one so its midpoint is the doors' midpoint with no
   magic number, and drops through the row gap to the doc centre. Behind the
   cards, so what reads is the gutter between the doors — and, wherever the
   glass enhancement runs, the whole span faintly through them. */
/* Everything is placed explicitly. An explicitly-placed item is positioned
   before auto-placement runs, so a spine claiming row 1 on its own sent the
   auto-placed doors into row 2 and left a 0px row above them. */
.sp-cards > .sp-card:nth-child(1) { grid-row: 1; grid-column: 1; }
.sp-cards > .sp-card:nth-child(2) { grid-row: 1; grid-column: 2; }
.sp-cards > .sp-card--wide { grid-row: 2; grid-column: 1 / -1; }
.sp-spine {
  grid-row: 1; grid-column: 1 / -1;
  align-self: stretch;
  position: relative; z-index: -1;
  width: 100%; pointer-events: none;
}
.sp-spine::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: 1px;
  background: linear-gradient(90deg,
      transparent 0%,
      rgba(127, 216, 210, 0.30) 24%,
      rgba(127, 216, 210, 0.46) 50%,
      rgba(127, 216, 210, 0.30) 76%,
      transparent 100%);
}
.sp-spine::after {
  content: ""; position: absolute;
  left: 50%; top: 50%; bottom: calc(-1 * var(--sp-rowgap));
  width: 1px; transform: translateX(-0.5px); transform-origin: 50% 0;
  background: linear-gradient(180deg,
      rgba(127, 216, 210, 0.46), rgba(127, 216, 210, 0.20));
}
.sp-card {
  display: flex; flex-direction: column; text-align: left;
  text-decoration: none; color: inherit;
  border: 1px solid rgba(233, 228, 218, 0.12);
  border-radius: var(--radius-card);
  padding: 22px 24px 20px;
  /* Opaque baseline, glass as the enhancement — the additive form, so a
     reader who has asked their OS for less transparency gets a solid card
     rather than a degraded one. Same contract as everything else here:
     it fails to a finished state. */
  background: rgba(24, 40, 38, 0.92);
  /* ⚠️ No drop shadow. The old one measured 1.29:1 against this ground —
     not subtle, absent. A dark object cannot cast a visible shadow onto a
     dark ground; lift on dark comes from light instead: an edge the light
     catches, contact at the base, and the fill's own colour spilling out. */
  /* Each card's inner light lives in these two variables — the doors
     override them with their angled stacks below — so the hover and focus
     rules can compose light + glow once, and every card gets the same
     glow from the same declaration. */
  --sp-light:       inset 0  1px 0 0     rgba(255, 255, 255, 0.16),
                    inset 0 -1px 0 0     rgba(0, 0, 0, 0.22),
                    inset 0 16px 40px -28px rgba(255, 255, 255, 0.10);
  --sp-light-hover: inset 0  1px 0 0     rgba(255, 255, 255, 0.22),
                    inset 0 -1px 0 0     rgba(0, 0, 0, 0.26),
                    inset 0 16px 40px -28px rgba(255, 255, 255, 0.14);
  --sp-glow: 0 16px 40px -18px rgba(19, 166, 160, 0.45);
  box-shadow: var(--sp-light);
  transition: background var(--duration-micro) var(--ease-remyt),
              border-color var(--duration-micro) var(--ease-remyt),
              box-shadow var(--duration-standard) var(--ease-remyt),
              transform var(--duration-micro) var(--ease-remyt);
}
/* Shared with keyboard focus, which previously got a ring and nothing else. */
.sp-card:hover,
.sp-card:focus-visible {
  background: rgba(33, 53, 51, 0.94);
  /* ⚠️ Brighter hue at LOWER alpha. #13A6A0 at 0.60 measured 2.73:1 against
     the ground; #7FD8D2 at 0.50 reaches 3.57:1 using less opacity. On a dark
     ground, hue buys separation more cheaply than opacity does. */
  border-color: rgba(127, 216, 210, 0.50);
  transform: translateY(-3px);
  box-shadow: var(--sp-light-hover), var(--sp-glow);
}
.sp-card:hover .sp-arrow,
.sp-card:focus-visible .sp-arrow { transform: translateX(4px); }

@media (prefers-reduced-transparency: no-preference) {
  .sp-card {
    background: rgba(233, 228, 218, 0.08);
    -webkit-backdrop-filter: blur(18px) saturate(1.15);
    backdrop-filter: blur(18px) saturate(1.15);
  }
  .sp-card:hover,
  .sp-card:focus-visible { background: rgba(233, 228, 218, 0.13); }
}

/* A real press, not the absence of a lift. The old rule only cancelled
   translateY, so a touch device — which never hovers, so never lifted —
   got no feedback at all. The light stops reaching the top edge: that is
   what pressing a lit object looks like. */
.sp-card:active {
  transform: none;
  box-shadow: inset 0 2px 6px 0 rgba(0, 0, 0, 0.28),
              inset 0 -1px 0 0 rgba(0, 0, 0, 0.10);
  transition-duration: 60ms;
}

/* ⚠️ The ring changes hue, not just width. Every ambient light on this page
   is teal — halo, beam, glyph, go-line, hover rim — so a teal ring is the
   least separable colour available. The dark collar fills the 3px offset so
   the indicator controls its own adjacent colour instead of inheriting
   whatever the wash is doing there. `outline` stays load-bearing: outlines
   survive forced-colors mode, box-shadow does not. */
.sp-card:focus-visible {
  outline: 3px solid var(--color-arrived-lift-soft);
  outline-offset: 3px;
  box-shadow: 0 0 0 3px rgba(20, 17, 13, 0.85),
              var(--sp-light-hover), var(--sp-glow);
}

/* The doc centre spans both doors: a modifier, so it must sit after the
   base card it modifies. */
.sp-card--wide {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: 1fr auto;
  align-items: center; column-gap: 22px;
  padding-top: 18px; padding-bottom: 18px;
  position: relative;
}
/* (The doc-centre card's corner brackets were removed 2026-09-02: their
   square angles fought the card's 20px radius, and once the corporate
   lockup landed on the page's top mark they were a second bracket instance
   on one screen. The register is carried by the lockup; the card is carried
   by its copy.) */
/* ---------- lit as one surface ----------
   The beam on this page falls from the top centre, so the two doors are lit
   from between them: the left card catches it on its top right, the right
   card on its top left. Identical highlights on both made them read as two
   separate objects sitting under the same light; angling them makes the
   light appear to fall across one surface with a seam in it.

   ⚠️ This is the opposite of the obvious reading. Lighting the outer corners
   would put a source outside each card — two lights, which is what the flat
   version already implied. There is one light here and it is in the middle. */
/* Only the light variables are overridden here — never box-shadow itself.
   Setting box-shadow at this specificity is how the doors once lost the
   hover glow the doc centre had: it out-ranked the shared hover rule. */
.sp-cards > .sp-card:nth-child(1) {
  --sp-light:       inset 0  1px 0 0     rgba(255, 255, 255, 0.16),
                    inset -1px 0 0 0     rgba(255, 255, 255, 0.09),
                    inset 0 -1px 0 0     rgba(0, 0, 0, 0.22),
                    inset -14px 16px 40px -30px rgba(255, 255, 255, 0.16);
  --sp-light-hover: inset 0  1px 0 0     rgba(255, 255, 255, 0.22),
                    inset -1px 0 0 0     rgba(255, 255, 255, 0.12),
                    inset 0 -1px 0 0     rgba(0, 0, 0, 0.26),
                    inset -14px 16px 40px -30px rgba(255, 255, 255, 0.20);
}
.sp-cards > .sp-card:nth-child(2) {
  --sp-light:       inset 0  1px 0 0     rgba(255, 255, 255, 0.16),
                    inset 1px 0 0 0      rgba(255, 255, 255, 0.09),
                    inset 0 -1px 0 0     rgba(0, 0, 0, 0.22),
                    inset 14px 16px 40px -30px rgba(255, 255, 255, 0.16);
  --sp-light-hover: inset 0  1px 0 0     rgba(255, 255, 255, 0.22),
                    inset 1px 0 0 0      rgba(255, 255, 255, 0.12),
                    inset 0 -1px 0 0     rgba(0, 0, 0, 0.26),
                    inset 14px 16px 40px -30px rgba(255, 255, 255, 0.20);
}

.sp-card--wide .sp-sub { margin-top: 3px; }
.sp-card--wide .sp-go { grid-column: 2; grid-row: 1 / span 2; margin-top: 0; }
.sp-name { font-size: 17px; font-weight: 800; color: #fff; }
/* 0.72, not 0.6. The teal wash behind these cards lifts the ground under
   the fill, and at 0.6 the helper line measures 3.98:1 where the wash is
   strongest — under AA. 0.72 holds it at 4.98:1 across the whole page. */
.sp-sub { font-size: 13.5px; line-height: 1.55; color: rgba(233, 228, 218, 0.72); margin-top: 6px; }
/* ⚠️ This chip is the whole answer to "it doesn't read as a button".
   Nothing else on the card can be: the fill measures 1.24:1 against the
   ground and the hover fill change is 1.15:1 — imperceptible — and no
   translucent fill on this ground clears 1.81:1 in either direction. So the
   separation cannot come from the glass. It comes from one painted element
   that can be measured: the chip's edge reads 3.54:1 against the card fill.

   It stays a LABEL, not a raised button. It is not separately focusable and
   must not imply a second target inside a card that is already one link. */
.sp-go {
  font-size: 13px; font-weight: 700; margin-top: 18px;
  align-self: start;
  padding: 7px 13px;
  border-radius: var(--radius-pill);
  background: rgba(19, 166, 160, 0.22);
  border: 1px solid rgba(127, 216, 210, 0.65);
  color: var(--color-arrived-lift-soft);
  transition: background var(--duration-micro) var(--ease-remyt),
              border-color var(--duration-micro) var(--ease-remyt),
              color var(--duration-micro) var(--ease-remyt);
}
/* ⚠️ Hover must BRIGHTEN. This went the other way: the card lightens on
   hover while the go-line darkened to --color-arrived-lift, which lands at
   2.91:1 on the hovered fill — the one state a person is looking straight
   at was the only one failing AA. Keyboard focus gets the same treatment;
   it was getting a ring and nothing else. */
.sp-card:hover .sp-go,
.sp-card:focus-visible .sp-go {
  color: #C8F0EC;
  background: rgba(19, 166, 160, 0.34);
  border-color: rgba(127, 216, 210, 0.85);
}

/* The wordmark's m as a low horizon — this surface's one crop. */
.sp-mfield {
  position: absolute; z-index: 1; pointer-events: none;
  left: 50%; transform: translateX(-50%);
  bottom: -34%; width: 110%; min-width: 760px; height: auto;
  color: rgba(19, 166, 160, 0.10);
}
.sp-foot {
  position: relative; z-index: 2;
  padding: clamp(26px, calc(48px - (680px - 100vh) * 0.275), 48px) 0
           clamp(18px, calc(26px - (680px - 100vh) * 0.1), 26px);
  font-size: 12px; color: rgba(233, 228, 218, 0.42);
}
.sp-foot p { margin: 0; }

@media (max-width: 620px) {
  /* Stacked, the same grouping has to be said in the one axis left: the
     doors keep the gutter's spacing between them, and the doc centre keeps
     the row gap's. */
  .sp-cards { grid-template-columns: 1fr; row-gap: var(--sp-gutter); }
  /* Stacked, the doors are no longer side by side, so a line across them
     joins nothing. It goes rather than rotating into a different claim. */
  .sp-cards > .sp-card:nth-child(1) { grid-row: 1; }
  .sp-cards > .sp-card:nth-child(2) { grid-row: 2; grid-column: 1; }
  .sp-cards > .sp-card--wide { grid-row: 3; }
  .sp-spine { display: none; }
  .sp-card--wide {
    grid-template-columns: 1fr; row-gap: 12px;
    margin-top: calc(var(--sp-rowgap) - var(--sp-gutter));
  }
  .sp-card--wide .sp-go { grid-column: 1; grid-row: auto; }
  .sp-mfield { min-width: 560px; bottom: -14%; }
}
@media (prefers-reduced-motion: reduce) {
  .sp-card, .sp-card:hover { transform: none; }
}

/* The light source the surfaces open with, so the front door reads as the
   same building. Both settle once and hold: nothing on this page loops. */
/* The surfaces light their heroes from the top-left because the mark sits
   there. Here the mark is centred, so the light is too: it comes down the
   middle and lands on the wordmark. Same instrument, aimed at the subject. */
.sp-halo {
  position: absolute; z-index: 0; pointer-events: none;
  top: -300px; left: 50%; transform: translateX(-50%);
  width: min(1150px, 130%); height: 760px;
  background: radial-gradient(ellipse 46% 52% at 50% 30%,
              rgba(127, 216, 210, 0.26), rgba(19, 166, 160, 0.13) 42%, transparent 72%);
  filter: blur(34px);
}
/* The shaft: a soft column widening as it falls toward the mark. */
.sp-beam {
  position: absolute; z-index: 0; pointer-events: none;
  top: -160px; left: 50%; transform: translateX(-50%);
  width: min(760px, 108%); height: 660px;
  background: linear-gradient(180deg,
              rgba(233, 228, 218, 0.15) 0%,
              rgba(127, 216, 210, 0.07) 34%,
              transparent 78%);
  /* No clip-path: a polygon gives the shaft a cut edge, and blurring a cut
     edge only makes a soft line — it is still a line. The mask fades the
     light out in every direction instead, so there is nothing to see the
     end of. */
  -webkit-mask-image: radial-gradient(ellipse 58% 96% at 50% -6%, #000 24%, rgba(0,0,0,0.35) 58%, transparent 82%);
  mask-image: radial-gradient(ellipse 58% 96% at 50% -6%, #000 24%, rgba(0,0,0,0.35) 58%, transparent 82%);
  filter: blur(30px);
}
/* The colour the page was missing: teal rising under the flare, so the
   ground is not a flat brown behind a cool light. */
.sp::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(ellipse 70% 46% at 50% 0%, rgba(19, 166, 160, 0.20), transparent 68%),
    radial-gradient(ellipse 90% 58% at 50% 106%, rgba(10, 117, 115, 0.30), transparent 72%);
}

/* The go-line carries the same long-stem arrow as the footer crossings. */
.sp-go { display: inline-flex; align-items: center; gap: 8px; }
.sp-arrow { flex: none; transition: transform var(--duration-micro) var(--ease-remyt); }

/* Arrival: the mark, then the identity stack, then the doors, each settling
   once. Prepared states live only where motion is welcome, so a reduced-motion
   visitor gets the finished page with nothing hidden and nothing to wait for. */
@media (prefers-reduced-motion: no-preference) {
  .sp-mark    { animation: sp-rise 0.66s var(--ease-remyt) 0.04s both; }
  .sp-id      { animation: sp-rise 0.66s var(--ease-remyt) 0.16s both; }
  .sp-card:nth-child(1) { animation: sp-rise 0.62s var(--ease-remyt) 0.30s both; }
  .sp-card:nth-child(2) { animation: sp-rise 0.62s var(--ease-remyt) 0.38s both; }
  .sp-card:nth-child(3) { animation: sp-rise 0.62s var(--ease-remyt) 0.46s both; }
  /* The join draws itself after the doors have landed — it is describing a
     relationship between them, so it cannot arrive before they do. Prepared
     states live in the keyframes only: with animation blocked the line is
     simply there, which is the finished state. */
  .sp-spine::before { animation: sp-drawx 0.70s var(--ease-remyt) 0.60s both; }
  .sp-spine::after  { animation: sp-drawy 0.44s var(--ease-remyt) 0.94s both; }
  .sp-foot    { animation: sp-fade 0.7s var(--ease-remyt) 0.62s both; }
  .sp-halo    { animation: sp-fade 1.6s var(--ease-remyt) 0.05s both; }
  .sp-beam    { animation: sp-beamin 1.3s var(--ease-remyt) both; }
}
@keyframes sp-drawx {
  from { opacity: 0; transform: scaleX(0.25); }
  to   { opacity: 1; transform: scaleX(1); }
}
@keyframes sp-drawy {
  from { opacity: 0; transform: translateX(-0.5px) scaleY(0); }
  to   { opacity: 1; transform: translateX(-0.5px) scaleY(1); }
}
@keyframes sp-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes sp-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes sp-beamin {
  from { opacity: 0; transform: translateX(-50%) translateY(-40px) scaleY(0.88); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0) scaleY(1); }
}
