/* ============================================================
 * enclave.css — Enclave page components, lifted out of refined.css
 * so the page can load the same stylesheets as the reference page and
 * therefore inherit its exact type sizes. Holds only the canvas, the
 * readout chips and the certificate mock animation.
 * ============================================================ */

/* the canvas fills its box; in the .ah frame that box is .ah-grid */
.pxh-canvas{ display:block; }
.ah-grid--canvas{ display:block; }
.ah-grid--canvas .pxh-canvas{ position:absolute; inset:0; width:100%; height:100%; }
.ah-grid--canvas .hero-chips{ position:absolute; inset:0; }

.pxh-canvas{position:absolute;inset:0 0 0 50%;z-index:1;width:50%;height:100%;display:block}
@media(max-width:760px){

  .pxh-canvas{inset:88px 0 auto;width:100%;height:42vh;min-height:300px;opacity:1}
}
.pxh--enclave .pxh-canvas{
  inset:auto;
  left:calc(50% + var(--hero-mid));
  top:var(--hero-top);
  width:calc(50% - var(--hero-mid) - var(--hero-gut));
  height:calc(100% - var(--hero-top) - var(--hero-bot));
  border-radius:26px;
  border:1px solid rgba(3,43,59,.1);
  background:linear-gradient(168deg,#0C5F66 0%,#07454F 56%,#053642 100%);
}
@media (max-width:760px){

  .pxh--enclave .pxh-canvas{
    left:16px; top:96px;
    width:calc(100% - 32px);
    height:42vh; min-height:300px;
    border-radius:20px;
  }
}
.mockfx.built .cert-track i,
.mockfx.built .cm-bar i{ width:62%; }
.mockfx.built .cert-track b{ transform:translate(-50%,-50%) scale(1); }
/* ============================================================
 * Hero product readouts (2026-08-19)
 * Small pieces of product over the hero image: an icon, the value,
 * and a live indicator. Teal glass with an accent edge so they read
 * as instrument panels rather than plain labels.
 * ============================================================ */
.hero-chips{
  position:absolute; z-index:3; pointer-events:none;
  left:calc(50% + var(--hero-mid));
  right:var(--hero-gut);
  top:var(--hero-top);
  bottom:var(--hero-bot);
}
.hchip{
  position:absolute;
  display:inline-flex; align-items:center; gap:11px;
  padding:10px 15px 10px 12px;
  border-radius:12px;
  border:1px solid rgba(123,219,211,.34);
  background:linear-gradient(140deg, rgba(8,58,72,.9), rgba(4,32,42,.86));
  -webkit-backdrop-filter:blur(10px) saturate(1.15); backdrop-filter:blur(10px) saturate(1.15);
  box-shadow:0 18px 40px -20px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,.06);
  white-space:nowrap;
  opacity:0; transform:translateY(10px) scale(.97);
  transition:opacity .7s ease, transform .8s var(--scr-ease);
}
/* the accent edge */
.hchip::before{
  content:""; position:absolute; left:0; top:12px; bottom:12px; width:2px;
  border-radius:2px; background:linear-gradient(180deg,var(--teal-bright),rgba(24,219,206,.15));
}
.pxh--enclave.chips-in .hchip{ opacity:1; transform:none; }
.pxh--enclave.chips-in .hchip.mr{ transition-delay:.14s; }
.pxh--enclave.chips-in .hchip.bl{ transition-delay:.28s; }
.hchip-ic{
  display:grid; place-items:center; flex:none;
  width:28px; height:28px; border-radius:8px;
  background:rgba(24,219,206,.13);
}
.hchip-ic svg{
  width:15px; height:15px; fill:none; stroke:var(--teal-bright);
  stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round;
}
.hchip-body{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.hchip b{
  font-size:19px; font-weight:500; color:#fff; line-height:1;
  font-variant-numeric:tabular-nums; letter-spacing:-.015em;
}
.hchip em{
  font-style:normal; font-size:10px; font-weight:600;
  letter-spacing:.14em; text-transform:uppercase; color:var(--aqua);
}
/* the stat chip carries a small fill under its number */
.hchip-bar{
  display:block; height:2px; margin-top:5px; border-radius:2px;
  background:rgba(123,219,211,.18); overflow:hidden;
}
.hchip-bar i{
  display:block; height:100%; width:0; border-radius:2px;
  background:linear-gradient(90deg,var(--teal),var(--teal-bright));
  transition:width 1.6s cubic-bezier(.16,.8,.3,1) .5s;
}
.pxh--enclave.chips-in .hchip-bar i{ width:78%; }
/* the live indicator on the status chips */
.hchip-live{ position:relative; width:7px; height:7px; flex:none; }
.hchip-live i{
  position:absolute; inset:0; border-radius:50%;
  background:var(--teal-bright);
}
.hchip-live::after{
  content:""; position:absolute; inset:0; border-radius:50%;
  border:1px solid var(--teal-bright);
  animation:hchipPing 2.6s cubic-bezier(.2,.6,.3,1) infinite;
}
@keyframes hchipPing{
  0%{ transform:scale(1); opacity:.7; }
  70%{ transform:scale(3.2); opacity:0; }
  100%{ transform:scale(3.2); opacity:0; }
}
.hchip.tl{ left:22px; top:22px; }
.hchip.mr{ right:22px; top:44%; }
.hchip.bl{ left:22px; bottom:24px; }
@media (max-width:1040px){

  .hero-chips{ left:16px; right:16px; top:96px; bottom:auto; height:42vh; min-height:300px; }
  .hchip.mr{ display:none; }
  .hchip b{ font-size:16px; }
  .hchip em{ font-size:9px; }
}
@media (max-width:640px){
 .hchip.bl{ display:none; }
}
@media (prefers-reduced-motion:reduce){

  .hchip{ opacity:1; transform:none; transition:none; }
  .hchip-live::after{ animation:none; opacity:.35; }
  .hchip-bar i{ width:78%; transition:none; }
}
/* ---------- chips: clear the wordmark, and carry a little peach and gold ----------
   The wordmark sits across the middle of the panel, so the right-hand chip
   moves up out of its band. Each chip takes a different accent so the group
   picks up the warm end of the palette rather than reading all-teal. */
.hchip.mr{ top:23% !important; }
.hchip.bl{ bottom:26px !important; }
/* gold on the policy chip */
.hchip.mr::before{ background:linear-gradient(180deg,var(--accent),rgba(252,201,33,.15)); }
.hchip.mr .hchip-ic{ background:rgba(252,201,33,.14); }
.hchip.mr .hchip-ic svg{ stroke:var(--accent); }
.hchip.mr em{ color:#FFE28A; }
.hchip.mr .hchip-live i{ background:var(--accent); }
.hchip.mr .hchip-live::after{ border-color:var(--accent); }
/* peach on the certificate chip */
.hchip.bl::before{ background:linear-gradient(180deg,#F6B9A6,rgba(246,185,166,.15)); }
.hchip.bl .hchip-ic{ background:rgba(246,185,166,.14); }
.hchip.bl .hchip-ic svg{ stroke:#F6B9A6; }
.hchip.bl em{ color:#F8CDBE; }
.hchip.bl .hchip-live i{ background:#F6B9A6; }
.hchip.bl .hchip-live::after{ border-color:#F6B9A6; }
@media (max-width:1040px){

  .hchip.bl{ bottom:auto !important; top:auto; }
}
/* ---------- chip corrections ----------
   No accent bar; icon sits on the left of the row; the warm accent is the
   SideChannel red from the logomark rather than a pastel tint. */
.hero-chips .hchip{
  display:flex !important;
  flex-direction:row !important;
  align-items:center !important;
  padding:11px 15px !important;
}
.hero-chips .hchip::before{ display:none !important; }
.hero-chips .hchip-ic{ align-self:center; }
.hero-chips .hchip-body{ align-items:flex-start; text-align:left; }
/* the certificate chip takes the logomark red */
.hchip.bl .hchip-ic{ background:rgba(233,89,89,.16); }
.hchip.bl .hchip-ic svg{ stroke:#E95959; }
.hchip.bl em{ color:#F09292; }
.hchip.bl .hchip-live i{ background:#E95959; }
.hchip.bl .hchip-live::after{ border-color:#E95959; }
/* the 47-day runway already leaves ~100px of air above the title */

/* ---------- Enclave hero in the asset-intelligence frame (2026-09-02) ----------
   The reference hero is a cell grid; ours is a canvas. The box, border, radius
   and height all come from .ah-grid — these three rules only stop the canvas
   from keeping the half-width geometry it uses in the .pxh hero. */
.ah-grid--canvas{ display:block; }
.ah-grid--canvas .pxh-canvas{ position:absolute; inset:0; width:100%; height:100%; }
.ah-grid--canvas .hero-chips{ position:absolute; inset:0; }


/* ============================================================
 * .efr — Enclave feature row  (third pass)
 *
 * Two things were wrong before. The page already runs hero-dark, band-dark,
 * band-dark either side of this section, so making the rows dark too gave
 * four dark blocks in a row and the whole middle read as one mass. And the
 * three mocks are different heights (a diagram, three cert rows, a table),
 * so the rows carried visibly different weight.
 *
 * So: light and airy, to breathe between the dark bands, separated by
 * hairlines instead of boxes. The media well has ONE fixed height for all
 * three rows and centres whatever mock it is given, which is what makes the
 * set read as even. The mock keeps the white card + glow treatment it was
 * designed for, so a navy panel on a light ground looks seated, not pasted.
 * ============================================================ */
/* The rows carry no panel of their own, so at .m-wrap's 1880px frame width
   their text sat flush against the page edge and read as full-bleed. They get
   their own measure instead — narrower than the frame, and shared with the
   section's lead paragraph so both start on the same left edge. */
.efr-wrap{ width:92vw; max-width:1560px; margin-inline:auto; }
.efr-wrap .sec-head{ max-width:64ch; }
@media(max-width:700px){ .efr-wrap{ width:calc(100% - 44px); } }

.efr{
  display:grid;
  grid-template-columns:1fr;
  gap:clamp(26px,3.2vw,58px);
  align-items:center;
  padding:clamp(34px,4vw,68px) 0;
}
.efr + .efr{ border-top:1px solid var(--m-line,#E1DED6); }
.efr:first-of-type{ padding-top:clamp(26px,3vw,46px); }

@media(min-width:980px){
  .efr{ grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr); }
  .efr.flip .efr-copy{ order:2; }
  .efr.flip .efr-media{ order:1; }
}

/* ---- copy ---- */
.efr-copy{ min-width:0; }
.efr-label{
  display:flex; align-items:center; gap:14px;
  font-size:11px; font-weight:600; letter-spacing:.16em; text-transform:uppercase;
  color:var(--dark-teal,#006B6B);
}
.efr-num{
  font-variant-numeric:tabular-nums; font-weight:600;
  color:var(--teal,#12BAB0);
}
.efr-num::after{
  content:""; display:inline-block; vertical-align:middle;
  width:clamp(18px,2.2vw,34px); height:1px; margin:0 0 2px 12px;
  background:var(--teal,#12BAB0); opacity:.5;
}
.efr-copy h2{
  margin-top:clamp(18px,1.9vw,26px);
  font-size:clamp(27px,2.7vw,42px); line-height:1.07; font-weight:400;
  letter-spacing:-.018em; color:var(--m-navy,#032B3B); max-width:19ch;
}
.efr-copy p{
  margin-top:clamp(15px,1.4vw,20px);
  font-size:clamp(15.5px,1.15vw,17px); line-height:1.7;
  color:var(--text-muted,#4A6470); max-width:52ch;
}
.efr-copy .m-btns{ margin-top:clamp(22px,2.3vw,32px); }

/* ---- media well: one height for all three rows ---- */
.efr-media{
  position:relative; min-width:0;
  display:grid; place-items:center;
  gap:16px;
  min-height:clamp(260px,21vw,330px);
  padding:clamp(18px,2vw,34px);
  border-radius:clamp(18px,2vw,26px);
  overflow:hidden;
  background:
    radial-gradient(52% 58% at 22% 24%, rgba(82,140,204,.34), transparent 70%),
    radial-gradient(56% 62% at 82% 22%, rgba(18,186,176,.30), transparent 70%),
    radial-gradient(60% 58% at 74% 86%, rgba(123,219,211,.36), transparent 70%),
    radial-gradient(46% 52% at 18% 84%, rgba(219,245,227,.85), transparent 72%),
    linear-gradient(150deg,#FFFFFF 0%,#F4F2EE 100%);
}
/* the mock rides in a white card, the treatment it was designed for */
.efr-card{
  width:100%; max-width:min(100%,620px);
  background:#fff; border-radius:18px; padding:11px 11px 0;
  box-shadow:0 34px 70px -34px rgba(3,43,59,.42);
  transition:transform .5s cubic-bezier(.16,.8,.3,1), box-shadow .5s ease;
}
.efr-card .mock{ width:100%; }
.efr-card .mock-diagram{ overflow-x:auto; }
.efr-cap{
  display:flex; align-items:center; gap:9px;
  padding:13px 5px 15px;
  font-size:10.5px; font-weight:600; letter-spacing:.15em; text-transform:uppercase;
  color:var(--slate,#3D5A6B);
}
.efr-cap::before{
  content:""; width:5px; height:5px; flex:none; border-radius:50%;
  background:var(--teal,#12BAB0); box-shadow:0 0 0 3px rgba(18,186,176,.18);
}
.efr:hover .efr-card{
  transform:translateY(-5px);
  box-shadow:0 44px 84px -34px rgba(3,43,59,.48);
}

@media(prefers-reduced-motion:reduce){
  .efr-card, .efr:hover .efr-card{ transition:none; transform:none; }
}
@media(max-width:700px){
  .efr{ padding:26px 0 30px; }
  .efr-media{ min-height:0; padding:18px; border-radius:16px; }
  .efr-copy h2{ font-size:clamp(25px,7.4vw,33px); max-width:none; }
  .efr-copy p{ max-width:none; }
}


/* ============================================================
 * Pinned horizontal track for the three feature rows
 *
 * The section pins for three screen-heights and the track slides sideways,
 * so the page cannot move on until all three items have gone past. Desktop
 * only, and only when motion is welcome: below 990px and under
 * prefers-reduced-motion the rows fall back to the plain vertical stack
 * defined above, which is fully readable on its own.
 *
 * Progress comes from JS as --p (0 -> 1) on .efr-track. Nothing here
 * depends on the script having run: with --p unset the track sits at 0,
 * showing item 01.
 * ============================================================ */
.efr-pin{ position:relative; }
.efr-rail{ display:none; }

@media (min-width:768px) and (prefers-reduced-motion:no-preference){
  /* one viewport of scroll per item, plus one to read the last */
  .efr-pin{ height:calc(100svh * 3); }
  .efr-stage{
    /* pinned BELOW the nav pill (fixed at top:22px, ~68px tall) rather than at
       top:0 with a big padding to clear it — that padding was the gap between
       the section's lead paragraph and the slider. */
    position:sticky; top:var(--efr-nav,96px);
    height:calc(100svh - var(--efr-nav,96px));
    display:flex; flex-direction:column; justify-content:center;
    gap:clamp(22px,3vh,40px);
    padding:0 0 clamp(24px,3vh,40px);
    box-sizing:border-box;
  }
  /* only the track clips — the head and the rail must stay visible */
  .efr-viewport{ flex:1 1 auto; min-height:0; overflow:hidden; }
  .efr-track{
    display:flex; flex:none; height:100%; align-items:stretch;
    width:calc(100% * var(--efr-n,3));
    /* Moved in WHOLE PIXELS, set by enclave.js as --x. A percentage offset
       lands the layer on a fractional pixel and every glyph inside the track
       — the copy column included — gets rasterised soft. Integers are crisp.
       No will-change either: it pins the layer permanently and keeps the
       blur even when the track is standing still. */
    transform:translate3d(var(--x,0px), 0, 0);
  }
  .efr-track > .efr{
    display:block;              /* .efr-inner owns the two columns in here */
    height:100%;
    width:calc(100% / var(--efr-n,3));
    flex:none;
    margin:0; padding:0;
    border-top:0;
  }
  /* inside a pinned panel the content takes the page measure, not the panel */
  .efr-track .efr-inner{
    width:92vw; max-width:1560px; margin-inline:auto; height:100%;
    display:grid; grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);
    gap:clamp(26px,3.2vw,58px); align-items:center;
  }
  /* keep a panel inside one screen on shorter displays */
  /* One rectangle for all three items. The trick is making each mock FIT the
     box rather than size itself: the diagram is an SVG that scales by width,
     so pinning its height and letting preserveAspectRatio letterbox it is
     what stops it being clipped at the bottom. */
  .efr-track .efr-media{ min-height:0; height:min(100%,520px); align-self:center; }
  .efr-track .efr-card{ height:100%; display:flex; flex-direction:column; overflow:hidden; }
  .efr-track .efr-card .mock{ flex:1 1 auto; display:flex; flex-direction:column; min-height:0; }
  .efr-track .efr-card .mock-bar{ flex:none; }
  .efr-track .efr-card .mock-body{ flex:1 1 auto; min-height:0; }
  .efr-track .efr-card .mock-diagram{
    flex:1 1 auto; min-height:0; display:flex; align-items:center;
  }
  .efr-track .efr-card .mock-diagram svg{ width:100%; height:100%; }
  .efr-track .efr-card .efr-cap{ flex:none; }
  .efr-track .efr-copy h2{ font-size:clamp(26px,2.4vw,38px); }

  /* Tablet: the two columns stop fitting side by side, so the panel becomes
     one column — copy on top, mock in whatever height is left. The media row
     is minmax(0,1fr), never auto: an auto row lets the mock ask for its
     natural height and the diagram gets cut off at the bottom of the screen,
     which is exactly what went wrong the first time round. */
  @media (max-width:989px){
    .efr-track .efr-inner{
      grid-template-columns:minmax(0,1fr);
      grid-template-rows:auto minmax(0,1fr);
      gap:clamp(14px,2vh,22px);
      width:calc(100% - 44px);
    }
    .efr-track .efr-copy h2{ font-size:clamp(23px,3.4vw,30px); }
    .efr-track .efr-copy p{ font-size:15px; line-height:1.55; }
    .efr-track .efr-copy .m-btns{ margin-top:clamp(12px,1.8vh,18px); }
    .efr-track .efr-media{ height:100%; min-height:0; padding:14px; border-radius:16px; }
  }
  /* the panel has to hold a heading, a paragraph and the mock inside one
     screen; the same link sits under every capability further down the page */
  @media (max-width:860px){
    .efr-track .efr-copy .m-btns{ display:none; }
  }


  /* progress rail: which of the three you are on */
  .efr-rail{
    display:flex; align-items:center; justify-content:center; gap:10px;
    flex:none;
  }
  /* on the light ground the resting dash needs to be darker than the teal one */
  .efr-dot{ background:rgba(3,43,59,.16); }
  .efr-dot:hover{ background:rgba(3,43,59,.34); }
}

/* outside the pinned range the inner grid is simply the row itself */
@media (max-width:767px), (prefers-reduced-motion:reduce){
  .efr-inner{ display:contents; }
}

/* the section lead sits above the pinned track, in the normal flow */
/* the lead and the slider are one section, so they read as one block */
.efr-lead{ padding-bottom:clamp(10px,1.2vw,18px); }
.efr-lead .m-lede{ margin:0; max-width:64ch; }


/* ============================================================
 * .expe — "Built from Experience": a plain centred panel
 *
 * This carried a 3D echo (two layers receding behind it, the panel travelling
 * forward on scroll). It is gone: just the box now. Type is the .ncol scale
 * the pillar bands use, so it reads at the same size as the rest of the page,
 * and the paragraph stays one block exactly as the doc has it.
 * ============================================================ */
.expe{
  display:flex; flex-direction:column; align-items:center;
  text-align:center;
  padding:clamp(38px,4.4vw,72px) clamp(24px,4vw,64px);
  position:relative;
  border-radius:clamp(20px,2.4vw,30px);
  border:1px solid rgba(123,219,211,.16);
  /* the pixel strips ride inside, so they must not cross the radius */
  overflow:hidden;
  background:
    radial-gradient(58% 56% at 50% 0%, rgba(18,186,176,.22), transparent 62%),
    linear-gradient(170deg,#0C2530 0%,#07181F 74%);
}
.expe h2{
  margin:0;
  /* the same scale as #partners' heading — the other dark panel on the page.
     This was on the .ncol scale, which is for column headings, not section
     titles, so it came out half the size of every other heading. */
  font-size:clamp(24px,2.4vw,40px); line-height:1.08; font-weight:400;
  letter-spacing:-.018em; color:#fff; max-width:24ch;
}
.expe-body{
  margin:clamp(18px,2vw,26px) 0 0;
  max-width:62ch;
  font-size:clamp(14.5px,1.2vw,16px); line-height:1.68;
  color:#A9C4CC; text-wrap:pretty;
}
.expe .m-btns{ margin-top:clamp(24px,2.8vw,36px); justify-content:center; }

/* The pixel field covers the whole panel, drawn on a canvas by enclave.js.
   It was two grids of spans while it only ran down the sides; covering the
   full box that way meant ~1400 spans and 87KB of markup for decoration, and
   a fixed-cell grid cannot follow a panel whose width changes with the
   viewport. Each cell keeps its own phase, so the field twinkles with no
   direction — a drifting background gave it one and read as a ticker. */
.expe > canvas.expx{
  position:absolute; inset:0;
  width:100%; height:100%;
  z-index:0; display:block; pointer-events:none;
}
/* A scrim between the field and the copy. The field is allowed to run right
   across the panel, so the text needs its own ground back: this darkens the
   middle with the panel's own colour and fades out well before the edges, so
   the pixels stay visible around it. Order matters — canvas 0, scrim 1,
   content 2. */
.expe::after{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(72% 64% at 50% 50%,
    rgba(7,24,31,.90) 0%,
    rgba(7,24,31,.66) 52%,
    rgba(7,24,31,0) 80%);
}
.expe > *:not(canvas){ position:relative; z-index:2; }

@media(max-width:700px){
  .expe{ padding:34px 22px 38px; border-radius:18px; }
  .expe-body{ max-width:none; }
}

/* ============================================================
 * .capb / .capst — partners: copy left, cards stacked in 3D on the right
 *
 * The three partner beats sit as a stack in real 3D: the front card at z=0
 * and the two behind receding, offset upward so their edges show like cards
 * behind a card. While the pinned section scrolls, the stack advances one
 * card at a time — the front one slides up and away and the next takes its
 * place.
 *
 * Three things this depends on, all learned the hard way:
 *  - depth is sorted by translateZ, never z-index (a negative z-index child
 *    paints above its parent's background, not behind it);
 *  - the band must NOT carry .pillars: effects.js treats that class as a
 *    scrubbed sequence and starts the heading at opacity 0, revealing it only
 *    once it adds .head-on — and with no .nline here it bails out first, so
 *    the heading would never appear. The teal ground is copied instead;
 *  - showcase.css only pins `.pillars-pin .band.pillars`, so without that
 *    class this band needs its own sticky rule or there is no pin at all and
 *    the stack never advances.
 * ============================================================ */
@media (min-width:990px) and (prefers-reduced-motion:no-preference){
  .pillars-pin > .band.capb{ position:sticky; top:clamp(64px,10vh,110px); }
}
.capb{
  background:
    radial-gradient(60% 52% at 50% 100%, rgba(18,186,176,.22), transparent 70%),
    radial-gradient(90% 70% at 22% 0%, rgba(18,186,176,.12), transparent 56%),
    var(--m-grad);
  display:grid; grid-template-columns:1fr;
  gap:clamp(30px,4vw,64px); align-items:center;
  text-align:left;
}
@media(min-width:990px){
  .capb{ grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr); }
}
.capb-copy h2{
  margin:0; max-width:20ch;
  font-size:clamp(24px,2.4vw,40px); line-height:1.08; font-weight:400;
  letter-spacing:-.018em; color:#fff;
}
.capb-sub{
  margin:clamp(18px,2vw,26px) 0 0; max-width:52ch;
  font-size:clamp(14.5px,1.2vw,16px); line-height:1.68; color:#A9C4CC;
}

/* the stack */
.capst{
  position:relative;
  box-sizing:border-box;
  /* No perspective and no translateZ: receding in Z made every card shrink as
     it went back and grow as it came forward, and the brief was that the cards
     should simply pass, not resize. They keep one size and only move on Y, so
     the stack is ordered by z-index alone. */
  /* the rear cards peek out to the LEFT, so the room for them is there.
     Height must be explicit: absolutely positioned children contribute none. */
  padding-left:clamp(28px,2.8vw,38px);
  height:clamp(310px,26vw,352px);
}
.capst-card{
  /* inset:0 on the padding box — NOT top:<padding>, which offsets the card a
     second time and pushed it clean out of the bottom of the stack */
  position:absolute; left:0; right:0; top:0; bottom:0;
  display:flex; flex-direction:column; justify-content:center;
  padding:clamp(24px,2.4vw,32px) clamp(22px,2.4vw,32px) clamp(24px,2.4vw,32px) clamp(32px,2.8vw,38px);
  border-radius:clamp(16px,1.8vw,22px);
  border:1px solid rgba(123,219,211,.18);
  background:
    radial-gradient(70% 74% at 22% 10%, rgba(18,186,176,.20), transparent 66%),
    linear-gradient(168deg,#0C2A33 0%,#071B24 100%);
  box-shadow:0 40px 80px -46px rgba(0,0,0,.66);
  transition:transform .8s cubic-bezier(.16,.8,.3,1), opacity .8s ease;
}
/* Depth states, written by enclave.js.
   The rear cards are SOLID and offset downward, so the only part of them that
   escapes the front card is a strip below its bottom edge — empty card, no
   text. That is why nothing needs hiding: an earlier version dimmed the rear
   cards and blanked their children, which turned the stack to mush and could
   leave the front card empty if a state class was missing. Geometry instead
   of opacity tricks. */
.capst-card.is-front{ transform:translateX(0);      opacity:1; z-index:4; }
.capst-card.is-next { transform:translateX(-14px);   opacity:1; z-index:3; }
.capst-card.is-far  { transform:translateX(-28px);   opacity:1; z-index:2; }
/* the one leaving still travels upward: the stack shows on the left, but the
   passing motion stays vertical, which is what was asked for */
.capst-card.is-past { transform:translateY(-118px);  opacity:0; z-index:1; pointer-events:none; }

/* before the script runs: card one in front, the others as edges to its left */
.capst-card:nth-child(1){ transform:translateX(0);     z-index:4; }
.capst-card:nth-child(2){ transform:translateX(-14px); z-index:3; }
.capst-card:nth-child(3){ transform:translateX(-28px); z-index:2; }

.capst-card .n-ic{
  width:44px; height:44px; flex:none; border-radius:12px;
  background:rgba(18,186,176,.16);
  display:flex; align-items:center; justify-content:center;
}
.capst-card .n-ic svg{ width:21px; height:21px; fill:none; stroke:var(--aqua,#7BDBD3); stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }
.capst-card h3{ margin:clamp(14px,1.5vw,20px) 0 0; font-size:clamp(19px,1.7vw,24px); font-weight:500; color:#fff; }
.capst-card p{ margin:12px 0 0; font-size:clamp(14.5px,1.2vw,16px); line-height:1.65; color:#A9C4CC; }

/* which of the three you are on — and a way to jump straight to one */
.capst-rail{ display:flex; gap:9px; margin-top:clamp(20px,2.2vw,28px); }
.capst-dot,
.efr-dot{
  -webkit-appearance:none; appearance:none;
  border:0; padding:0; font:inherit; cursor:pointer;
  width:24px; height:3px; border-radius:2px;
  background:rgba(123,219,211,.24);
  transition:background .3s ease, width .3s ease;
}
.capst-dot:hover, .efr-dot:hover{ background:rgba(123,219,211,.5); }
.capst-dot.on, .efr-dot.on{ background:var(--teal,#12BAB0); width:38px; }
.capst-dot:focus-visible, .efr-dot:focus-visible{
  outline:2px solid var(--aqua,#7BDBD3); outline-offset:5px; border-radius:3px;
}
/* the hit area is bigger than the 3px dash, or it is unclickable in practice */
.capst-dot, .efr-dot{ position:relative; }
.capst-dot::after, .efr-dot::after{
  content:""; position:absolute; left:0; right:0; top:-11px; bottom:-11px;
}
/* label for screen readers only */
.u-sr{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* Tablet and below, and reduced motion: no pin, no 3D — three cards in a
   column. The bound is 989px so it complements the pin's min-width:990px
   exactly. At 979 it left 980-989 in neither branch: the script stood down
   (no sticky) but the cards kept their stacked 3D offsets, so the deck froze
   on 01 and two thirds of the section could never be read. One pinned scroll
   on this page is enough; the second one belongs to Platform. */
@media (max-width:989px), (prefers-reduced-motion:reduce){
  .capst{ height:auto; padding-left:0; }
  .capst-card{
    position:relative; top:auto;
    transform:none !important; opacity:1 !important; transition:none;
  }
  .capst-card + .capst-card{ margin-top:16px; }
  /* content of every card visible here, whatever states the script left behind */
  .capst-card > *{ opacity:1 !important; }
  .capst-rail{ display:none; }
}


/* the timeline lede runs wider than the site default (.sec-head .m-lede is
   64ch): this paragraph is one dense block and at 64ch it stacked into a
   narrow column beside a lot of empty page. Stopped at 84ch — past about 90
   characters the eye loses the line on the return sweep. Scoped to #timeline
   so no other section moves. */
#timeline .sec-head .m-lede{ max-width:84ch; }

/* ============================================================
 * .ctl — the certificate timeline
 *
 * This content is a chronology: three dates on a mandatory schedule, each
 * tightening the limit. The number is the news, so the day count leads each
 * card at display size — it is the opening fragment of the doc's own sentence,
 * promoted out of the paragraph, not new wording — and a meter under it draws
 * the same number as a length, which is what makes the shrink visible.
 *
 * All three cards are the same paper. ONCE, when the section arrives on
 * screen, a wave runs the row: each card comes FORWARD in turn — lifts, scales
 * a hair, casts a real shadow — then settles back. There is no light object
 * drawn on top; earlier passes tried a travelling glint and it read as a prop
 * flying across the page. The depth IS the light. On a light ground depth
 * reads and hue does not: a teal glow at low alpha over paper is invisible, a
 * shadow is not. And a lift is passing emphasis, where a colour that stays
 * would claim the date is the current one.
 *
 * Which date IS current is said once, statically: the first node is filled
 * teal. Two separate signals, neither pretending to be the other.
 *
 * Ground and shadow animate as registered custom properties, so the whole
 * card moves from one keyframe set. Text colour never changes.
 *
 * .is-lit is set by the observer in enclave.js. Without JS, and under
 * prefers-reduced-motion, the row simply sits at rest — which is the whole
 * design minus the entrance.
 * ============================================================ */
@property --ctl-edge{ syntax:'<color>'; inherits:true; initial-value:#E1DED6; }
@property --ctl-bar { syntax:'<color>'; inherits:true; initial-value:rgba(252,201,33,.62); }
@property --ctl-nodefill{ syntax:'<color>'; inherits:true; initial-value:#F4F2EE; }
@property --ctl-nodeline{ syntax:'<color>'; inherits:true; initial-value:rgba(3,43,59,.28); }
@property --ctl-nodeglow{ syntax:'<color>'; inherits:true; initial-value:rgba(252,201,33,0); }
@property --ctl-bar2{ syntax:'<color>'; inherits:true; initial-value:rgba(255,221,112,.80); }

.ctl{
  position:relative;
  margin-top:clamp(30px,3.6vw,52px);
  display:grid;
  grid-template-columns:1fr;
  gap:clamp(16px,1.8vw,24px);
}

.ctl-stop{
  position:relative; z-index:1;
  display:flex; flex-direction:column;
  padding:clamp(22px,2.4vw,32px);
  border-radius:clamp(14px,1.5vw,18px);
  border:1px solid var(--ctl-edge);
  /* the paper stays the paper, lifted or not: going to near-white read as a
     different material rather than the same card closer to you */
  background-image:linear-gradient(168deg, #F2F0EB 0%, #E9E7E1 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.7),
             0 12px 26px -24px rgba(3,43,59,.40);
  transform:translateY(0) scale(1);
}
.ctl-stop > *{ position:relative; z-index:1; }

@media(min-width:900px){
  .ctl{ grid-template-columns:repeat(3,1fr); }
  /* the rail runs behind the cards and shows through the gaps, reading as one
     line across the three of them. It sits on the row's vertical centre: at
     node height it hung near the top edge and looked like it had slipped. */
  .ctl::before{
    content:""; position:absolute; z-index:0;
    left:clamp(22px,2.4vw,32px); right:clamp(22px,2.4vw,32px);
    top:50%; transform:translateY(-50%);
    height:2px; border-radius:2px;
    background:linear-gradient(90deg,
      rgba(3,43,59,.20) 0%, rgba(3,43,59,.13) 100%);
  }
}

/* the wave, left to right: each card comes forward in turn and settles back,
   so the row ends exactly where it started. Then it holds still for three
   seconds and goes again — 3s of wave, 3s of rest, on a 6s loop. The pause is
   the point: without it the row never stops moving and the copy beside it
   becomes unreadable. */
.ctl.is-lit .ctl-stop{
  animation-duration:6s;
  animation-timing-function:cubic-bezier(.22,.9,.28,1);
  animation-iteration-count:infinite;
}
.ctl.is-lit .ctl-stop:nth-child(1){ animation-name:ctlFwd1; }
.ctl.is-lit .ctl-stop:nth-child(2){ animation-name:ctlFwd2; }
.ctl.is-lit .ctl-stop:nth-child(3){ animation-name:ctlFwd3; }

@keyframes ctlFwd1{
  0%, 8.9%{
    --ctl-edge:#E1DED6;
    --ctl-bar:rgba(252,201,33,.62); --ctl-bar2:rgba(255,221,112,.80);
    --ctl-nodefill:#F4F2EE; --ctl-nodeline:rgba(3,43,59,.28); --ctl-nodeglow:rgba(252,201,33,0);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.7),
               0 12px 26px -24px rgba(3,43,59,.40);
    transform:translateY(0) scale(1); z-index:1;
  }
  11%, 20.9%{
    --ctl-edge:rgba(3,43,59,.15);
    --ctl-bar:#FCC921; --ctl-bar2:#FFDD70;
    --ctl-nodefill:#FCC921; --ctl-nodeline:#FCC921; --ctl-nodeglow:rgba(252,201,33,.32);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.85),
               0 34px 54px -24px rgba(3,43,59,.28),
               0 10px 20px -12px rgba(3,43,59,.12);
    transform:translateY(-9px) scale(1.018); z-index:3;
  }
  25%, 100%{
    --ctl-edge:#E1DED6;
    --ctl-bar:rgba(252,201,33,.62); --ctl-bar2:rgba(255,221,112,.80);
    --ctl-nodefill:#F4F2EE; --ctl-nodeline:rgba(3,43,59,.28); --ctl-nodeglow:rgba(252,201,33,0);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.7),
               0 12px 26px -24px rgba(3,43,59,.40);
    transform:translateY(0) scale(1); z-index:1;
  }
}
@keyframes ctlFwd2{
  0%, 20.3%{
    --ctl-edge:#E1DED6;
    --ctl-bar:rgba(252,201,33,.62); --ctl-bar2:rgba(255,221,112,.80);
    --ctl-nodefill:#F4F2EE; --ctl-nodeline:rgba(3,43,59,.28); --ctl-nodeglow:rgba(252,201,33,0);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.7),
               0 12px 26px -24px rgba(3,43,59,.40);
    transform:translateY(0) scale(1); z-index:1;
  }
  23.4%, 33.6%{
    --ctl-edge:rgba(3,43,59,.15);
    --ctl-bar:#FCC921; --ctl-bar2:#FFDD70;
    --ctl-nodefill:#FCC921; --ctl-nodeline:#FCC921; --ctl-nodeglow:rgba(252,201,33,.32);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.85),
               0 34px 54px -24px rgba(3,43,59,.28),
               0 10px 20px -12px rgba(3,43,59,.12);
    transform:translateY(-9px) scale(1.018); z-index:3;
  }
  37.4%, 100%{
    --ctl-edge:#E1DED6;
    --ctl-bar:rgba(252,201,33,.62); --ctl-bar2:rgba(255,221,112,.80);
    --ctl-nodefill:#F4F2EE; --ctl-nodeline:rgba(3,43,59,.28); --ctl-nodeglow:rgba(252,201,33,0);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.7),
               0 12px 26px -24px rgba(3,43,59,.40);
    transform:translateY(0) scale(1); z-index:1;
  }
}
@keyframes ctlFwd3{
  0%, 32.9%{
    --ctl-edge:#E1DED6;
    --ctl-bar:rgba(252,201,33,.62); --ctl-bar2:rgba(255,221,112,.80);
    --ctl-nodefill:#F4F2EE; --ctl-nodeline:rgba(3,43,59,.28); --ctl-nodeglow:rgba(252,201,33,0);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.7),
               0 12px 26px -24px rgba(3,43,59,.40);
    transform:translateY(0) scale(1); z-index:1;
  }
  36.1%, 46.2%{
    --ctl-edge:rgba(3,43,59,.15);
    --ctl-bar:#FCC921; --ctl-bar2:#FFDD70;
    --ctl-nodefill:#FCC921; --ctl-nodeline:#FCC921; --ctl-nodeglow:rgba(252,201,33,.32);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.85),
               0 34px 54px -24px rgba(3,43,59,.28),
               0 10px 20px -12px rgba(3,43,59,.12);
    transform:translateY(-9px) scale(1.018); z-index:3;
  }
  50%, 100%{
    --ctl-edge:#E1DED6;
    --ctl-bar:rgba(252,201,33,.62); --ctl-bar2:rgba(255,221,112,.80);
    --ctl-nodefill:#F4F2EE; --ctl-nodeline:rgba(3,43,59,.28); --ctl-nodeglow:rgba(252,201,33,0);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.7),
               0 12px 26px -24px rgba(3,43,59,.40);
    transform:translateY(0) scale(1); z-index:1;
  }
}

/* header row: node, date, index on one line, so the whole body of the card
   can be given to the number */
.ctl-top{
  position:relative; z-index:1;
  display:flex; align-items:center; gap:11px;
}
.ctl-node{
  flex:0 0 auto;
  display:block; width:11px; height:11px; border-radius:50%;
  background:var(--ctl-nodefill);
  border:1.5px solid var(--ctl-nodeline);
  box-shadow:0 0 0 5px var(--ctl-nodeglow);
}
/* every node is hollow at rest. The one that lights is the one the wave is
   on, and nothing else — a node left filled would read as a second, competing
   signal. Which date is in effect today is what the copy says. */
.ctl-stop{
  --ctl-nodefill:#F4F2EE; --ctl-nodeline:rgba(3,43,59,.28);
  --ctl-nodeglow:rgba(252,201,33,0);
}
.ctl-date{
  flex:1 1 auto; min-width:0;
  font-size:clamp(13.5px,1.05vw,15px); font-weight:600;
  letter-spacing:.005em; color:var(--text-muted,#4A6470);
}
/* the step index, from the doc's own 01 / 02 / 03 */
.ctl-ix{
  flex:0 0 auto;
  font-size:12px; font-weight:600; letter-spacing:.16em;
  font-variant-numeric:tabular-nums; line-height:1;
  color:rgba(3,43,59,.30);
}

.ctl-body{
  position:relative; z-index:1;
  margin:clamp(20px,2.2vw,30px) 0 clamp(24px,2.6vw,34px);
  font-size:clamp(14.5px,1.15vw,16px); line-height:1.6;
  color:var(--text-muted,#4A6470);
}
/* the opening fragment of the doc's own sentence, at display size */
.ctl-fig{
  display:block; margin-bottom:9px;
  font-size:clamp(38px,4.4vw,60px); font-weight:600;
  letter-spacing:-.035em; line-height:.94;
  font-variant-numeric:tabular-nums;
  color:var(--m-navy,#032B3B);
}

/* the meter: the same number the card opens with, drawn as a length. Three
   equal boxes said "three equal things"; the bars say "this is shrinking",
   which is what the section is actually about. */
.ctl-meter{
  position:relative; z-index:1;
  margin-top:auto; height:4px; border-radius:4px;
  background:rgba(3,43,59,.10);
}
.ctl-meter-fill{
  display:block; height:100%; border-radius:inherit;
  background:linear-gradient(90deg, var(--ctl-bar), var(--ctl-bar2));
}

/* ---------- closing 3-up: three columns through the whole tablet band ----------
 * showcase.css switches .scope-3up to three columns at 920px site-wide. Here it
 * holds them from 768px, which is the project's tablet floor (mobile <=767 ·
 * tablet 768-989 · desktop >=990), so the band never drops to one column while
 * the page is still on a tablet. Scoped to #demo: the other three pages that
 * use .scope-3up keep the site-wide 920.
 * ------------------------------------------------------------------------- */
@media(min-width:768px){
  #demo .scope-3up{ grid-template-columns:repeat(3,1fr); align-items:stretch; }
}

/* ---------- mobile: the capability CTAs must wrap ----------
 * .m-btn is white-space:nowrap site-wide, including inside its <=989px block.
 * "SEE HOW ENCLAVE HANDLES CERTIFICATE LIFECYCLE MANAGEMENT" is 55 characters,
 * so on a 390px screen the pill came out 448px wide and stretched the whole
 * document to 448px: the page scrolled sideways, the hero was cut off and the
 * fixed nav (centred with translateX(-50%) on a 448px document) sat off to the
 * right. Same treatment the system already uses for long anchors in .m-btn.quiet.
 * ---------------------------------------------------------- */
@media(max-width:767px){
  .efr-copy .m-btn{
    white-space:normal; text-align:left; line-height:1.45;
    max-width:100%; justify-content:flex-start;
  }
}

/* ---------- mobile: give the rows back the page measure ----------
 * The pinned scaffolding (.efr-pin > .efr-stage > .efr-viewport > .efr-track)
 * is full-bleed by design: on desktop the panel content gets the page measure
 * from `.efr-track .efr-inner`. Below 768px `.efr-inner{display:contents}`
 * dissolves that grid, so nothing re-applies the measure and every row ran
 * 0 -> viewport while the section lead sat inset — the rows looked like they
 * were escaping the section. Constrain the track once and the whole subtree
 * lines up with .efr-wrap.
 * ---------------------------------------------------------------- */
@media (max-width:767px){
  .efr-track{ width:92vw; max-width:1560px; margin-inline:auto; }
}
@media (max-width:700px){
  .efr-track{ width:calc(100% - 44px); }
}

/* ---------- service pages: the manifesto runs wider ----------
 * .expe-body is capped at 62ch, which suits the single paragraph Enclave puts
 * there. On the service pages the manifesto is two full paragraphs centred in
 * a wide band and 62ch left them looking like a narrow column with air on both
 * sides. Scoped to #manifesto so Enclave's own #experience is untouched.
 * ------------------------------------------------------------ */
@media(min-width:768px){
  #manifesto .expe-body{ max-width:86ch; }
}

/* ---------- .clmx — the certificate lifecycle field ----------
 * Its own animation, not a restyled component: a canvas of square cells in the
 * house pixel language, one row per certificate. See enclave.js for what it
 * draws. Sits in the manifesto's side card, where the static mock used to be.
 * ------------------------------------------------------------- */
.clmx-host{
  position:relative; width:100%; aspect-ratio:1 / 1;
  border-radius:clamp(14px,1.4vw,20px); overflow:hidden;
  background:linear-gradient(165deg,#04303F 0%, #032B3B 55%, #0D1F2D 100%);
  box-shadow:0 30px 60px -34px rgba(3,43,59,.6), inset 0 1px 0 rgba(123,219,211,.10);
}
.clmx{ position:absolute; inset:0; width:100%; height:100%; display:block; }

/* ------------------------------------------------------------------
 * Compliance note — the icon
 * The stacked note starts hidden and asset-hero.js reveals it, but these
 * pages don't load that script, so the icon never showed. Here it is
 * simply visible from the start.
 * ------------------------------------------------------------------ */
#compliance .vnote--stack .vnote-ic{ opacity:1; transform:none; }

/* the table and the note only sit side by side from 989px up: below that the
   table was too cramped to read */
@media (max-width:988px){
  #compliance .comp-grid{ grid-template-columns:minmax(0,1fr); }
}

/* la variante ancha del cajon: los textos de las bandas de Solutions son mas
   largos que los de Enclave y con 62ch se quedaban en una columna estrecha */
.expe--ancho .expe-body{ max-width:86ch; }
.expe--ancho h2{ max-width:34ch; }

/* la lista del cajon: el doc la trae como <ul>. Alineada a la izquierda dentro
   de una caja centrada quedaba descolgada, asi que sus tres puntos van en tres
   columnas, cada una con su filete y su marca: se leen como lista, no como
   prosa partida. */
.expe-list{
  margin:clamp(26px,3vw,40px) 0 0; padding:0; list-style:none;
  width:100%; max-width:1100px; text-align:left;
  display:grid; grid-template-columns:1fr; gap:clamp(18px,2vw,26px);
}
@media (min-width:990px){
  .expe-list{ grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(24px,2.6vw,40px); }
}
.expe-list li{
  position:relative; padding-top:clamp(16px,1.8vw,22px);
  border-top:1px solid rgba(123,219,211,.22);
  font-size:clamp(14.5px,1.15vw,15.5px); line-height:1.6; color:#A9C4CC;
}
.expe-list li::before{
  content:""; position:absolute; left:0; top:-4px;
  width:7px; height:7px; border-radius:2px; background:var(--teal-bright,#7BDBD3);
}


/* ---------- el manifiesto de los productos, centrado en movil -------------- */
@media (max-width:767px){
  #manifesto .case-main{ text-align:center; }
  #manifesto .case-main h2,
  #manifesto .case-main p{ margin-inline:auto; max-width:none; }
}
