/* ==========================================================================
   SciMynd V1 design system
   Ported from "SciMynd Site.dc.html" (Scimynd V1 redesign).
   Every value here comes from that file -- when something needs changing, add
   or edit a token in :root so the change propagates instead of drifting.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Fonts -- self-hosted, replacing the Google Fonts <link> the layouts used to
   carry. That link produced a visible mid-load font change on every hard
   reload: the hero painted in Georgia/system-ui and repainted in
   Newsreader/Manrope a few hundred ms later.

   The cause was a two-hop cross-origin chain -- HTML, then
   fonts.googleapis.com/css2, then fonts.gstatic.com/*.woff2 -- that no amount
   of preconnect can collapse, paired with display=swap, which explicitly asks
   the browser to paint the fallback first and swap in the real font whenever it
   turns up. Serving from our own origin makes the fonts preloadable from the
   document head (see _RedesignLayout / _AuthLayout), so they start downloading
   at HTML parse time on a connection that is already open.

   font-display:optional, not swap, is what actually guarantees the text never
   changes font mid-load: the browser blocks for ~100ms, and if the face has not
   arrived by then it uses the fallback for the WHOLE page view rather than
   swapping later. Preloading same-origin is what makes optional safe -- it is a
   bad bet for third-party fonts precisely because they rarely win that 100ms.

   These are the same variable woff2 subsets Google serves (Newsreader v26,
   Manrope v20), so rendering is unchanged -- the full 6..72 optical-size axis is
   intact and the hero headline still adapts as it did. Only the latin faces are
   preloaded; latin-ext is fetched on demand via unicode-range and costs nothing
   on English pages. Both are OFL-1.1, see wwwroot/fonts/OFL.txt.
   -------------------------------------------------------------------------- */

/* Latin. Preloaded by the layouts -- keep the two in sync. */
@font-face{
  font-family:'Manrope';
  src:url('/fonts/manrope-latin.woff2') format('woff2');
  font-style:normal;font-weight:200 800;font-display:optional;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Newsreader';
  src:url('/fonts/newsreader-latin.woff2') format('woff2');
  font-style:normal;font-weight:200 800;font-display:optional;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Newsreader';
  src:url('/fonts/newsreader-italic-latin.woff2') format('woff2');
  font-style:italic;font-weight:200 800;font-display:optional;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* Latin Extended. Not preloaded -- unicode-range keeps these off the wire
   entirely unless a page actually uses a character in the range. */
@font-face{
  font-family:'Manrope';
  src:url('/fonts/manrope-latin-ext.woff2') format('woff2');
  font-style:normal;font-weight:200 800;font-display:optional;
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Newsreader';
  src:url('/fonts/newsreader-latin-ext.woff2') format('woff2');
  font-style:normal;font-weight:200 800;font-display:optional;
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face{
  font-family:'Newsreader';
  src:url('/fonts/newsreader-italic-latin-ext.woff2') format('woff2');
  font-style:italic;font-weight:200 800;font-display:optional;
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

:root{
  /* Surfaces */
  --bg:#FFFFFF;
  --bg-soft:#F4F7FD;        /* alternating section background */
  --bg-hover:#F1F6FD;       /* nav item hover */
  --bg-tint:#EBF3FE;        /* info callouts, active chips */
  --bg-tint-2:#E8F5FF;      /* subpage hero radial */
  --bg-code:#F6F9FE;
  --bg-mono:#F1F5FC;

  /* Ink */
  --navy:#0E1638;           /* primary text + dark panels */
  --navy-deep:#08102B;      /* hero / auth aside */
  --navy-2:#141F4D;
  --navy-3:#1B2761;
  --text:#0E1638;
  --text-strong:#22304A;
  --text-body:#33405A;
  --text-muted:#5A6478;
  --text-faint:#8C97AB;

  /* Brand blue */
  --blue:#0A6FD0;
  --blue-dark:#084F9E;
  --blue-deep:#0A5CB8;
  --blue-mid:#0A83E0;
  --blue-bright:#0A9BF0;
  --cyan:#00AEFF;
  --cyan-light:#6FD3FF;
  --cyan-pale:#8FDBFF;
  --selection:#CDEAFF;

  /* Lines */
  --line:#E4EAF4;
  --line-strong:#DCE4F2;
  --line-soft:#EEF2FA;
  --line-softer:#F1F5FB;
  --line-section:#E9EFF9;
  --line-dashed:#C9DAF3;
  --line-focus:#CFE3F8;

  /* Module colours. The base tones are lifted straight out of the app-icon artwork
     (App_Icons_RGB.pdf -> images/redesign/app-icons/*.svg) so a nav dot and the icon it
     stands for are the same colour; --*-deep is that icon's darker swoosh tone.

     The -ink values are deliberately NOT the artwork colours: they tint small text (module
     tag lines, credit-tier labels) where the brand tone would fail contrast on white, so
     they stay hand-picked at 4.5:1 or better. Catalyst and Synapse are dark enough that
     their ink is a real artwork tone. */
  --ask:#00B1FF;        --ask-deep:#0092FF;      --ask-ink:#0A6FD0;
  --core:#FF7015;       --core-deep:#FF4C15;     --core-ink:#B4551A;
  --studio:#FC153D;     --studio-deep:#DC153D;   --studio-ink:#C21F2C;
  --vault:#FC9E00;      --vault-deep:#FC8800;    --vault-ink:#8F6A00;
  --synapse:#2055CE;    --synapse-deep:#294497;  --synapse-ink:#294497;
  --amplify:#1E9F8C;    --amplify-deep:#1E8672;  --amplify-ink:#147263;
  --fusion:#00B1FF;     --fusion-deep:#0092FF;   --fusion-ink:#0A6FD0;
  --catalyst:#4B535E;   --catalyst-deep:#0D1638; --catalyst-ink:#0D1638;

  /* Semantic.
     --good-bg-2 / --good-line are the "this is the better column" lane on the /why-scimynd
     table: a tint strong enough to read as a highlighted lane at a glance, where --good-bg is
     near-white and only works behind small type. The column beside it carries no glyph at all:
     a cross there read as "does not do this" against rows that describe what those systems
     plainly do, and the point of the table is the comparison, not the verdict. */
  --good:#1E9E8C;  --good-ink:#147263;  --good-bg:#F7FCFB;
  --good-bg-2:#F1FAF8;  --good-line:#D3EAE4;
  --bad:#C94B4B;   --bad-ink:#B33A3A;
  /* Warning: something needs doing, nothing went wrong -- e.g. "confirm your email first".
     Amber, so it reads as a nudge rather than the red of a failed action. */
  --warn:#C98A2B;  --warn-ink:#9A6A1D;  --warn-bg:#FFFBF2;  --warn-line:#F0DFC0;

  /* Type */
  --serif:'Newsreader',Georgia,'Times New Roman',serif;
  --sans:'Manrope',system-ui,-apple-system,'Segoe UI',sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  /* Shape */
  --r-card:20px;
  --r-band:24px;
  --r-panel:28px;
  --r-sm:14px;
  --r-md:16px;
  --r-lg:18px;
  --pill:999px;

  /* Elevation */
  --sh-card:0 10px 30px -26px rgba(14,22,56,0.5);
  --sh-card-hover:0 26px 58px -28px rgba(14,22,56,0.32);
  --sh-menu:0 28px 70px -24px rgba(14,22,56,0.3);
  --sh-band:0 30px 70px -32px rgba(10,111,208,0.6);
  --sh-primary:0 10px 24px -10px rgba(10,111,208,0.7);
  --sh-primary-lg:0 16px 38px -14px rgba(10,155,240,0.85);
  --sh-white:0 14px 32px -12px rgba(6,26,54,0.5);

  /* Layout */
  --gutter:clamp(20px,3vw,40px);
  --shell:1440px;
  --header-h:76px;
  --sec-y:clamp(48px,6vw,92px);
}

/* --------------------------------------------------------------------------
   Reset + base
   -------------------------------------------------------------------------- */
*{box-sizing:border-box;margin:0;padding:0;}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;}
body{
  background:var(--bg);color:var(--text);
  font-family:var(--sans);line-height:1.65;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
img{display:block;max-width:100%;}
button{font:inherit;color:inherit;}
a{color:var(--blue);text-decoration:none;}
a:hover{color:var(--blue-dark);}
ul,ol{list-style:none;}
:focus-visible{outline:3px solid var(--blue);outline-offset:3px;border-radius:4px;}
::selection{background:var(--selection);color:var(--navy);}
mark{background:var(--selection);color:var(--navy);border-radius:3px;padding:0 1px;}
@media print{header.site,footer.site{position:static;}}

.skip-link{
  position:absolute;left:-9999px;top:0;z-index:999;
  background:var(--navy);color:#fff;padding:12px 20px;
  border-radius:0 0 10px 0;font-size:14px;font-weight:700;
}
.skip-link:focus{left:0;color:#fff;}

.sr-only{
  position:absolute!important;left:-9999px!important;
  width:1px;height:1px;overflow:hidden;
}

/* --------------------------------------------------------------------------
   Layout primitives
   -------------------------------------------------------------------------- */
.wrap{max-width:var(--shell);margin:0 auto;padding:0 var(--gutter);}
.wrap-md{max-width:1080px;margin:0 auto;padding:0 var(--gutter);}

.sec{padding:var(--sec-y) 0;}
.sec-tight{padding:clamp(32px,4vw,56px) 0;}
.sec-top-0{padding-top:0;}
.sec-bottom-0{padding-bottom:0;}
.sec-soft{
  background:var(--bg-soft);
  border-top:1px solid var(--line-section);
  border-bottom:1px solid var(--line-section);
}
.sec-soft-open{background:var(--bg-soft);border-top:1px solid var(--line-section);}

/* Subpage hero wash */
.sec-hero{
  padding:clamp(48px,6vw,80px) 0 clamp(32px,4vw,56px);
  background:radial-gradient(ellipse 74% 62% at 82% 0%,var(--bg-tint-2) 0%,var(--bg) 58%);
}

.grid{display:grid;gap:20px;}
.grid-24{display:grid;gap:24px;}
.g-200{grid-template-columns:repeat(auto-fit,minmax(200px,1fr));}
.g-210{grid-template-columns:repeat(auto-fit,minmax(210px,1fr));}
.g-220{grid-template-columns:repeat(auto-fit,minmax(220px,1fr));}
.g-230{grid-template-columns:repeat(auto-fit,minmax(230px,1fr));align-items:stretch;}
.g-250{grid-template-columns:repeat(auto-fit,minmax(250px,1fr));align-items:stretch;}
.plan-grid{grid-template-columns:repeat(auto-fit,minmax(250px,1fr));}
@media (min-width:1100px){.plan-grid{grid-template-columns:repeat(4,minmax(0,1fr));}}
@media (min-width:700px) and (max-width:1099px){.plan-grid{grid-template-columns:repeat(2,minmax(0,1fr));}}
.g-270{grid-template-columns:repeat(auto-fit,minmax(270px,1fr));}
.g-280{grid-template-columns:repeat(auto-fit,minmax(280px,1fr));}
.g-290{grid-template-columns:repeat(auto-fit,minmax(290px,1fr));}
.g-300{grid-template-columns:repeat(auto-fit,minmax(300px,1fr));}
.g-320{grid-template-columns:repeat(auto-fit,minmax(320px,1fr));}
.g-split{
  grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:clamp(32px,4vw,72px);align-items:center;
}
.g-split-top{
  grid-template-columns:repeat(auto-fit,minmax(340px,1fr));
  gap:clamp(32px,4vw,72px);align-items:start;
}

.row{display:flex;gap:14px;flex-wrap:wrap;}
.row-center{display:flex;gap:14px;flex-wrap:wrap;justify-content:center;}
.row-tags{display:flex;gap:12px;flex-wrap:wrap;}
.row-tags-sm{display:flex;gap:10px;flex-wrap:wrap;}

/* --------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */
.eyebrow{
  display:flex;align-items:center;gap:10px;
  font-size:11.5px;font-weight:800;letter-spacing:.16em;text-transform:uppercase;
  color:var(--blue);margin-bottom:16px;
}
.eyebrow::before{
  content:'';width:24px;height:2px;border-radius:2px;
  background:currentColor;flex:none;
}
.eyebrow-bare{
  font-size:11.5px;font-weight:800;letter-spacing:.16em;text-transform:uppercase;
  color:var(--blue);margin-bottom:14px;
}
.eyebrow.on-dark{color:var(--cyan-light);}

h1,h2,h3,.display{
  font-family:var(--serif);font-weight:500;
  color:var(--navy);letter-spacing:-0.018em;line-height:1.12;
}
h1,.h1{
  font-size:clamp(34px,4.6vw,54px);line-height:1.06;
  letter-spacing:-0.022em;text-wrap:balance;
}
.h1-hero{font-size:clamp(40px,5.6vw,70px);line-height:1.04;letter-spacing:-0.022em;text-wrap:balance;}
h2,.h2{font-size:clamp(28px,3.4vw,42px);line-height:1.1;text-wrap:balance;}
.h2-sm{font-size:clamp(26px,3.2vw,38px);line-height:1.12;text-wrap:balance;}
.h2-xs{font-size:clamp(24px,2.9vw,34px);line-height:1.16;text-wrap:balance;}
.h2-xxs{font-size:clamp(24px,2.8vw,32px);line-height:1.14;}
h3,.h3{font-size:21px;line-height:1.2;}
h1 em,h2 em,.h1 em{font-style:italic;color:var(--blue);}
h1.on-dark,h2.on-dark,h3.on-dark{color:#fff;}
h1.on-dark em,h2.on-dark em{color:var(--cyan-light);}

/* The hero headline is two clauses -- a statement and its italic follow-on -- and they stack.
   Inline, the break depended on how the text happened to wrap: at desktop widths it fell between
   the clauses and looked deliberate, but on a phone the italic began mid-line, halfway through the
   line that ends the first clause. Block makes the structure hold at every width, and lets
   text-wrap:balance work on each clause separately instead of on the run-on of both.
   Scoped to .h1-hero, which the home hero is the only user of -- inline italics elsewhere in an
   h1 or h2 are emphasis inside a sentence and must stay inline. */
.h1-hero em{display:block;}

/* "Knowledge," sits on its own line above "grounded in expertise." That break is deliberate -- the
   whole clause fits on one line at the current measure, so left to itself it would not break at all.
   Block rather than a <br> so the break is a styling decision and can be undone at a breakpoint
   without touching the view; it also keeps text-wrap:balance from treating the one-word line as
   something to even out against the rest. */
.h1-hero-lead{display:block;}

.lede{font-size:clamp(16.5px,1.5vw,19px);color:var(--text-muted);text-wrap:pretty;}
.lede-hero{font-size:clamp(17px,1.5vw,20px);line-height:1.6;color:rgba(255,255,255,0.78);text-wrap:pretty;}
.body-16{font-size:16px;color:var(--text-muted);line-height:1.7;text-wrap:pretty;}
.body-17{font-size:17px;color:var(--text-muted);text-wrap:pretty;}
.body-155{font-size:15.5px;color:var(--text-muted);line-height:1.75;text-wrap:pretty;}
.body-15{font-size:15px;color:var(--text-muted);text-wrap:pretty;}
.note{font-size:13.5px;color:var(--text-muted);line-height:1.7;text-wrap:pretty;}
.note-faint{font-size:12.5px;color:var(--text-faint);}
.center{text-align:center;}
.mx-auto{margin-left:auto;margin-right:auto;}

/* Section heads */
.sec-head{max-width:780px;margin-bottom:clamp(32px,4vw,56px);}
.sec-head-wide{max-width:840px;margin-bottom:clamp(32px,4vw,52px);}
/* For a lead long enough that 840px stacks it three deep and leaves the right third of the row
   empty beside it -- the See It Live copy, which names what the footage shows and then runs into the
   walkthrough link. 1120px is the hero's measure, so this is a width the page already sets rather
   than a new one, and it stays short of the 1360px row so the copy never runs edge to edge. */
.sec-head-widest{max-width:1120px;margin-bottom:clamp(32px,4vw,52px);}
.sec-head-center{max-width:760px;margin:0 auto clamp(28px,3vw,40px);text-align:center;}
.sec-head-narrow{max-width:640px;margin:0 auto clamp(32px,4vw,52px);text-align:center;}
.sec-head p,.sec-head-wide p,.sec-head-widest p,.sec-head-center p,.sec-head-narrow p{margin-top:16px;}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  height:52px;padding:0 28px;border-radius:var(--pill);
  font-family:var(--sans);font-size:15px;font-weight:700;
  border:none;cursor:pointer;white-space:nowrap;
  transition:transform .2s ease,box-shadow .2s ease,background .2s ease,border-color .2s ease,color .2s ease;
}
.btn-lg{height:54px;padding:0 30px;font-size:15.5px;}
.btn-md{height:50px;padding:0 26px;font-size:14.5px;}
.btn-sm{height:44px;padding:0 20px;font-size:14px;}
.btn-xs{height:42px;padding:0 20px;font-size:13.5px;}
.btn-block{width:100%;height:48px;font-size:14px;}

.btn-primary{
  background:linear-gradient(135deg,var(--blue-bright),var(--blue-deep));
  color:#fff;box-shadow:var(--sh-primary-lg);
}
.btn-primary:hover{
  color:#fff;transform:translateY(-2px);
  box-shadow:0 22px 46px -16px rgba(10,155,240,0.95);
}
.btn-primary.btn-sm,.btn-primary.btn-xs{box-shadow:var(--sh-primary);}
.btn-primary.btn-sm:hover{box-shadow:0 16px 32px -12px rgba(10,111,208,0.8);}

.btn-dark{
  background:var(--navy);color:#fff;
  box-shadow:0 14px 32px -14px rgba(14,22,56,0.6);
}
.btn-dark:hover{color:#fff;transform:translateY(-2px);}

.btn-outline{background:#fff;color:var(--navy);border:1.5px solid var(--line-strong);}
.btn-outline:hover{border-color:var(--blue);color:var(--blue);background:#F5FAFF;}

.btn-white{background:#fff;color:var(--navy);box-shadow:var(--sh-white);}
.btn-white:hover{color:var(--navy);transform:translateY(-2px);background:var(--bg-tint-2);}

.btn-ghost-light{
  background:rgba(255,255,255,0.07);color:#fff;
  border:1.5px solid rgba(255,255,255,0.28);
}
.btn-ghost-light:hover{color:#fff;background:rgba(255,255,255,0.15);border-color:rgba(255,255,255,0.5);}

.btn-ghost-light-2{
  background:rgba(255,255,255,0.12);color:#fff;
  border:1.5px solid rgba(255,255,255,0.45);
}
.btn-ghost-light-2:hover{color:#fff;background:rgba(255,255,255,0.22);}

.btn-band{
  height:48px;padding:0 24px;font-size:14.5px;
  background:rgba(255,255,255,0.08);color:#fff;
  border:1.5px solid rgba(255,255,255,0.3);
}
.btn-band:hover{color:#fff;background:rgba(255,255,255,0.18);}

/* Multi-line CTA (Unlimited "become an ambassador" link) */
.btn-wrap{
  display:inline-flex;align-items:center;min-height:52px;
  padding:12px 26px;border-radius:var(--pill);
  border:1.5px solid var(--line-strong);color:var(--navy);
  font-size:14.5px;font-weight:700;line-height:1.35;text-align:center;
  transition:border-color .2s ease,color .2s ease;
}
.btn-wrap:hover{border-color:var(--blue);color:var(--blue);}

.inline-link{color:var(--blue);font-weight:700;text-decoration:underline;text-underline-offset:3px;}

/* --------------------------------------------------------------------------
   Header + primary navigation
   -------------------------------------------------------------------------- */
header.site{
  position:sticky;top:0;z-index:120;
  background:rgba(255,255,255,0.9);
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  border-bottom:1px solid var(--line);
}
header.site > .wrap{
  display:flex;align-items:center;justify-content:space-between;
  gap:24px;height:var(--header-h);
}
.brand{display:flex;align-items:center;flex:none;padding:6px 4px;border-radius:10px;}
/* The lockup is 5.8:1, not the brand original's 3.7:1, because SCIMYND is set larger against the
   mark -- so the same height buys a lot more width. Shorter than the old 34-44px on purpose: the
   2.6vw middle keeps it near ~165px at the narrow end of the desktop nav's range, and only lets
   it out to 208px on wide viewports that have the space. The wordmark still reads ~40% larger
   than before at full width, which is the point.

   This clamp is a nicety, not the fix for the row overflowing -- shrinking the logo bought ~20px
   against a ~245px shortfall. The nav now switches to the drawer at 1179px and runs compact up to
   1360px; see "Where the desktop nav gives way to the drawer" below. */
.brand img{height:clamp(28px,2.6vw,36px);width:auto;}

.nav-primary{display:flex;align-items:center;gap:4px;}
.nav-link{
  background:none;border:none;cursor:pointer;
  font-size:15.5px;font-weight:600;padding:10px 14px;border-radius:10px;
  color:#3D4759;white-space:nowrap;
  transition:background .18s ease,color .18s ease;
}
.nav-link:hover{background:var(--bg-hover);color:var(--blue);}
.nav-link[aria-current="page"]{color:var(--blue);background:var(--bg-hover);}

.dot{width:10px;height:10px;border-radius:3px;flex:none;}

.nav-actions{display:flex;align-items:center;gap:10px;flex:none;}
/* Matches the 15.5px the links and Sign in run at, so the whole header row reads at one size --
   .btn-sm's own 14px is for buttons in page content, which sit next to 14px body copy. */
.nav-actions .btn-sm{font-size:15.5px;}
.nav-signin{
  background:none;border:none;cursor:pointer;
  font-size:15.5px;font-weight:700;padding:10px 12px;border-radius:10px;
  color:var(--navy);white-space:nowrap;
  transition:background .18s ease,color .18s ease;
}
.nav-signin:hover{background:var(--bg-hover);color:var(--blue);}

/* Account chip + menu.
   The chip is a link to My Apps and the caret is a separate disclosure button, so both
   sit inside one bordered pill and only the pill shows the hover state. */
/* Deliberately borderless and unfilled, unlike .btn: this sits immediately after Contact and
   "Open my app", and a third pill of the same height read as another button. Identity is not an
   action, so it gets no button chrome -- only a hover wash for affordance. */
.user-menu{position:relative;display:flex;align-items:center;flex:none;
  height:48px;padding-right:2px;border-radius:var(--pill);
}

/* Separates the button group from the account control, so the two stop reading as one row of
   three actions. A pseudo-element rather than markup -- it is decoration, not content. */
.user-menu::before{
  content:'';flex:none;
  width:1px;height:26px;margin-right:10px;
  background:var(--line-strong);
}

.user-chip{
  display:flex;align-items:center;gap:10px;height:100%;
  padding:0 6px 0 4px;border-radius:var(--pill);
  transition:background .16s ease;
}
.user-chip:hover{background:var(--bg-hover);color:inherit;}

.user-chip .avatar{
  width:34px;height:34px;border-radius:50%;
  background:linear-gradient(135deg,#0A9BF0,var(--blue-deep));
  color:#fff;display:flex;align-items:center;justify-content:center;
  font-size:13.5px;font-weight:800;flex:none;
  object-fit:cover;
}

/* The chip is the avatar alone; the name is kept for assistive tech but not painted.

   It used to render at up to 180px, and there is no viewport where that fits. Signed in,
   .nav-actions carries Contact + "Open my app" + this chip and measured 495px against the
   signed-out row's 303px. header.site > .wrap is capped at --shell (1440px), so the content box
   stops growing at 1360px however wide the monitor is -- the surplus never gets absorbed, and the
   signed-in row overflowed its right gutter at every width including 1440. Capping the name lower
   only moved the problem: the widest tier can seat ~95px of it, which is eight characters and an
   ellipsis, and the narrower tiers can seat none.

   So it comes out of the layout entirely. Nothing is lost -- .user-menu-id in the panel this chip
   opens shows the full name and the address, which is where an account is confirmed anyway, and
   the avatar remains the signed-in signal. The payoff is that the signed-in and signed-out rows
   are now the same width, so one set of breakpoints is correct for both.

   Hidden the .sr-only way rather than display:none: the chip is a link whose only text is this
   span, and display:none would leave it with no accessible name at all. */
.user-chip-name{
  position:absolute;left:-9999px;
  width:1px;height:1px;overflow:hidden;
  font-size:14px;font-weight:800;color:var(--navy);white-space:nowrap;
}
.user-chip{gap:0;}

.user-menu-toggle{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:30px;height:30px;border:none;border-radius:50%;
  background:none;cursor:pointer;color:var(--text-muted);
  transition:background .16s ease,color .16s ease;
}
.user-menu-toggle:hover{background:var(--bg-hover);color:var(--navy);}
.user-menu-toggle svg{width:16px;height:16px;stroke-width:2.2;transition:transform .18s ease;}
.user-menu[data-open="true"] .user-menu-toggle svg{transform:rotate(180deg);}

/* Right-aligned rather than centred under its trigger: the chip is the last thing in
   the header, so a centred panel would overflow the viewport edge. */
.user-menu-panel{
  position:absolute;top:calc(100% + 10px);right:0;
  min-width:248px;padding:8px;
  background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--sh-menu);
  display:flex;flex-direction:column;gap:2px;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .18s ease,visibility .18s ease;
  z-index:130;
}

/* Click-driven only -- deliberately no :hover rule. A menu that opens on hover directly
   under the pointer's resting place after a page load is easy to trigger by accident.

   sm-menu-right translates on Y only, because this panel is pinned with right:0. A keyframe
   written for a left:50% trigger-centred menu carries translateX(-50%) through both frames,
   and reused here it would drag the panel half its own width off to the left -- with
   animation-fill-mode both leaving it there once finished. */
.user-menu[data-open="true"] .user-menu-panel{
  opacity:1;visibility:visible;pointer-events:auto;
  animation:sm-menu-right .18s ease both;
}

@keyframes sm-menu-right{
  from{opacity:0;transform:translateY(-8px);}
  to{opacity:1;transform:translateY(0);}
}

/* No-JS fallback. Scoped to html:not(.js) -- site.js sets that class before first paint -- so it
   never competes with the click toggle. Unscoped, :focus-within would hold the panel open after
   the caret is clicked a second time, because the button still has focus. */
html:not(.js) .user-menu:focus-within .user-menu-panel{
  opacity:1;visibility:visible;pointer-events:auto;
}

/* Identity block at the top of the panel. The header chip shows the name only, so this is the
   one place that answers "which account am I signed in as" -- two people called Vishani would
   otherwise be indistinguishable without navigating to the account pages. */
.user-menu-id{
  display:flex;flex-direction:column;gap:2px;
  padding:8px 12px 12px;margin-bottom:6px;
  border-bottom:1px solid var(--line-soft);
}
.user-menu-id-name{font-size:14px;font-weight:800;color:var(--navy);}

/* break-all, not ellipsis: a truncated address cannot be checked, which is the whole point of
   showing it here. Wrapping is the lesser evil. */
.user-menu-id-email{
  font-size:12.5px;font-weight:500;color:var(--text-faint);
  word-break:break-all;line-height:1.45;
}

.user-menu-panel a,
.user-menu-panel button{
  display:flex;align-items:center;gap:11px;width:100%;
  padding:10px 12px;border:none;background:none;text-align:left;
  border-radius:12px;
  font-family:var(--sans);font-size:14px;font-weight:600;color:var(--navy);
  cursor:pointer;
  transition:background .16s ease,color .16s ease;
}
.user-menu-panel a:hover,
.user-menu-panel button:hover{background:var(--bg-soft);color:var(--navy);}
.user-menu-panel svg{width:17px;height:17px;stroke-width:1.9;flex:none;color:var(--text-muted);}

.user-menu-panel form{
  margin-top:4px;padding-top:6px;border-top:1px solid var(--line-soft);
}
.user-menu-panel form button{color:var(--text-muted);}
.user-menu-panel form button:hover{color:var(--bad-ink);background:#FDF2F2;}
.user-menu-panel form button:hover svg{color:var(--bad-ink);}

.nav-toggle{
  display:none;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  width:46px;height:46px;border:1.5px solid var(--line-strong);
  border-radius:12px;background:#fff;cursor:pointer;
}
.nav-toggle span{display:block;width:18px;height:2px;border-radius:2px;background:var(--navy);}

/* Mobile drawer */
.drawer{
  position:fixed;inset:0;z-index:200;
  background:var(--navy);color:#fff;overflow-y:auto;
  animation:sm-fade .22s ease both;
}
.drawer[hidden]{display:none;}
.drawer-top{
  max-width:var(--shell);margin:0 auto;padding:0 var(--gutter);
  /* Fixed, not tied to --header-h: the drawer only opens on narrow viewports where the
     desktop header is a single short row, so it doesn't need the two-row height. */
  display:flex;align-items:center;justify-content:space-between;height:76px;
}
.drawer-top img{width:52px;height:auto;}
.drawer-close{
  width:46px;height:46px;border:1px solid rgba(255,255,255,0.25);
  border-radius:12px;background:rgba(255,255,255,0.06);
  color:#fff;font-size:20px;line-height:1;cursor:pointer;
}
.drawer-body{
  max-width:var(--shell);margin:0 auto;
  padding:16px var(--gutter) 56px;
  display:flex;flex-direction:column;gap:8px;
}
.drawer-link{
  border-bottom:1px solid rgba(255,255,255,0.1);
  display:block;width:100%;
  font-family:var(--serif);font-size:28px;font-weight:500;
  color:#fff;padding:16px 2px;letter-spacing:-0.01em;
}
.drawer-link:hover{color:var(--cyan-light);}
.drawer-label{
  font-size:11.5px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--cyan-light);margin:28px 0 6px;
}
.drawer-mods{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:6px;}
.drawer-mods a{
  background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.12);
  border-radius:var(--r-sm);text-align:left;
  display:flex;align-items:center;gap:12px;padding:16px;
  font-size:15px;font-weight:700;color:#fff;min-height:56px;
}
.drawer-mods a:hover{color:#fff;background:rgba(255,255,255,0.12);}
.drawer-cta{display:flex;flex-direction:column;gap:12px;margin-top:32px;}
.drawer-cta .btn{height:52px;font-size:15px;}
.drawer-cta .btn-white{box-shadow:none;}
body.drawer-open{overflow:hidden;}

/* --------------------------------------------------------------------------
   Where the desktop nav gives way to the drawer

   The switch used to happen at 1079px, but the row has never fitted in 1080px.
   Measured at full spacing: brand 201 + nav 657 + actions 339 + two 24px wrap gaps
   + two 40px gutters = ~1325px of demand. So every viewport from 1080 to 1324 --
   including a 1280px laptop -- kept the desktop nav and pushed "Request a Demo"
   past the right gutter, where it was clipped and left the page scrolling
   horizontally. The breakpoint was describing a layout that did not exist.

   Fixed as two tiers rather than by moving one number, because sending a 1280px
   laptop to a hamburger to fix a 40px overflow is the worse trade:

     >= 1361px   full spacing (needs ~1300px, so it has room to spare)
     1200-1360px compact -- same links, tightened padding and gaps (needs ~1150px)
     <= 1199px   drawer

   Those two demand figures are re-measured for the 15.5px header text and the shorter
   "All Modules" label: the bigger type costs about what the shorter label gives back,
   so both tiers still clear their own floor by the same margin they did at 14px.

   The drawer loses nothing: it carries the same links, the module list, Sign in,
   Contact and the demo CTA.
   -------------------------------------------------------------------------- */
@media (min-width:1200px) and (max-width:1360px){
  header.site > .wrap{gap:16px;}
  .nav-primary{gap:2px;}
  .nav-primary .nav-link{padding:10px 9px;}
  .nav-actions{gap:8px;}
  .nav-actions .nav-signin{padding:10px 8px;}
  .nav-actions .btn-sm{padding:0 14px;}
}

@media (max-width:1199px){
  .nav-primary,.nav-actions{display:none;}
  .nav-toggle{display:flex;}
}

/* --------------------------------------------------------------------------
   Unverified-email bar

   Site chrome, not a page component: it is rendered by _RedesignLayout for any signed-in customer
   whose address is unconfirmed, so it has to live in site.css -- account.css is only loaded by the
   pages under /account, and the bar shows on marketing pages too.

   Amber (the --vault ramp) rather than red: nothing is broken and nothing is lost, there is one step
   left. Sits directly under the sticky header in normal flow, so it never overlaps content and never
   needs a z-index of its own.
   -------------------------------------------------------------------------- */
.verify-bar{background:#FFF4E0;border-bottom:1px solid #F2DFBE;}
.verify-bar > .wrap{
  display:flex;align-items:center;gap:14px;
  padding:11px 0;
}
.verify-bar-ico{
  flex:none;width:24px;height:24px;border-radius:8px;
  background:var(--vault);color:#fff;
  display:flex;align-items:center;justify-content:center;
  font-size:13px;font-weight:800;
}
.verify-bar p{
  margin:0;flex:1;min-width:0;
  font-size:13.5px;line-height:1.5;color:var(--vault-ink);text-wrap:pretty;
}
.verify-bar p strong{color:var(--navy);}
/* Amber-on-white rather than the white button's default shadow, which reads as a raised card
   against a tinted bar. */
.verify-bar .btn-white{flex:none;box-shadow:none;color:var(--navy);}

@media (max-width:640px){
  /* The button drops to its own line rather than squeezing the message to two words. */
  .verify-bar > .wrap{flex-wrap:wrap;gap:10px;}
  .verify-bar p{flex:1 1 100%;order:2;}
  .verify-bar .btn-white{order:3;width:100%;justify-content:center;}
}

/* --------------------------------------------------------------------------
   Breadcrumbs
   -------------------------------------------------------------------------- */
.crumbs{
  font-size:13px;color:var(--text-muted);margin-bottom:22px;
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;
}
.crumbs a{font-weight:700;font-size:13px;}

/* --------------------------------------------------------------------------
   Home hero
   -------------------------------------------------------------------------- */
.hero{
  position:relative;overflow:hidden;background:var(--navy-deep);
  display:flex;align-items:center;
  min-height:min(88vh,760px);padding:clamp(72px,9vw,120px) 0;
}
.hero-media{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;}
.hero-scrim{
  position:absolute;inset:0;z-index:1;
  background:linear-gradient(104deg,
    rgba(4,9,26,0.95) 0%,rgba(8,17,46,0.88) 44%,
    rgba(8,17,46,0.58) 72%,rgba(8,17,46,0.34) 100%);
}
.hero > .wrap{position:relative;z-index:2;width:100%;}
/* 1120px, not 900px, because of the headline. Each clause of .h1-hero is its own block (see
   .h1-hero em) and needs to sit on one line. The italic clause measures ~893px at the 70px top of
   the clamp, which technically cleared a 900px measure but by 7px -- any change to the face, the
   size or the wording pushed it over and it wrapped. The extra room is margin against that, not
   decoration. The lede keeps its own narrower 760px measure below, so this only affects the
   headline. */
.hero-copy{max-width:1120px;}
.hero-copy h1{margin-bottom:24px;color:#fff;}
.hero-copy .lede-hero{max-width:760px;margin-bottom:36px;}
.hero-copy .row{margin-bottom:48px;}

.badge-hero{
  display:inline-flex;align-items:center;gap:10px;
  font-size:12px;font-weight:800;letter-spacing:.16em;text-transform:uppercase;
  color:var(--cyan-pale);background:rgba(0,174,255,0.1);
  border:1px solid rgba(0,174,255,0.32);
  padding:8px 16px;border-radius:var(--pill);margin-bottom:28px;
}

/* Stat rail */
.stats{
  display:flex;gap:clamp(24px,4vw,52px);flex-wrap:wrap;
  padding-top:28px;border-top:1px solid var(--line);
}
.stats dt{font-family:var(--serif);font-size:26px;font-weight:500;color:var(--navy);line-height:1.1;}
.stats dd{font-size:12.5px;color:var(--text-muted);margin-top:4px;}
.stats-top{margin-top:36px;}
/* .stats-lg and .stats.on-dark are gone with the hero KPI rail they were written for -- the home
   hero was the only .stats on a dark background, and the only one at the larger size. The three
   surviving rails (/module, /explore, /anatomy-3d-viewer) are all light and all default size. */

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */
.card{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:clamp(26px,3vw,36px);
  display:flex;flex-direction:column;gap:14px;
}
.card-lift{transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease;}
.card-lift:hover{
  transform:translateY(-4px);box-shadow:0 24px 56px -28px rgba(14,22,56,0.3);
  border-color:var(--line-focus);
}
/* .card-num is gone with the home "Why SciMynd" card grid it was written for -- the pillars are a
   rail now (.why-rail below) and nothing else numbered a card. */
.card-note{
  font-size:13.5px;color:var(--navy);background:var(--bg-soft);
  border-radius:12px;padding:14px 16px;font-weight:600;margin-top:auto;
}
.card h3{font-size:26px;line-height:1.15;}
.card-24 h3{font-size:24px;line-height:1.18;}

/* --------------------------------------------------------------------------
   Why rail (home "Why SciMynd")
   Claim on the left, evidence on the right. The claim is short and the three
   reasons are long, so the aside is centred against the rail rather than pinned
   to its top -- top-aligned, the whole lower half of the left column was empty.
   The two columns only exist above 1000px; below that everything stacks.
   -------------------------------------------------------------------------- */
.why-split{display:grid;gap:clamp(30px,4vw,56px);}
@media (min-width:1000px){
  .why-split{
    grid-template-columns:minmax(320px,0.9fr) 1.1fr;
    gap:clamp(48px,6vw,104px);
    align-items:center;
  }
}
.why-aside h2{margin-bottom:16px;}
.why-aside-cta{margin-top:28px;}

.why-rail{display:flex;flex-direction:column;}
.why-row{
  display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:clamp(16px,2.2vw,30px);
  padding:clamp(24px,2.8vw,32px) 0;
  border-top:1px solid var(--line);
}
/* The rail is enclosed rather than trailing off, so the last reason reads as the
   end of the argument and not as a list that was cut short. */
.why-row:last-child{border-bottom:1px solid var(--line);}
/* Serif numeral, sized to sit level with the title beside it. Pale by default:
   it is a position marker, and at this size a blue one would outrank the heading. */
.why-n{
  font-family:var(--serif);font-weight:500;
  font-size:clamp(30px,3.2vw,40px);line-height:1;
  color:var(--line-dashed);letter-spacing:-0.02em;
  font-variant-numeric:lining-nums tabular-nums;
}
.why-title{font-size:clamp(21px,2vw,25px);margin-bottom:10px;}
/* The takeaway line, the part a visitor skims for. A blue rule and italic serif
   set it apart from the body without the grey box the card version used, which
   at this width would have been a full-column slab. */
.why-note{
  margin-top:16px;padding-left:16px;
  border-left:2px solid var(--blue);
  font-family:var(--serif);font-size:16.5px;font-style:italic;
  line-height:1.45;color:var(--navy);text-wrap:pretty;
}
@media (max-width:520px){
  /* At phone width the numeral column eats the title's line length, so it goes
     inline above the title instead of beside it. */
  .why-row{grid-template-columns:1fr;gap:6px;}
  .why-n{font-size:22px;}
}

/* Module / solution card */
.mod-card{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:28px 26px;text-align:left;cursor:pointer;
  display:flex;flex-direction:column;gap:10px;color:inherit;
  transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease;
}
.mod-card:hover{
  transform:translateY(-5px);box-shadow:var(--sh-card-hover);
  border-color:var(--line-focus);color:inherit;
}
.mod-card.pad-lg{padding:30px 28px;}

/* Pointer spotlight -- module cards only (the ones _ModuleCard marks with data-glow;
   the solution cards on the home page use .mod-card too and stay flat).

   Two layers, both centred on --px / --py: the pointer position in that card's own
   coordinates, written by initCardGlow in site.js. ::before is a wash across the face,
   ::after is the same gradient masked down to a 1px band sitting exactly on the card's
   border, so the edge nearest the pointer lights while the rest of the outline stays as
   it was. The gradient is narrower than the grid, which is the point: cards light as the
   pointer passes near them and fade as it moves on, instead of switching on at :hover.

   Both are tinted with --glow, which the partial sets to the module's own icon colour --
   Core lights orange, Synapse blue, Amplify teal. The tint comes from layer opacity
   rather than a translucent colour so the eight brand values stay exactly as declared at
   the top of this file, with no per-module alpha variants to keep in step with them.

   --px defaults far off-card, so a card is flat until the pointer has actually moved:
   that is also what touch devices get, since site.js never binds there. z-index:-1 needs
   the isolation, or the layers would paint behind the card's own white background. */
.mod-card[data-glow]{position:relative;isolation:isolate;--glow-size:280px;}
.mod-card[data-glow]::before,
.mod-card[data-glow]::after{
  content:'';position:absolute;inset:-1px;z-index:-1;pointer-events:none;
  border-radius:calc(var(--r-card) + 1px);
  transition:opacity .35s ease;
}
.mod-card[data-glow]::before{
  opacity:.13;
  background:radial-gradient(var(--glow-size) var(--glow-size) at
    calc(var(--px,-9999) * 1px) calc(var(--py,-9999) * 1px),
    var(--glow,transparent),transparent 72%);
}
.mod-card[data-glow]:hover::before{opacity:.22;}
/* padding + the content-box mask cut is what leaves only the border band painted; with
   inset:-1px the padding box lands exactly on the card's border box, so the band covers
   the real border rather than sitting inside or outside it. */
.mod-card[data-glow]::after{
  padding:1px;opacity:.9;
  background:radial-gradient(calc(var(--glow-size) * .85) calc(var(--glow-size) * .85) at
    calc(var(--px,-9999) * 1px) calc(var(--py,-9999) * 1px),
    var(--glow,transparent),transparent 68%);
  -webkit-mask:linear-gradient(#000,#000) content-box,linear-gradient(#000,#000);
  mask:linear-gradient(#000,#000) content-box,linear-gradient(#000,#000);
  -webkit-mask-composite:xor;
  mask-composite:exclude;
}

/* The module mark is the shipped app-icon artwork, not a tinted box with a letter in it:
   the rounded corners, the two-tone swoosh and the letterform all live inside the SVG. So
   this is a size box only -- no background, radius or font, and nothing to keep in sync
   with the icon files. Squared aspect is enforced rather than assumed, because an SVG that
   failed to load would otherwise collapse the card's first row. */
.mod-mark{width:46px;height:46px;display:block;flex:none;}

/* The icon's own row, height-locked at the icon size so every card in a row starts its heading on
   the same baseline whether or not the icon SVG has loaded. */
.mod-card-top{
  display:flex;align-items:center;justify-content:space-between;
  gap:12px;margin-bottom:12px;min-height:46px;
}
.mod-card h2,.mod-card h3{font-size:21px;line-height:1.2;}
.mod-card.pad-lg h3{font-size:22px;}
.mod-tag{
  font-size:10.5px;font-weight:800;letter-spacing:.13em;
  text-transform:uppercase;color:var(--navy);
}
.mod-lead{font-size:14px;color:var(--text-muted);text-wrap:pretty;}
.card-cta{
  margin-top:6px;font-size:13px;font-weight:700;color:var(--blue);
  display:flex;align-items:center;gap:6px;
}

/* Media placeholder (the design ships these as content slots).

   Was a 1.5px dashed outline round a flat gradient. Dashed is the honest signal for "nothing here
   yet", but at 300px tall and full width it read as a broken image rather than a reserved frame,
   and a page carrying three of them looked unfinished rather than staged. This is the same promise
   in a finished-looking frame: a hairline border, a faded dot grid so the fill is not a dead
   expanse, and a caption naming what will land there. The height comes off the aspect ratio now,
   so slots keep a media shape instead of a fixed rectangle at every width. */
.slot{
  position:relative;overflow:hidden;isolation:isolate;
  border:1px solid var(--line-strong);border-radius:var(--r-card);
  background:linear-gradient(155deg,#FBFDFF 0%,#EDF3FD 100%);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;padding:36px 28px;min-height:240px;gap:11px;
}
/* The grid fades out towards the edges so it never fights the border. */
.slot::before{
  content:'';position:absolute;inset:0;z-index:-1;
  background-image:radial-gradient(rgba(10,111,208,0.16) 1px,transparent 1px);
  background-size:18px 18px;
  -webkit-mask-image:radial-gradient(ellipse 62% 62% at 50% 46%,#000,transparent 76%);
  mask-image:radial-gradient(ellipse 62% 62% at 50% 46%,#000,transparent 76%);
}
.slot-md{min-height:300px;}
.slot-icon{
  width:52px;height:52px;border-radius:50%;background:#fff;
  border:1px solid var(--line);display:flex;align-items:center;justify-content:center;
  font-size:20px;color:var(--blue);
  box-shadow:0 12px 26px -16px rgba(14,22,56,0.4);
}
.slot b{font-size:15px;color:var(--navy);line-height:1.35;}
/* Names the medium, so the frame says what it is holding a place for rather than just sitting
   there empty. */
.slot-note{
  font-size:10px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-faint);
}
.slot img{opacity:.9;}

/* Real footage, where a module has it -- same hairline frame as the slots above so the section reads
   the same whether it is holding a place or playing. Capped at 980px and centred rather than run to
   the full 1360px wrap: at full width a 16:9 frame is over 760px tall and the controls end up past
   the fold on a laptop. The frame is dark because the footage is, and a white card behind letterboxed
   video shows as a rim of grey. */
.media-film{
  max-width:980px;margin:0 auto;position:relative;
}

/* Click-to-play, on the frames marked data-poster-play. A poster whose composition
   runs to the bottom edge -- a lower third, a caption burned into the footage --
   sits under Chrome's control bar for as long as the video goes unplayed, and no
   amount of choosing a better frame fixes that. So the controls come off until the
   first press and this stands in for them. The button covers the whole frame rather
   than just the disc: the target people aim at on a video poster is the picture.
   Hidden until the script removes the attribute, so with no JS the native controls
   stay put and the player still works. */
.film-play{
  position:absolute;inset:0;display:grid;place-items:center;
  padding:0;border:0;background:transparent;cursor:pointer;
  border-radius:var(--r-card);-webkit-appearance:none;appearance:none;
}
.film-play[hidden]{display:none;}
.film-play-disc{
  display:grid;place-items:center;
  width:clamp(58px,5.4vw,76px);aspect-ratio:1;border-radius:50%;
  color:#fff;background:rgba(9,16,42,0.52);
  border:1px solid rgba(255,255,255,0.32);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  box-shadow:0 18px 40px -18px rgba(4,9,26,0.7);
  transition:background-color .18s ease,transform .18s ease;
}
/* The triangle's visual mass sits left of its bounding box, so a mathematically
   centred glyph reads as sitting too far left inside a circle. */
.film-play-disc svg{width:38%;height:38%;margin-left:6%;}
.film-play:hover .film-play-disc{background:rgba(9,16,42,0.72);transform:scale(1.05);}
.film-play:active .film-play-disc{transform:scale(0.98);}
@media (prefers-reduced-motion:reduce){
  .film-play-disc{transition:none;}
  .film-play:hover .film-play-disc,.film-play:active .film-play-disc{transform:none;}
}
.media-film video,
.rail-clip video{
  display:block;width:100%;height:auto;aspect-ratio:16 / 9;
  background:#0B1330;
  border:1px solid var(--line-strong);border-radius:var(--r-card);
  box-shadow:var(--sh-card);
}

/* Several clips in one horizontal line the visitor swipes -- see Redesign/_ReelMedia for why they
   are a rail rather than a stack. The frames themselves are the rule above, shared with the single
   film, so a module with five clips reads as the same component at the same scale as one with one.

   Native overflow scrolling and snap points do the paging: on a touch screen that is the swipe
   itself, and site.js drives the same scrollLeft from the buttons below. The track is padded by half
   its leftover width so the first and last clip can sit centred like the ones between them -- the
   alternative is a rail that snaps every clip to the middle except the two you start and end at. */
.media-rail{--rail-clip:min(880px,82vw);}
.media-rail-track{
  display:flex;gap:18px;
  padding-inline:max(0px,calc((100% - var(--rail-clip)) / 2));
  overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch;
  /* The buttons and the counter are the affordance. A bar running the full 1360px under one 880px
     video frame reads as browser chrome that ended up inside the page. */
  scrollbar-width:none;
}
.media-rail-track::-webkit-scrollbar{display:none;}
.rail-clip{
  flex:0 0 var(--rail-clip);margin:0;
  /* Same as .media-film, and for the same reason: the click-to-play disc pins itself to the frame. */
  position:relative;
  scroll-snap-align:center;
}

/* Closed into a loop by site.js, which copies the last two clips in front of the first and the first
   two behind the last. The padding above was what held a lone first clip in the middle of the track;
   the copies stand in that space now, so the frame beside the first clip is the fifth rather than the
   page, and the padding would only push the copies back off the edges they were put there to fill.
   The copies are scenery and a landing strip -- pointer-events keeps the reel's controls to the five
   clips that are really in it, so a click on the fifth peeking in at the left edge cannot start a
   second copy of a video playing off the side of the rail. */
.media-rail.is-looped .media-rail-track{padding-inline:0;}
.rail-clip-copy{pointer-events:none;}
.media-rail-foot{
  display:flex;align-items:center;justify-content:center;gap:18px;
  margin-top:20px;
}
.media-rail-btn{
  width:44px;height:44px;border-radius:50%;flex:none;
  display:flex;align-items:center;justify-content:center;
  background:#fff;border:1px solid var(--line-strong);
  color:var(--navy);cursor:pointer;
  box-shadow:0 12px 26px -16px rgba(14,22,56,0.4);
  transition:border-color .2s ease,color .2s ease,opacity .2s ease;
}
.media-rail-btn:hover{border-color:var(--blue);color:var(--blue);}
.media-rail-btn svg{
  width:20px;height:20px;fill:none;stroke:currentColor;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round;
}
.media-rail-count{
  font-size:11px;font-weight:800;letter-spacing:.13em;
  color:var(--text-faint);font-variant-numeric:tabular-nums;
}
/* The buttons are the script's, so without it they are not offered. The track still scrolls and
   still snaps -- that part is the browser's. */
html:not(.js) .media-rail-foot{display:none;}

/* --------------------------------------------------------------------------
   Panels
   -------------------------------------------------------------------------- */
.band{
  background:linear-gradient(118deg,var(--navy) 0%,var(--navy-3) 100%);
  border-radius:var(--r-band);
  padding:clamp(24px,3vw,34px) clamp(24px,3.4vw,40px);
  display:flex;align-items:center;justify-content:space-between;
  gap:24px;flex-wrap:wrap;box-shadow:var(--sh-band);
}
.band-copy{display:flex;align-items:center;gap:20px;flex-wrap:wrap;}
.band-copy p{
  color:rgba(255,255,255,0.9);font-size:clamp(16px,1.05vw,17.5px);line-height:1.6;
  max-width:660px;text-wrap:pretty;
}
.band-copy p strong{color:#fff;font-weight:700;}
.band-pill{
  background:rgba(0,174,255,0.16);color:var(--cyan-pale);
  border:1px solid rgba(0,174,255,0.42);
  font-size:12px;font-weight:800;letter-spacing:.11em;
  padding:8px 15px;border-radius:var(--pill);white-space:nowrap;
}

.panel-dark{
  background:var(--navy);border-radius:var(--r-panel);
  padding:clamp(32px,5vw,60px) clamp(24px,4vw,52px);
  position:relative;overflow:hidden;
}
.panel-dark::before{
  content:'';position:absolute;top:-28%;left:-8%;
  width:520px;height:520px;border-radius:50%;
  background:radial-gradient(circle,rgba(0,174,255,0.2),transparent 70%);
}
.panel-dark.glow-right::before{
  left:auto;right:-8%;
  background:radial-gradient(circle,rgba(0,174,255,0.18),transparent 70%);
}
.panel-dark > *{position:relative;z-index:2;}
.panel-dark .sec-head{margin-bottom:44px;}
.panel-dark .sec-head p{color:rgba(255,255,255,0.78);font-size:clamp(16px,1.3vw,18px);line-height:1.6;text-wrap:pretty;}
.panel-foot{
  margin-top:32px;padding-top:26px;
  border-top:1px solid rgba(255,255,255,0.14);
  color:rgba(255,255,255,0.75);font-size:15.5px;line-height:1.6;text-wrap:pretty;
}
.panel-foot strong{color:#fff;font-weight:700;}

.cta-panel{
  background:linear-gradient(135deg,var(--blue-bright) 0%,var(--blue-deep) 100%);
  border-radius:var(--r-panel);
  padding:clamp(40px,5vw,68px) clamp(24px,4vw,52px);
  text-align:center;position:relative;overflow:hidden;
}
.cta-panel::before{
  content:'';position:absolute;inset:0;
  background:radial-gradient(circle at 20% 15%,rgba(255,255,255,0.24),transparent 52%);
}
.cta-panel > *{position:relative;}
.cta-panel h2{color:#fff;margin-bottom:16px;}
.cta-panel p{
  color:rgba(255,255,255,0.9);font-size:16.5px;
  margin:0 auto 32px;max-width:560px;text-wrap:pretty;
}

/* Journey / pipeline steps */
.steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:16px;}
.steps-wide{grid-template-columns:repeat(auto-fit,minmax(250px,1fr));}
.steps li{
  background:rgba(255,255,255,0.05);
  border:1px solid rgba(255,255,255,0.13);
  border-radius:var(--r-md);padding:24px 22px;
}
.steps li.is-active{
  background:linear-gradient(135deg,rgba(0,174,255,0.28),rgba(0,174,255,0.09));
  border-color:rgba(0,174,255,0.6);
}
.step-n{
  width:32px;height:32px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-size:13.5px;font-weight:800;margin-bottom:18px;
  background:rgba(255,255,255,0.13);color:#fff;
}
.steps li.is-active .step-n{background:var(--cyan);color:var(--navy);}
.steps h3{
  font-family:var(--sans);color:#fff;font-size:17px;font-weight:800;
  margin-bottom:7px;line-height:1.35;
}
.steps span{
  color:rgba(255,255,255,0.65);font-size:12px;
  letter-spacing:.07em;text-transform:uppercase;font-weight:600;
}
.steps p{color:rgba(255,255,255,0.75);font-size:15px;line-height:1.6;text-wrap:pretty;}
.steps-wide li{padding:28px 24px;}
.steps-wide h3{margin-bottom:8px;}

/* ==========================================================================
   /why-scimynd
   The page is one argument in three movements: what an answer carries (hero),
   how that differs from a generated one (table), and what the difference buys
   you (pillars). Everything below is scoped to that page and used nowhere else.
   ========================================================================== */

/* --- Hero -----------------------------------------------------------------
   Copy left, launch film right. As a single column the copy topped out at 760px
   and left the whole right half of a 1440px shell empty, with the fold landing
   in that gap. The film is the page's argument shown rather than stated, so it
   takes the slightly wider column -- the frame lands near 660x371 at the 1360px
   wrap, big enough to watch in place, and the headline stays beside it. */
.why-hero-grid{display:grid;gap:clamp(30px,4vw,48px);align-items:center;}
@media (min-width:1000px){
  .why-hero-grid{
    grid-template-columns:minmax(0,1fr) minmax(420px,1.06fr);
    gap:clamp(44px,5vw,72px);
  }
}
.why-hero-copy h1{max-width:680px;}
/* Same reason as .h1-hero em on the home page: the headline is a statement and an italic
   follow-on, and inline the break landed wherever the measure happened to put it. */
.why-hero-copy h1 em{display:block;}
.why-hero-copy .lede{max-width:60ch;margin-top:18px;}
.why-hero-cta{margin-top:clamp(26px,3vw,34px);}

/* The five-line contract, under the hero rather than in it. As a card in the
   right column it was competing with the film for the same slot; across the
   full width the same rows read as a spec bar between the film and the table
   that argues each one out. */
.prov-strip{
  margin-top:clamp(30px,3.6vw,48px);
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:clamp(20px,2.2vw,26px) clamp(22px,2.6vw,30px);
  box-shadow:0 24px 56px -42px rgba(14,22,56,0.42);
}
.prov-strip-head{
  display:flex;align-items:center;gap:10px;
  font-size:11.5px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-faint);
}
.prov-dot{
  width:8px;height:8px;border-radius:50%;flex:none;
  background:var(--good);box-shadow:0 0 0 4px rgba(30,158,140,0.14);
}
/* Explicit column counts rather than auto-fit: five items divide evenly only into
   one column or five, and auto-fit picked four in the 1000-1180px band, which left
   "Result" -- the row that concludes the other four -- stranded alone underneath.
   1 / 3 / 5 keeps the ragged tail to a pair at worst. */
.prov-strip-list{
  display:grid;grid-template-columns:minmax(0,1fr);
  gap:20px clamp(24px,2.6vw,36px);
  margin-top:18px;padding-top:18px;border-top:1px solid var(--line-soft);
}
@media (min-width:680px){.prov-strip-list{grid-template-columns:repeat(3,minmax(0,1fr));}}
@media (min-width:1180px){.prov-strip-list{grid-template-columns:repeat(5,minmax(0,1fr));}}
.prov-strip-list li{display:grid;gap:7px;align-content:start;}
/* The last row is the consequence of the four before it, not a fifth input --
   its value picks up the same green as the status dot. */
.prov-strip-list li:last-child .prov-v{color:var(--good-ink);}
.prov-k{
  font-size:10.5px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-faint);
}
.prov-v{font-size:15px;font-weight:600;line-height:1.45;color:var(--navy);text-wrap:pretty;}

/* --- Comparison table -----------------------------------------------------
   The SciMynd column is a highlighted lane running header to last row, the way
   a pricing table marks its recommended plan: the eye finds the answer without
   reading the header. Body copy sits at 15.5/16px here rather than the 14.5px
   this table used to run at -- it is the densest block on the site and was the
   smallest type on it. */
.compare-wrap{
  border:1px solid var(--line);border-radius:var(--r-card);
  overflow:hidden;background:#fff;
  box-shadow:0 24px 60px -40px rgba(14,22,56,0.4);
}
.compare{width:100%;border-collapse:collapse;table-layout:fixed;}
.compare thead tr{background:var(--navy);}
.compare th[scope="col"]{
  text-align:left;padding:20px 26px;vertical-align:middle;
  font-family:var(--sans);font-size:13.5px;font-weight:800;letter-spacing:.03em;
  color:rgba(255,255,255,0.74);
}
.compare th.col-dim{width:26%;}
.compare th.col-ai{width:37%;}
/* Only this heading clears the marker column (19px glyph + 12px gap), so it sits over the prose
   it labels rather than over the ticks. */
.compare th.col-sm{
  width:37%;padding-left:57px;color:#fff;
  background:rgba(0,174,255,0.16);
  box-shadow:inset 0 -3px 0 var(--cyan);
}
.compare tbody tr + tr{border-top:1px solid var(--line-section);}
.compare th[scope="row"]{
  text-align:left;padding:22px 26px;vertical-align:top;
  font-family:var(--sans);font-size:16px;font-weight:700;line-height:1.4;
  color:var(--navy);
}
.compare td{
  padding:22px 26px;vertical-align:top;
  font-size:15.5px;line-height:1.6;color:var(--text-body);text-wrap:pretty;
}
.compare td.sm{
  color:var(--navy);font-weight:600;background:var(--good-bg-2);
  box-shadow:inset 1px 0 0 var(--good-line),inset -1px 0 0 var(--good-line);
}

/* Cell marker: a tick and a line of prose, on the SciMynd side only. Grid rather than flex so a
   wrapped second line aligns under the first instead of under the icon. */
.mk{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:start;}
.mk-i{width:19px;height:19px;flex:none;margin-top:2px;}
.sm .mk-i,.v-sm .mk-i{color:var(--good);}

/* Stacked below 860px, where three columns of prose either overflow or shrink
   past reading size. Same marker, so the two renderings read as one thing. */
.compare-cards{display:none;flex-direction:column;gap:16px;}
.compare-card{
  border:1px solid var(--line);border-radius:var(--r-card);background:#fff;
  padding:24px 22px;box-shadow:var(--sh-card);
}
.compare-card h3{
  font-family:var(--sans);font-size:17px;font-weight:800;letter-spacing:-0.01em;
  margin-bottom:18px;
}
.compare-card .k{
  font-size:10.5px;font-weight:800;letter-spacing:.13em;text-transform:uppercase;
  color:var(--text-faint);margin-bottom:8px;
}
/* Both values are panels, so each column label sits over a block rather than one over a panel
   and one over loose prose -- and neither label has to be indented past the marker to line up
   with the sentence it introduces. */
.compare-card .v-ai,.compare-card .v-sm{
  font-size:15px;line-height:1.6;
  border-radius:var(--r-md);padding:14px 16px;
}
.compare-card .v-ai{
  color:var(--text-body);margin-bottom:20px;
  background:var(--bg-soft);border:1px solid var(--line-soft);
}
.compare-card .v-sm{
  color:var(--navy);font-weight:600;
  background:var(--good-bg-2);border:1px solid var(--good-line);
}
@media (max-width:860px){
  .compare-wrap{display:none;}
  .compare-cards{display:flex;}
}

/* --- Pillars --------------------------------------------------------------
   Four cards across a 1440px shell gave each one a ~310px column for a
   50-word paragraph, which is why the body copy had been pushed down to
   14.5px. Two across at 16px is the same content at a readable measure.
   The numeral and the italic takeaway line are the home page's .why-rail
   treatment, so the two places that argue this point look related. */
.pillar-grid{display:grid;gap:clamp(20px,2.4vw,28px);}
@media (min-width:900px){.pillar-grid{grid-template-columns:repeat(2,minmax(0,1fr));}}
.pillar{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:clamp(26px,2.8vw,34px);
  display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:clamp(18px,2vw,26px);align-items:start;
}
.pillar-n{
  font-family:var(--serif);font-weight:500;
  font-size:clamp(30px,3vw,40px);line-height:1;
  color:var(--line-dashed);letter-spacing:-0.02em;
  font-variant-numeric:lining-nums tabular-nums;
}
.pillar-title{font-size:clamp(21px,2vw,25px);margin-bottom:12px;}
.pillar-body{font-size:16px;line-height:1.7;color:var(--text-muted);text-wrap:pretty;}
.pillar-note{margin-top:20px;padding-left:16px;border-left:2px solid var(--blue);}
.pillar-note .k{
  display:block;font-family:var(--sans);
  font-size:10.5px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  color:var(--blue);margin-bottom:6px;
}
.pillar-note p{
  font-family:var(--serif);font-size:16.5px;font-style:italic;line-height:1.45;
  color:var(--navy);text-wrap:pretty;
}
@media (max-width:520px){
  /* Same reason as .why-row: at phone width the numeral column eats the
     title's measure, so it goes above the title instead of beside it. */
  .pillar{grid-template-columns:1fr;gap:8px;}
  .pillar-n{font-size:22px;}
}

/* --------------------------------------------------------------------------
   Pricing
   -------------------------------------------------------------------------- */
.toggle{
  display:inline-flex;background:#fff;border:1px solid var(--line-strong);
  border-radius:var(--pill);padding:5px;gap:4px;
  box-shadow:0 6px 18px -12px rgba(14,22,56,0.35);
}
.toggle-soft{background:var(--bg-soft);box-shadow:none;}
.toggle a{
  display:inline-flex;align-items:center;justify-content:center;
  height:42px;padding:0 24px;border-radius:var(--pill);
  font-size:14px;font-weight:700;
  background:transparent;color:var(--text-muted);
  transition:background .2s ease,color .2s ease;
}
.toggle-lg a{height:44px;padding:0 28px;font-size:14.5px;}
.toggle a[aria-pressed="true"]{background:var(--navy);color:#fff;}
.toggle-row{display:flex;justify-content:center;margin-bottom:clamp(28px,3.4vw,44px);}

.plan{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:30px 24px;display:flex;flex-direction:column;position:relative;
  box-shadow:var(--sh-card);
}
.plan-full{padding:32px 24px;}
.plan.is-featured{
  border:2px solid var(--blue-mid);
  box-shadow:0 30px 70px -34px rgba(10,131,224,0.65);
}
.plan-badge{
  position:absolute;top:-13px;left:50%;transform:translateX(-50%);
  background:var(--navy);color:#fff;font-size:11px;font-weight:800;
  padding:6px 15px;border-radius:var(--pill);letter-spacing:.06em;white-space:nowrap;
}
.plan.is-featured .plan-badge{background:var(--blue);}
.plan h2,.plan h3{font-size:22px;margin-bottom:6px;}
/* Reserved at exactly two lines so a sub that wraps at a narrow card width does not push its own
   price row below its neighbours'. It was 56px on the full card -- two and a half lines, sized when
   the widest sub ran long -- which every one-line sub paid for as a gap over the price.
   Centred in that reservation, not sat on top of it: a one-line sub top-aligned in a two-line box
   leaves the whole spare line under the text, which reads as the name and the price drifting apart.
   The bottom margin is small for the same reason -- half the space below the text is the reservation
   itself, so 18px on top of it double-counted. */
.plan-sub{
  font-size:13.5px;color:var(--text-muted);margin-bottom:10px;
  line-height:1.65;min-height:calc(2 * 1.65em);
  display:flex;align-items:center;
}
.plan-strike{
  font-size:13px;color:var(--text-faint);
  text-decoration:line-through;margin-bottom:2px;
}
.plan-amt{
  font-family:var(--serif);font-size:38px;font-weight:500;
  color:var(--navy);line-height:1.05;letter-spacing:-0.02em;
}
.plan-cur{
  font-family:var(--sans);font-size:0.52em;font-weight:800;
  vertical-align:0.62em;margin-right:2px;letter-spacing:0;
}
.plan-unit{font-size:13.5px;color:var(--text-muted);font-weight:600;margin-top:4px;}
.plan-alt{font-size:12.5px;color:var(--text-faint);margin-top:6px;}
.plan .btn-block{margin-top:auto;}
.plan .btn-outline{box-shadow:none;}
.plan-inherits{
  margin:18px 0 -6px;font-size:13px;font-weight:700;color:var(--navy);
  line-height:1.45;padding-left:24px;position:relative;
}
.plan-inherits::before{
  content:'\21AA';position:absolute;left:0;top:0;color:var(--blue);font-weight:800;
}
.plan-inherits-plus{font-weight:600;color:var(--text-muted);}

.plan-unlocks{
  margin:18px 0 0;font-size:11px;font-weight:800;color:var(--blue);
  letter-spacing:.09em;text-transform:uppercase;
}
/* The inheritance line follows it directly, so it loses its own top margin when both are present. */
.plan-unlocks + .plan-inherits{margin-top:8px;}
.plan-more{flex:0 0 auto;margin:0 0 18px;}
.plan-more>summary{
  cursor:pointer;font-size:12.5px;font-weight:700;color:var(--blue);
  list-style:none;padding:0;
}
.plan-more>summary::-webkit-details-marker{display:none;}
.plan-more>summary::after{content:' \25BE';}
.plan-more[open]>summary::after{content:' \25B4';}
.plan-more>summary:hover{text-decoration:underline;}
.plan-more>summary:focus-visible{outline:2px solid var(--blue);outline-offset:3px;border-radius:4px;}
/* The nested list re-declares its own spacing: it inherits .ticks, whose flex:1 and bottom margin
   are meant for the primary list and would otherwise push the expanded block away from the fold. */
.plan-more .ticks{margin:10px 0 0;flex:0 0 auto;}

.ticks{margin:22px 0 26px;flex:1;display:flex;flex-direction:column;gap:9px;}
.ticks li{font-size:13.5px;color:var(--text-body);padding-left:24px;position:relative;line-height:1.5;}
.ticks li::before{content:'\2713';position:absolute;left:0;top:1px;color:var(--blue);font-weight:800;}
.ticks-sm{gap:7px;margin:12px 0 0;flex:0 0 auto;}
.ticks-sm li{font-size:12.5px;padding-left:20px;}
.ticks-sm li::before{top:0;}

/* Credit packs */
.pack{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:28px 22px;text-align:center;box-shadow:var(--sh-card);
}
.pack.is-featured{border:2px solid var(--blue-mid);box-shadow:0 26px 60px -32px rgba(10,131,224,0.6);}
.pack h3{font-size:20px;margin-bottom:4px;}
.pack-credits{font-size:13.5px;color:var(--text-muted);margin-bottom:16px;}
.pack-price{font-family:var(--serif);font-size:32px;font-weight:500;color:var(--navy);line-height:1;}
.pack-each{font-size:12.5px;color:var(--text-faint);margin-top:8px;}

/* Asset tiers */
.tier{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:28px 24px;display:flex;flex-direction:column;
}
.tier h3{font-size:19px;line-height:1.25;margin-bottom:6px;text-wrap:balance;}
.tier-sub{font-size:13.5px;color:var(--text-muted);margin-bottom:20px;min-height:58px;text-wrap:pretty;}
.tier-rates{
  display:flex;gap:28px;padding:16px 0;
  border-top:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft);
}
.rate-k{
  font-size:10.5px;color:var(--text-faint);letter-spacing:.12em;
  text-transform:uppercase;font-weight:800;margin-bottom:4px;
}
.rate-v{font-family:var(--serif);font-size:26px;font-weight:500;line-height:1;}
.rate-v span{font-family:var(--sans);font-size:12px;font-weight:700;}
.rate-com{color:var(--core-ink);}
.tier-items{margin-top:16px;display:flex;flex-direction:column;gap:2px;}
.tier-items li{
  font-size:13px;color:var(--text-body);
  padding:9px 0 9px 20px;position:relative;
  border-bottom:1px solid var(--line-softer);line-height:1.5;
}
.tier-items li::before{
  content:'';position:absolute;left:0;top:15px;
  width:7px;height:7px;border-radius:2px;background:var(--dot,var(--blue));
}

/* Credit steps */
.credit-step{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:26px 22px;}
.credit-step .n{
  width:32px;height:32px;border-radius:50%;
  background:#EAF3FF;color:var(--blue);
  display:flex;align-items:center;justify-content:center;
  font-weight:800;font-size:13px;margin-bottom:14px;
}
.credit-step h3{font-family:var(--sans);font-size:15px;font-weight:800;margin-bottom:8px;}
.credit-step p{font-size:13.5px;color:var(--text-muted);line-height:1.6;text-wrap:pretty;}

/* Add-ons */
.addon{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:clamp(26px,3vw,34px);display:flex;flex-direction:column;
}
.addon h3{font-size:23px;margin-bottom:4px;}
.addon-sub{font-size:13.5px;color:var(--text-muted);margin-bottom:20px;}
.addon-price{font-family:var(--serif);font-size:32px;font-weight:500;color:var(--navy);line-height:1.05;}
.addon-price span{font-family:var(--sans);font-size:14px;color:var(--text-muted);font-weight:600;}
.addon .ticks{margin:22px 0 18px;}
.addon-note{
  font-size:12.5px;color:var(--text-muted);background:var(--bg-soft);
  border-radius:12px;padding:14px 16px;line-height:1.6;text-wrap:pretty;
}
.price-xl{font-family:var(--serif);font-size:38px;font-weight:500;color:var(--navy);line-height:1;}
.price-xl span{font-family:var(--sans);font-size:14px;color:var(--text-muted);font-weight:600;}

/* Square-bulleted lists */
.sq-list{display:flex;flex-direction:column;}
.sq-list li{
  font-size:15px;color:var(--navy);padding:13px 0;
  border-bottom:1px solid var(--line-soft);
  display:flex;align-items:flex-start;gap:12px;line-height:1.6;
}
.sq-list li::before{
  content:'';width:8px;height:8px;border-radius:2px;flex:none;margin-top:8px;
  background:var(--sq,var(--navy));
}
.sq-list-sm li{
  display:block;position:relative;
  font-size:14px;color:var(--text-body);padding:10px 0 10px 20px;
  border-bottom:1px solid var(--line-softer);
}
.sq-list-sm li::before{position:absolute;left:0;top:17px;width:6px;height:6px;margin:0;}

/* Standalone label pill. Lighter than it was (13px/700 on a tinted fill with 10px of vertical
   padding): at that weight a row of six read as six buttons competing with the real CTA under
   them, which is exactly the "everything shouts" look. White fill, medium weight, and the border
   doing the containing. */
.tag-pill{
  display:inline-flex;align-items:center;
  font-size:13px;font-weight:600;padding:8px 16px;border-radius:var(--pill);
  background:#fff;color:var(--text-strong);border:1px solid var(--line-strong);
  line-height:1.35;transition:border-color .18s ease,color .18s ease,background .18s ease;
}
a.tag-pill:hover{border-color:var(--blue);color:var(--blue);background:#F5FAFF;}
.tag-pill-sm{font-size:12.5px;padding:7px 13px;}

/* Dense, non-interactive chips. Where .tag-pill is a standalone label, these come in runs of
   eight or ten (a Catalyst vertical's capability list, Fusion's audiences) and have to read as
   one block of related terms rather than as a row of controls -- so they are quieter again, and
   the list owns the wrapping. */
.chip-list{display:flex;flex-wrap:wrap;gap:8px;list-style:none;}
.chip-static{
  font-size:12.5px;font-weight:600;line-height:1.35;
  color:var(--text-body);background:var(--bg-soft);
  border:1px solid var(--line-soft);border-radius:var(--pill);
  padding:7px 13px;
}

/* --- Who it's for -------------------------------------------------------------------------
   A caption and a run of chips, not a container. Audience labels are one or two words each, and
   every enclosing shape tried before this one -- cards, then a full-width bordered strip divided
   into cells -- sized itself off the section rather than off the words, so three short labels
   were spread across a 1300px bar with a quarter of it empty and the cell rules read as an empty
   table. Chips are as wide as their text, so four fit on one line, seven wrap to two, and neither
   leaves dead space.

   Audience strings carry an optional membership tier in parentheses ("Clinicians
   (Professional)"); the view splits it out and it renders inside the chip after a hairline, in
   caption case, so it cannot be mistaken for part of the audience name. */
.aud-row{
  display:flex;align-items:baseline;flex-wrap:wrap;
  gap:10px clamp(18px,2.2vw,32px);
}
.aud-row-head{
  flex:none;
  font-size:11.5px;font-weight:800;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text-faint);
}
.aud-list{display:flex;flex-wrap:wrap;gap:9px;list-style:none;}
.aud{
  display:inline-flex;align-items:center;gap:9px;
  padding:8px 15px;border-radius:var(--pill);
  background:#fff;border:1px solid var(--line-strong);
}
.aud-dot{
  width:6px;height:6px;border-radius:50%;flex:none;
  background:var(--aud,var(--blue));
}
.aud b{font-size:14px;font-weight:650;color:var(--navy);line-height:1.35;}
/* Divider drawn on the tier rather than as its own element: it only exists when a tier does. */
.aud-tier{
  padding-left:10px;margin-left:1px;border-left:1px solid var(--line);
  font-size:10.5px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-faint);
}
@media (max-width:640px){
  /* The caption takes its own line: beside the chips at this width it steals a chip's worth of
     room from every row below it. */
  .aud-row{display:block;}
  .aud-row-head{display:block;margin-bottom:12px;}
}

/* ==========================================================================
   Module page (/platform/{slug})

   Every module renders the same six blocks off SiteContent, so the layout has to hold up for a
   module with three stats and three audiences as well as one with ten features. What it did not
   hold up against was width: the whole page was a single left-aligned column inside a 1360px
   shell, so at desktop widths the right half of the hero, the stat rail and the audience row were
   empty, and the copy ran to 120-character lines wherever it was not explicitly capped.
   ========================================================================== */

/* Light on the bottom: the section after it opens with its own clamp(48px,6vw,92px), and the two
   together left a 170px band of nothing between the CTA row and the first eyebrow. */
.mod-hero{padding:clamp(40px,5vw,68px) 0 clamp(20px,2.4vw,36px);}

/* Copy left, at-a-glance panel right. Single column below 980px, where the panel would squeeze the
   copy into a gutter -- there it falls under the buttons and reads as a summary of what was said. */
.mod-hero-grid{
  display:grid;gap:clamp(30px,4vw,64px);
  grid-template-columns:minmax(0,1fr);align-items:start;
}
@media (min-width:980px){
  .mod-hero-grid{grid-template-columns:minmax(0,1fr) minmax(300px,380px);}
}
.mod-hero-copy{max-width:720px;}
.mod-hero-copy h1{margin-top:10px;}
.mod-hero-lede{margin:16px 0 14px;color:var(--text-body);}
.mod-hero-cta{margin-top:30px;}

/* The panel the stat rail moved into. The module's own tone appears once, as a soft bloom behind
   the icon -- enough to tell two module pages apart at a glance without tinting text or borders,
   which is where the brand tones fail contrast. */
.mod-glance{
  position:relative;overflow:hidden;
  background:#fff;border:1px solid var(--line);border-radius:var(--r-panel);
  padding:24px 26px 8px;
  box-shadow:0 26px 64px -44px rgba(14,22,56,0.6);
}
.mod-glance::before{
  content:'';position:absolute;top:-76px;right:-76px;
  width:210px;height:210px;border-radius:50%;
  background:var(--mod,var(--blue));opacity:.10;
}
.mod-glance > *{position:relative;}
.mod-glance-top{
  display:flex;align-items:center;gap:14px;
  padding-bottom:20px;
}
.mod-glance-mark{width:50px;height:50px;flex:none;}
.mod-glance-label{
  font-size:11px;font-weight:800;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text-faint);
}
.mod-facts{display:flex;flex-direction:column;}
.mod-facts > div{padding:15px 0;border-top:1px solid var(--line-soft);}
.mod-facts dt{
  font-family:var(--serif);font-size:25px;font-weight:500;
  color:var(--navy);line-height:1.1;letter-spacing:-0.015em;
}
.mod-facts dd{margin-top:3px;font-size:12.5px;color:var(--text-muted);line-height:1.5;}

/* The same rows on the heroes where the footage took the right column, laid across the copy measure
   instead of down a panel. Compounded selectors rather than source order, so the layout override
   cannot be undone by anything later in the file moving above it. */
/* Three exactly, not auto-fit. Every module carries three stats and always has, so auto-fit was
   measuring for a count that cannot vary -- and getting it wrong at the bottom of the two-column
   range, where a 482px copy column is a hair under three 148px tracks and the third stat dropped to
   a second row on its own, under a hairline running the full width for one item. Three fixed tracks
   hold the row down to the 980 breakpoint, below which the copy has the whole wrap to spend. */
.mod-facts.mod-spec{margin-top:34px;}

/* The row only exists where the hero has two columns. Below that the copy is the full 350 of a
   phone, three tracks in it are 105 each, and "Guided navigation" under "Standard" is one character
   from wrapping in a 105px box -- so the strip goes back to the stacked rows the card itself used at
   this width, which is what the visitor saw here before the footage moved in. */
@media (min-width:980px){
  .mod-facts.mod-spec{
    display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
    gap:0 clamp(18px,2.4vw,34px);
  }
  .mod-facts.mod-spec > div{padding:14px 0 0;}
  .mod-facts.mod-spec dt{font-size:22px;}
}

/* Footage in the hero's right column. Wider than the 380px the at-a-glance card sat in: 16:9 of 380
   is 214px tall, and a screen capture of the viewer at that scale shows a grey model and labels too
   small to read, which is worse than showing no video at all.

   Both tracks are proportional rather than the card's fixed 380. A fixed media column is the wrong
   shape here because it does not give way: pinned at the 560 this needs on a wide screen it left the
   copy on 362px at 1024, which is the gutter the base grid's breakpoint exists to avoid. At 0.78 the
   copy holds a full measure where there is room for it and the footage gives ground first as the
   window narrows, until 980 takes the whole hero to one column and the film runs full width.

   0.85 and not less: the copy's own 720 cap means the last of the width at the top of the range goes
   to the footage rather than to a longer line, and every point below that is a laptop at 1180-1280
   where the capture is already down near 480 wide. It buys ~30px of frame at 1440 and ~20 at 1180
   for about 15 of measure, which the paragraph does not miss and a 3D capture very much does. */
@media (min-width:980px){
  .mod-hero-grid-film{grid-template-columns:minmax(0,1fr) minmax(0,0.85fr);}

  /* Centred, where the rest of the grid starts its columns at the top. The two sides of this hero
     are the one pairing on the site that moves in opposite directions as the window narrows: the
     copy grows taller as it wraps at exactly the widths the media column is losing height to its own
     16:9. At 1180 that is 518 against 434, and pinned to the top the whole 84px lands under the
     footage as a hole in the corner of the section. Centred, the difference splits either side of
     the frame and reads as margin -- and it brings the top of the video down to about the top of the
     h1, which is the line the eye takes as the start of the page anyway. */
  .mod-hero-grid-film{align-items:center;}
}

/* The rail's own clip is 880px, wider than this column will ever be, so it is sized off the track
   here instead. Exactly 100%, so one clip fills the track and the next one starts a full width plus
   the gap along -- outside the box the track clips at, which is what keeps the neighbours off screen
   entirely. At anything less they show as a dark vertical band down each edge of the frame: too
   narrow to read as a video, close enough to the rounded corners of the real one to read as a
   rendering fault. The arrows and the counter under the frame are the whole affordance here.
   .media-film needs no such override -- its 980px cap simply never binds in a 560px column. */
.mod-hero-film .media-rail{--rail-clip:100%;}
.mod-hero-film .media-rail-foot{margin-top:14px;}

/* The section lead, demoted to a caption now that it sits under the frame rather than above it.
   Further from the controls than they are from the video: at an even 18 on both sides the arrows and
   the count read as the top line of the caption rather than as the frame's own controls, which is
   the wrong pair to group given one steps the video and the other describes it. */
.mod-hero-cap{margin-top:28px;}
.mod-hero-cap-head{
  display:block;font-family:var(--serif);font-size:19px;font-weight:500;
  color:var(--navy);line-height:1.25;letter-spacing:-0.01em;
}
.mod-hero-cap p{margin-top:7px;font-size:13.5px;line-height:1.62;color:var(--text-muted);}

/* Section heads on this page carry an eyebrow, a heading and sometimes one line -- they do not
   need the 56px the marketing pages give a head that introduces a whole argument. */
.sec-head-tight{margin-bottom:clamp(24px,2.6vw,34px);}
.sec-head-tight p{margin-top:12px;}

/* Two columns, hairline-separated, filling the shell. A single column of eight items ran ~700px
   tall against an empty right half; in two it is scannable and the section is half the height.

   Two exactly, not auto-fit: the shell is wide enough to seat three 340px tracks, and at three the
   items are narrower than the sentences in them -- every third feature wrapped to three lines and
   the last row left a third of itself empty. */
.feat-grid{
  display:grid;column-gap:clamp(28px,3.4vw,60px);
  grid-template-columns:minmax(0,1fr);
  list-style:none;
}
@media (min-width:820px){
  .feat-grid{grid-template-columns:repeat(2,minmax(0,1fr));}
}
.feat{
  display:flex;align-items:flex-start;gap:14px;
  padding:14px 0;border-top:1px solid var(--line-soft);
  font-size:15px;line-height:1.6;color:var(--text-strong);text-wrap:pretty;
}
/* A tick in the module's tone on a wash of the same colour. Built from currentColor and opacity
   rather than a mixed fill, so the eight brand tones need no second hand-picked value each. */
.feat-mark{
  position:relative;flex:none;
  width:22px;height:22px;border-radius:7px;margin-top:1px;
  display:flex;align-items:center;justify-content:center;
  color:var(--mod,var(--blue));
}
.feat-mark::before{
  content:'';position:absolute;inset:0;border-radius:inherit;
  background:currentColor;opacity:.14;
}
.feat-mark::after{
  content:'\2713';position:relative;
  font-size:11px;font-weight:800;line-height:1;
}

/* The audience row closes the same section the feature grid opens. The rule reads as the closing
   line of the feature list -- every feature carries one on top, so the list would otherwise end
   on an open edge. */
.feat-grid + .aud-row{
  margin-top:clamp(26px,3vw,40px);padding-top:clamp(24px,3vw,36px);
  border-top:1px solid var(--line-soft);
}

/* Catalyst's three enterprise verticals. */
.vert{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:clamp(24px,2.6vw,30px) clamp(22px,2.4vw,28px);
  display:flex;flex-direction:column;
}
.vert h3{font-size:22px;line-height:1.2;margin-bottom:7px;}
.vert-tag{
  font-size:10.5px;font-weight:800;letter-spacing:.13em;text-transform:uppercase;
  color:var(--text-faint);line-height:1.4;
}
.vert .chip-list{margin-top:20px;}

/* --------------------------------------------------------------------------
   Explore catalog
   -------------------------------------------------------------------------- */
.explore-hero{padding:clamp(40px,5vw,72px) 0 clamp(24px,3vw,40px);}
.explore-hero .lede{margin-bottom:30px;}
.search-wrap{max-width:720px;}

/* One pill containing icon, field, clear and submit. The border and focus ring live on
   the container rather than the input, so focusing the field lights the whole control
   and the button reads as part of it instead of sitting alongside it. */
.search{
  position:relative;display:flex;align-items:center;gap:10px;
  height:60px;padding:0 8px 0 20px;
  border-radius:var(--pill);border:1.5px solid var(--line-strong);background:#fff;
  box-shadow:0 12px 32px -22px rgba(14,22,56,0.6);
  transition:border-color .18s ease, box-shadow .18s ease;
}

.search:focus-within{
  border-color:var(--blue);
  box-shadow:0 12px 32px -18px rgba(10,111,208,0.65);
}

/* An SVG, not the ⌕ glyph: the glyph rendered at a different weight and baseline in every
   font and sat visibly off-centre. */
.search-icon{flex:none;width:19px;height:19px;color:var(--text-faint);}
.search:focus-within .search-icon{color:var(--blue);}

.search input{
  flex:1;min-width:0;height:100%;
  border:0;background:none;outline:none;padding:0;
  font-family:var(--sans);font-size:16px;font-weight:600;color:var(--navy);
}

.search input::placeholder{color:var(--text-faint);font-weight:500;}

/* The platform's own clear button would sit on top of ours. */
.search input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none;}

/* display:flex outranks the UA sheet's [hidden], so the attribute needs saying again here. */
.search-clear[hidden]{display:none;}
.search-clear{
  flex:none;display:flex;align-items:center;justify-content:center;
  width:30px;height:30px;border-radius:var(--pill);
  color:var(--text-faint);transition:background .16s ease,color .16s ease;
}
.search-clear svg{width:15px;height:15px;}
.search-clear:hover{background:var(--bg-mono);color:var(--navy);}

.search-go{
  flex:none;height:44px;padding:0 22px;border:0;border-radius:var(--pill);
  background:var(--blue);color:#fff;cursor:pointer;
  font-family:var(--sans);font-size:14px;font-weight:800;
  box-shadow:var(--sh-primary);
  transition:background .16s ease,transform .16s ease;
}
.search-go:hover{background:var(--blue-deep);}
.search-go:active{transform:translateY(1px);}

/* Hint for the "/" shortcut. Hidden once the field has focus -- at that point it is telling
   you how to do the thing you have already done -- and on touch, where there is no key. */
.search-kbd{
  position:absolute;right:118px;
  font-family:var(--mono);font-size:11.5px;font-weight:700;color:var(--text-faint);
  background:var(--bg-mono);border:1px solid var(--line);
  border-radius:6px;padding:2px 7px;
  transition:opacity .16s ease;
}
.search:focus-within .search-kbd{opacity:0;}

/* The hint is absolutely positioned at a fixed offset that assumes nothing sits between the field and
   the Search button. Once there is text the clear button does sit there, and the two overlapped -- the
   "/" chip covered the clear target and swallowed the click. Hidden while the clear button is showing,
   which is also when the hint has nothing useful to say. */
.search-clear:not([hidden]) ~ .search-kbd{display:none;}

@media (hover:none){
  .search-kbd{display:none;}
}

@media (max-width:560px){
  /* The label would leave no room for the field itself at this width. */
  .search{padding-right:6px;}
  .search-go{padding:0 14px;font-size:0;width:44px;position:relative;}
  .search-go::after{
    content:'';position:absolute;inset:0;
    background:no-repeat center/17px url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' \
stroke-width='2.4' stroke-linecap='round'><circle cx='10.5' cy='10.5' r='6.5'/>\
<path d='M15.4 15.4L21 21'/></svg>");
  }
  .search-kbd{display:none;}
}
.explore-stats{margin-top:34px;}

.explore-body{
  display:flex;flex-wrap:wrap;gap:clamp(20px,2.4vw,36px);align-items:flex-start;
  padding:clamp(16px,2vw,28px) 0 clamp(48px,6vw,88px);
}
.facets{
  flex:0 0 288px;min-width:264px;
  position:sticky;top:calc(var(--header-h) + 20px);align-self:flex-start;
  display:flex;flex-direction:column;gap:18px;
}
.facet-card{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:22px 20px;display:flex;flex-direction:column;gap:24px;
  box-shadow:var(--sh-card);
}
.facet-head{display:flex;align-items:center;justify-content:space-between;gap:10px;}
.facet-head h2{
  font-family:var(--sans);font-size:11.5px;font-weight:800;
  letter-spacing:.16em;text-transform:uppercase;color:var(--navy);
}
.facet-head a{font-size:12.5px;font-weight:700;padding:4px 6px;border-radius:8px;}
.facet-head a:hover{background:var(--bg-tint);}
.facet-group{display:flex;flex-direction:column;gap:4px;}
.facet-group + .facet-group{border-top:1px solid var(--line-soft);padding-top:20px;}
.facet-title{
  font-size:12px;font-weight:800;color:var(--navy);margin-bottom:8px;
  display:flex;align-items:baseline;gap:8px;
}
.facet-title code{font-family:var(--mono);font-size:10.5px;font-weight:600;color:var(--text-faint);}
.facet{
  display:flex;align-items:center;gap:11px;width:100%;
  padding:8px;border-radius:10px;text-align:left;
  transition:background .16s ease;color:inherit;
}
.facet:hover{background:var(--bg-soft);color:inherit;}
.facet .box{
  width:18px;height:18px;border-radius:5px;flex:none;
  display:flex;align-items:center;justify-content:center;
  font-size:11px;font-weight:800;color:#fff;
  background:#fff;border:1.5px solid var(--line-strong);
}
.facet.is-on .box{background:var(--blue);border-color:var(--blue);}
.facet .label{flex:1;font-size:13.5px;font-weight:600;color:var(--text-strong);}
.facet .count{
  font-size:11.5px;font-weight:700;color:var(--text-faint);
  background:var(--bg-mono);border-radius:var(--pill);padding:2px 8px;
}
.facet-foot{
  background:var(--bg-soft);border:1px solid var(--line);border-radius:var(--r-md);
  padding:16px 18px;font-size:12.5px;color:var(--text-muted);
  line-height:1.6;text-wrap:pretty;
}
.facet-foot b{color:var(--navy);font-weight:700;}

.results{flex:1 1 560px;min-width:0;display:flex;flex-direction:column;gap:20px;}
.results-top{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;}
.result-line{font-size:14px;color:var(--text-muted);font-weight:600;}
.sort{
  display:inline-flex;background:#fff;border:1px solid var(--line-strong);
  border-radius:var(--pill);padding:4px;gap:3px;
}
.sort a{
  display:inline-flex;align-items:center;height:34px;padding:0 16px;
  border-radius:var(--pill);font-size:12.5px;font-weight:700;
  color:var(--text-muted);transition:background .2s ease,color .2s ease;
}
.sort a[aria-current="true"]{background:var(--navy);color:#fff;}

.chips{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.chip{
  display:inline-flex;align-items:center;gap:8px;height:34px;
  padding:0 8px 0 14px;border-radius:var(--pill);
  border:1px solid var(--line-focus);background:var(--bg-tint);
  color:var(--blue-deep);font-size:12.5px;font-weight:700;
}
.chip:hover{background:#DCEBFC;color:var(--blue-deep);}
.chip .x{
  width:18px;height:18px;border-radius:50%;background:#fff;
  display:flex;align-items:center;justify-content:center;font-size:12px;line-height:1;
}

.gate{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  background:var(--navy);border-radius:var(--r-lg);padding:18px 22px;
}
.gate .ico{
  width:34px;height:34px;border-radius:10px;
  background:rgba(0,174,255,0.22);color:var(--cyan-light);
  display:flex;align-items:center;justify-content:center;font-size:15px;flex:none;
}
.gate p{flex:1;min-width:220px;color:rgba(255,255,255,0.78);font-size:13.5px;text-wrap:pretty;}
.gate p b{color:#fff;font-weight:700;}

/* In flight. The previous results stay on screen and are only replaced when the new ones arrive, so
   nothing collapses and the page cannot shift under a cursor mid-click -- this only says "these are
   about to change". Opacity, not a spinner over an emptied list: the old cards are still the honest
   answer until the new ones land.

   .is-loading was already being set by the script with no rule behind it, so filtering and typing had
   no visible acknowledgement at all. */
.results.is-loading,
.facets.is-loading{opacity:.5;transition:opacity .1s ease;}

/* The click already happened; blocking further ones stops a double-click firing two requests and
   stops a second facet being ticked while the first is still resolving. */
.results.is-loading .catalog,
.results.is-loading .sort,
.facets.is-loading .facet-card{pointer-events:none;}

/* Immediate acknowledgement on the control that was activated, since it survives on screen until the
   swap lands. Without it a click reads as dead for the length of the round trip and gets repeated. */
.facet.is-pending,
.chip.is-pending,
.sort a.is-pending{opacity:1;}
.facet.is-pending .label{text-decoration:underline;text-underline-offset:2px;}

@media (prefers-reduced-motion:reduce){
  .results.is-loading,
  .facets.is-loading{transition:none;}
}

.catalog{display:grid;grid-template-columns:repeat(auto-fill,minmax(288px,1fr));gap:20px;}
.cfg{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  overflow:hidden;display:flex;flex-direction:column;
  transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease;
}
.cfg:hover{transform:translateY(-5px);box-shadow:var(--sh-card-hover);border-color:var(--line-focus);}
.cfg-media{
  position:relative;aspect-ratio:16/10;background:#EEF4FD;
  border-bottom:1px solid var(--line);
  display:flex;align-items:center;justify-content:center;
  color:var(--text-faint);font-size:12px;font-weight:800;
  letter-spacing:.1em;text-transform:uppercase;text-align:center;padding:0 16px;
}
.cfg-media img{width:100%;height:100%;object-fit:cover;}
.cfg-body{padding:20px 20px 22px;display:flex;flex-direction:column;gap:11px;flex:1;}
.cfg-tags{display:flex;align-items:center;gap:7px;flex-wrap:wrap;}
.tag-region,.tag-system{
  font-size:10.5px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  border-radius:var(--pill);padding:4px 10px;
}
.tag-region{color:var(--blue-deep);background:var(--bg-tint);}
.tag-system{color:#fff;}
.cfg-tags mark{
  background:none;color:inherit;padding:0;
  text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:2px;
}
.cfg h3{font-size:20px;line-height:1.2;}
.cfg-desc{font-size:13.5px;color:var(--text-muted);line-height:1.6;text-wrap:pretty;flex:1;}
.cfg-meta{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  padding-top:12px;border-top:1px solid var(--line-soft);
  font-size:12px;color:var(--text-muted);
}
.cfg-meta b{color:var(--navy);font-weight:800;}
.cfg .btn-block{margin-top:4px;height:46px;font-size:13.5px;}

.empty{
  background:#fff;border:1.5px dashed var(--line-dashed);border-radius:var(--r-card);
  padding:clamp(40px,6vw,72px) 28px;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:14px;
}
.empty .ico{
  width:56px;height:56px;border-radius:50%;background:var(--bg-hover);
  color:var(--blue);display:flex;align-items:center;justify-content:center;font-size:22px;
}
.empty h3{font-size:24px;}
.empty p{font-size:14.5px;color:var(--text-muted);max-width:420px;text-wrap:pretty;}

@media (max-width:900px){
  .facets{position:static;flex:1 1 100%;}
}

/* --------------------------------------------------------------------------
   Auth (sign in / sign up)
   -------------------------------------------------------------------------- */
.auth{display:flex;flex-wrap:wrap;min-height:calc(100vh - var(--header-h));}
.auth-form-side{
  flex:1 1 520px;display:flex;align-items:center;justify-content:center;
  padding:clamp(40px,6vw,80px) clamp(20px,4vw,56px);
  background:radial-gradient(ellipse 90% 70% at 30% 0%,var(--bg-tint-2) 0%,var(--bg) 60%);
}
.auth-form{width:100%;max-width:432px;display:flex;flex-direction:column;gap:26px;}
.auth-form h1{font-size:clamp(30px,3.6vw,40px);line-height:1.1;letter-spacing:-0.02em;margin-bottom:12px;}
.auth-sso-note{font-size:12.5px;color:var(--text-faint);text-align:center;margin-top:-14px;}
.auth-alt{font-size:14px;color:var(--text-muted);text-align:center;}
.auth-alt a{font-size:14px;font-weight:700;}
/* Right-aligned under the password field, inside .fields -- the negative margin pulls it up against
   that field so it reads as attached to it rather than as a third form row. */
.auth-forgot{font-size:13px;text-align:right;margin-top:-18px;}
.auth-forgot a{font-size:13px;font-weight:600;color:var(--text-muted);}
.auth-forgot a:hover{color:var(--text);}
.auth-aside{
  flex:1 1 420px;position:relative;overflow:hidden;background:var(--navy-deep);
  display:flex;align-items:center;padding:clamp(40px,6vw,80px) clamp(24px,4vw,56px);
}
.auth-aside::before{
  content:'';position:absolute;top:-20%;right:-14%;
  width:560px;height:560px;border-radius:50%;
  background:radial-gradient(circle,rgba(0,174,255,0.24),transparent 70%);
}
.auth-aside-inner{
  position:relative;z-index:2;max-width:460px;
  display:flex;flex-direction:column;gap:26px;
}
.auth-aside img{align-self:flex-start;flex:none;height:auto;width:clamp(148px,17vw,206px);}
.auth-aside h2{color:#fff;font-size:clamp(24px,2.6vw,32px);line-height:1.16;}
/* Same reason as .why-hero-copy h1 em: the headline is a statement and an italic second clause
   commenting on it, so the clause gets its own line rather than trailing the first one mid-wrap.
   Not a copy of .h1-hero em, which also relies on the hero's 1120px measure to keep each clause
   on one line -- this column is ~460px, so the clause wraps internally and that is fine. */
.auth-aside h2 em{display:block;}
.auth-aside p{color:rgba(255,255,255,0.7);font-size:15px;line-height:1.7;text-wrap:pretty;}
.auth-points{display:flex;flex-direction:column;gap:14px;}
.auth-points li{
  display:flex;align-items:flex-start;gap:12px;
  color:rgba(255,255,255,0.82);font-size:14px;line-height:1.6;
}
.auth-points li::before{
  content:'\2713';flex:none;width:20px;height:20px;border-radius:6px;
  background:rgba(0,174,255,0.22);color:var(--cyan-light);
  display:flex;align-items:center;justify-content:center;
  font-size:11px;font-weight:800;margin-top:2px;
}

.fields{display:flex;flex-direction:column;gap:16px;}
.field{display:flex;flex-direction:column;gap:8px;}
.field > label,.field > span{font-size:12.5px;font-weight:700;color:var(--navy);}
.field input,.field select,.field textarea{
  border-radius:var(--r-sm);border:1.5px solid var(--line-strong);
  background:#fff;padding:0 16px;height:52px;
  font-family:var(--sans);font-size:15px;font-weight:600;color:var(--navy);outline:none;
  transition:border-color .2s ease;
}
.field textarea{height:auto;min-height:140px;padding:14px 16px;line-height:1.6;resize:vertical;}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--blue);}
.field .hint{font-size:12px;color:var(--text-faint);font-weight:400;}
.field .err{font-size:12.5px;color:var(--bad-ink);font-weight:600;}
.field input.input-invalid,.field textarea.input-invalid{border-color:var(--bad);}

/* Show/hide password. The wrapper and button are inserted by initPasswordToggles()
   in site.js; the input keeps its .field styling and the extra right padding stops
   typed characters running under the eye. */
.field .pw-box{position:relative;display:block;}
.field .pw-box input{width:100%;padding-right:52px;}
.pw-toggle{
  position:absolute;top:50%;right:8px;transform:translateY(-50%);
  display:flex;align-items:center;justify-content:center;
  width:36px;height:36px;border:0;border-radius:var(--r-sm);
  background:none;cursor:pointer;
  color:var(--text-faint);transition:color .16s ease;
}
.pw-toggle:hover,.pw-toggle:focus-visible{color:var(--navy);}

/* Opt-in invitation code on /signup. A custom checkbox (the native box is visually replaced) set
   apart from the required fields by a hairline rule. Ticking it reveals the code field, CSS-only:
   the ':checked ~ .invite-field' rule needs the checkbox, its label and the field to be siblings. */
.invite{border-top:1px solid var(--line);padding-top:18px;}
.invite-check{position:absolute;width:1px;height:1px;opacity:0;margin:0;}
.invite-label{
  display:inline-flex;align-items:center;gap:10px;cursor:pointer;user-select:none;
  font-size:13.5px;font-weight:700;color:var(--navy);padding:2px 0;
}
.invite-label::before{
  content:'';flex:none;width:20px;height:20px;border-radius:6px;
  border:1.5px solid var(--line-strong);background:#fff;transition:border-color .2s ease,background .2s ease;
}
.invite-check:hover + .invite-label::before{border-color:var(--blue);}
.invite-check:checked + .invite-label::before{
  border-color:var(--blue);background:var(--blue)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E")
    center/13px no-repeat;
}
.invite-check:focus-visible + .invite-label::before{outline:2px solid var(--blue);outline-offset:3px;}
.invite-field{display:none;margin-top:14px;}
.invite-check:checked ~ .invite-field{display:flex;animation:invite-reveal .2s ease;}
@keyframes invite-reveal{from{opacity:0;transform:translateY(-4px);}to{opacity:1;transform:none;}}

.btn-sso{
  width:100%;height:56px;border-radius:var(--pill);border:none;cursor:pointer;
  background:var(--navy);color:#fff;font-size:15px;font-weight:700;
  display:flex;align-items:center;justify-content:center;gap:12px;
  box-shadow:0 16px 36px -18px rgba(14,22,56,0.75);
  transition:transform .2s ease;
}
.btn-sso:hover{color:#fff;transform:translateY(-2px);}
.btn-sso img{width:22px;height:auto;}
/* Also used on <a> (the reset-password confirmation and dead-link pages), so the label is centred
   with flex rather than relying on a button's native centring. */
.btn-auth{
  width:100%;height:54px;border-radius:var(--pill);border:none;cursor:pointer;
  background:linear-gradient(135deg,var(--blue-bright),var(--blue-deep));
  color:#fff;font-size:15px;font-weight:700;text-align:center;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 16px 36px -18px rgba(10,155,240,0.85);
  transition:transform .2s ease;
}
.btn-auth:hover{color:#fff;transform:translateY(-2px);}

.or{
  display:flex;align-items:center;gap:14px;color:var(--text-faint);
  font-size:11.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
}
.or::before,.or::after{content:'';flex:1;height:1px;background:var(--line);}

.callout{
  display:flex;align-items:flex-start;gap:12px;
  background:var(--bg-tint);border:1px solid var(--line-focus);
  border-radius:var(--r-md);padding:16px 18px;
}
.callout .ico{
  flex:none;width:30px;height:30px;border-radius:9px;background:#fff;
  color:var(--blue);display:flex;align-items:center;justify-content:center;font-size:14px;
}
.callout p{
  font-size:13.5px;color:var(--navy);line-height:1.55;text-wrap:pretty;
  padding-top:calc((30px - 1.55em) / 2);
}
.callout.is-error{background:#FDF2F2;border-color:#F3CFCF;}
.callout.is-error .ico{color:var(--bad);}
.callout.is-warning{background:var(--warn-bg);border-color:var(--warn-line);}
.callout.is-warning .ico{color:var(--warn);}
.callout.is-success{background:var(--good-bg);border-color:#C9E9E3;}
.callout.is-success .ico{color:var(--good);}
.callout ul{display:flex;flex-direction:column;gap:4px;}
.callout li{font-size:13.5px;color:var(--navy);}

/* Sign-up */
.signup{
  padding:clamp(40px,5vw,72px) 0 clamp(48px,6vw,88px);
  background:radial-gradient(ellipse 80% 60% at 50% 0%,var(--bg-tint-2) 0%,var(--bg) 58%);
  min-height:calc(100vh - var(--header-h));
}
.signup-head{text-align:center;max-width:620px;margin:0 auto clamp(28px,3.4vw,44px);}
.signup-head h1{font-size:clamp(30px,3.8vw,44px);line-height:1.08;letter-spacing:-0.02em;margin-bottom:14px;}
.signup-steps{
  display:flex;align-items:center;justify-content:center;gap:12px;
  margin-bottom:clamp(28px,3vw,40px);flex-wrap:wrap;
}
.signup-steps li{
  display:flex;align-items:center;gap:10px;
  padding:8px 18px 8px 8px;border-radius:var(--pill);
  border:1.5px solid var(--line-strong);background:#fff;
}
.signup-steps li .n{
  width:26px;height:26px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-size:12px;font-weight:800;background:var(--line);color:var(--text-faint);
}
.signup-steps li .t{font-size:13px;font-weight:700;color:var(--text-faint);}
.signup-steps li.is-active{border-color:var(--blue-mid);background:var(--bg-tint);}
.signup-steps li.is-active .n{background:var(--blue);color:#fff;}
.signup-steps li.is-active .t{color:var(--blue-deep);}

.signup-card{
  max-width:460px;margin:0 auto;background:#fff;
  border:1px solid var(--line);border-radius:var(--r-panel);
  padding:clamp(26px,3vw,36px);
  box-shadow:0 30px 70px -44px rgba(14,22,56,0.55);
  display:flex;flex-direction:column;gap:22px;
}
.plan-pick{
  position:relative;
  text-align:left;background:#fff;border:1.5px solid var(--line);
  border-radius:var(--r-card);padding:24px 20px;
  display:flex;flex-direction:column;gap:8px;color:inherit;
  box-shadow:0 10px 30px -26px rgba(14,22,56,0.45);
  transition:transform .2s ease,border-color .2s ease,box-shadow .2s ease;
}
.plan-pick:hover{transform:translateY(-3px);}
/* The radio is the source of truth; :has() keeps the selected look out of JS entirely. */
.plan-pick:has(input:checked){
  border:2px solid var(--blue-mid);
  box-shadow:0 26px 60px -34px rgba(10,131,224,0.6);
}
.plan-pick:has(input:focus-visible){outline:3px solid var(--blue);outline-offset:3px;}
/* Covers the card so a click anywhere selects, without nesting blocks inside a <label>. */
.plan-pick-hit{position:absolute;inset:0;cursor:pointer;border-radius:inherit;z-index:1;}
.plan-pick-top{display:flex;align-items:center;justify-content:space-between;gap:10px;}
.plan-pick h3{font-size:20px;}
.plan-pick .tick{
  width:20px;height:20px;border-radius:50%;flex:none;
  display:flex;align-items:center;justify-content:center;
  font-size:11px;font-weight:800;color:#fff;
  background:#fff;border:1.5px solid var(--line-strong);
}
.plan-pick:has(input:checked) .tick{background:var(--blue);border-color:var(--blue);}
.plan-pick:has(input:checked) .tick::after{content:'\2713';}
.plan-pick .plan-sub{min-height:34px;font-size:12.5px;margin-bottom:0;}
.plan-pick .plan-amt{font-size:30px;}
.plan-pick .plan-unit{font-size:12.5px;}

.summary-bar{
  display:flex;align-items:center;justify-content:space-between;
  gap:16px;flex-wrap:wrap;background:#fff;
  border:1px solid var(--line);border-radius:var(--r-card);
  padding:20px 24px;box-shadow:var(--sh-card);
}
.summary-bar .k{
  font-size:12px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-faint);margin-bottom:5px;
}
.summary-bar .v{font-size:15.5px;font-weight:700;color:var(--navy);}

/* --------------------------------------------------------------------------
   Long-form prose (privacy, news, team)
   -------------------------------------------------------------------------- */
.prose{max-width:820px;}
.prose h2{font-size:clamp(24px,2.6vw,30px);margin:40px 0 14px;}
.prose h3{font-size:20px;margin:28px 0 10px;}
.prose p,.prose li{font-size:15.5px;color:var(--text-muted);line-height:1.8;text-wrap:pretty;}
.prose p + p{margin-top:14px;}
.prose ul{margin:14px 0;display:flex;flex-direction:column;gap:8px;}
.prose ul li{padding-left:20px;position:relative;}
.prose ul li::before{
  content:'';position:absolute;left:0;top:11px;
  width:6px;height:6px;border-radius:2px;background:var(--blue);
}
.prose a{font-weight:600;}
.prose > *:first-child{margin-top:0;}
.prose blockquote{
  margin:22px 0;padding:22px 26px;
  background:var(--bg-soft);border-left:3px solid var(--blue);
  border-radius:0 var(--r-md) var(--r-md) 0;
}
.prose blockquote p{font-size:16.5px;color:var(--navy);font-style:italic;}
.prose blockquote cite{
  display:block;margin-top:12px;font-style:normal;
  font-size:12px;font-weight:800;letter-spacing:.12em;
  text-transform:uppercase;color:var(--blue);
}
.prose figure{margin:26px 0;}
.prose figure img{width:100%;border-radius:var(--r-card);border:1px solid var(--line);}
.prose figcaption{margin-top:10px;font-size:13px;color:var(--text-faint);}
.prose strong{color:var(--navy);font-weight:700;}
.prose hr{border:none;border-top:1px solid var(--line);margin:36px 0;}
.prose ol{margin:14px 0;padding-left:22px;list-style:decimal;}
.prose ol li{padding-left:4px;}
.prose ol li::before{content:none;}
/* Legal tables can be wide; scroll the table, never the page. */
.prose table{
  display:block;overflow-x:auto;width:100%;
  border-collapse:collapse;margin:20px 0;
  border:1px solid var(--line);border-radius:var(--r-md);
}
.prose th,.prose td{
  text-align:left;padding:12px 14px;font-size:13.5px;
  border-bottom:1px solid var(--line-soft);vertical-align:top;
}
.prose th{
  background:var(--bg-soft);color:var(--navy);font-weight:700;
  font-size:12.5px;letter-spacing:.04em;
}
.prose td{color:var(--text-muted);}
.prose tbody tr:last-child td{border-bottom:none;}

/* Article / press-release meta line */
.meta-row{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:16px;
  font-size:12.5px;color:var(--text-faint);
}
.type-pill{
  font-size:10.5px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  color:var(--blue-deep);background:var(--bg-tint);
  border-radius:var(--pill);padding:5px 12px;
}

/* Long-form bio block (Team) */
.bio{
  display:grid;grid-template-columns:minmax(240px,300px) 1fr;
  gap:clamp(28px,4vw,56px);align-items:start;
}

/* The bio blocks are .bio.prose, and .prose caps width at 820px -- right for ONE readable column of
   body text, wrong here: on a two-column grid that cap applies to the whole row, so the 300px photo
   plus the 56px gap left the copy about 460px wide with a wide empty band beside it.
   Two classes, so this beats .prose whatever the source order.

   The row is uncapped and fills the .wrap. The limit moves onto the text column, which is the thing
   that actually needs one -- an uncapped row on a very wide monitor would run to 200-character
   lines. 104ch is deliberately generous (the usual advice is 75); lower it if the lines read long. */
.bio.prose{max-width:none;}
.bio.prose > :not(.bio-photo){max-width:104ch;}
.bio-photo{
  border-radius:var(--r-card);overflow:hidden;
  border:1px solid var(--line);box-shadow:var(--sh-card);
}
.bio-photo img{width:100%;aspect-ratio:1/1;object-fit:cover;}
.bio h2{font-size:clamp(26px,3vw,34px);margin:8px 0 14px;}
.bio .role{
  font-size:10.5px;font-weight:800;letter-spacing:.13em;
  text-transform:uppercase;color:var(--blue);
}
.bio-creds{
  margin-top:24px;padding-top:20px;border-top:1px solid var(--line);
  display:flex;flex-direction:column;gap:12px;
}
.bio-creds li{
  font-size:13.5px;color:var(--text-muted);
  padding-left:20px;position:relative;line-height:1.6;
}
.bio-creds li::before{
  content:'';position:absolute;left:0;top:9px;
  width:7px;height:7px;border-radius:2px;background:var(--blue);
}
@media (max-width:760px){
  .bio{grid-template-columns:1fr;}
  .bio-photo{max-width:300px;}
}

/* People / article cards */
.person{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  overflow:hidden;display:flex;flex-direction:column;
}
.person img{width:100%;aspect-ratio:1/1;object-fit:cover;}
.person-body{padding:22px 22px 26px;display:flex;flex-direction:column;gap:6px;}
.person h3{font-size:20px;}
.person .role{
  font-size:10.5px;font-weight:800;letter-spacing:.13em;
  text-transform:uppercase;color:var(--blue);
}
.person p{font-size:13.5px;color:var(--text-muted);line-height:1.6;margin-top:6px;text-wrap:pretty;}

.article{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-card);
  padding:28px 26px;display:flex;flex-direction:column;gap:10px;
}
.article .date{
  font-size:11px;font-weight:800;letter-spacing:.12em;
  text-transform:uppercase;color:var(--text-faint);
}
.article h3{font-size:22px;line-height:1.25;}
.article p{font-size:14px;color:var(--text-muted);text-wrap:pretty;}

/* --------------------------------------------------------------------------
   Footer

   Styled once, further down under "Site footer" -- this file used to carry two
   competing definitions of the same four classes, and the later one won on every
   property it repeated. What it did NOT repeat (.footer-brand{grid-column:span 2})
   still applied, which is what pushed Ecosystem onto a row of its own.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Motion
   -------------------------------------------------------------------------- */
@keyframes sm-fade{from{opacity:0;transform:translateY(10px);}to{opacity:1;transform:none;}}

/* Reveal-on-scroll. Gated on html.js so a JS failure never hides content. */
html.js [data-reveal]{
  opacity:0;transform:translateY(22px);
  transition:opacity .63s cubic-bezier(.22,.61,.36,1),transform .63s cubic-bezier(.22,.61,.36,1);
}
html.js [data-reveal].is-revealed{opacity:1;transform:none;}
html.js [data-reveal][data-delay="1"]{transition-delay:72ms;}
html.js [data-reveal][data-delay="2"]{transition-delay:144ms;}
html.js [data-reveal][data-delay="3"]{transition-delay:216ms;}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  html.js [data-reveal]{opacity:1;transform:none;transition:none;}
  .btn:hover,.mod-card:hover,.card-lift:hover,.cfg:hover,.plan-pick:hover,.btn-sso:hover,.btn-auth:hover{
    transform:none;
  }
}

/* --------------------------------------------------------------------------
   Site footer

   _RedesignLayout has always emitted footer.site with .footer-grid/.footer-col/
   .footer-bottom, but this stylesheet defined none of them -- only the print rule
   at the top referenced footer.site. The result was an unstyled block: white
   background (so the white lockup was invisible), footer <h2>s rendering at the
   full marketing h2 clamp, and every link run together inline. Styled here, in
   the shared stylesheet, because the footer belongs to the layout rather than to
   any one page.
   -------------------------------------------------------------------------- */
footer.site{
  background:var(--navy-deep);
  color:rgba(255,255,255,0.72);
  padding:clamp(48px,6vw,76px) 0 28px;
  margin-top:auto;
}

/* Explicit tiers rather than auto-fit. auto-fit resolved to five tracks in a
   container that could only seat four of them at the brand's real width, so
   Ecosystem wrapped to a second row and sat alone under the description. Each
   tier below states its own track count, so the four link columns either share
   one row or stack in even pairs -- never four-plus-one. */
footer.site .footer-grid{
  display:grid;
  grid-template-columns:1.5fr repeat(4,minmax(0,1fr));
  gap:clamp(28px,3vw,44px) clamp(24px,2.6vw,40px);
  padding-bottom:clamp(36px,4vw,52px);
}

/* Brand takes the full width and the four link columns share the row below it. */
@media (max-width:1180px){
  footer.site .footer-grid{grid-template-columns:repeat(4,minmax(0,1fr));}
  footer.site .footer-brand{grid-column:1 / -1;}
}

/* 860, the same width the comparison table swaps to cards at. Four columns in a 768px
   tablet leaves each one ~160px, which is narrower than "Hospitals & Institutions". */
@media (max-width:860px){
  footer.site .footer-grid{grid-template-columns:repeat(2,minmax(0,1fr));}
}

@media (max-width:460px){
  footer.site .footer-grid{grid-template-columns:minmax(0,1fr);}
}

/* 34ch, not a px max-width: the measure should track the font size, and this keeps
   the description at a readable ~60 characters per line at every tier. */
footer.site .footer-brand{max-width:34ch;}

/* Sized by WIDTH off the 3.71:1 white lockup. The previous height:44px was applied
   to an 825x825 square canvas, so the lockup rendered 44px wide -- a thumbnail with
   an illegible wordmark. Width-driven also means the mark scales with the type
   rather than against it. */
footer.site .footer-brand img{
  width:clamp(148px,14vw,184px);height:auto;
  margin-bottom:20px;
}

footer.site .footer-brand p{
  font-size:14.5px;line-height:1.7;font-weight:400;
  color:rgba(255,255,255,0.66);text-wrap:pretty;
}

/* Not the marketing h2 clamp: these are column labels, not section headings.
   12px/.12em rather than 11.5px/.16em -- at this size the wider tracking was doing
   the work of a larger font badly, spacing five-letter words out past their links. */
footer.site .footer-col h2{
  font-family:var(--sans);
  font-size:12px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--cyan-light);
  margin:0 0 18px;line-height:1.3;
}

footer.site .footer-col > div{display:flex;flex-direction:column;gap:12px;align-items:flex-start;}

footer.site .footer-col a,
footer.site .footer-col > div span{
  font-size:14.5px;font-weight:400;line-height:1.35;
  color:rgba(255,255,255,0.72);
  transition:color .16s ease;
}

footer.site .footer-col a:hover{color:#fff;}

footer.site .footer-bottom{
  display:flex;align-items:center;justify-content:space-between;
  flex-wrap:wrap;gap:8px 24px;
  padding-top:26px;
  border-top:1px solid rgba(255,255,255,0.12);
  font-size:13px;line-height:1.6;color:rgba(255,255,255,0.5);
}

/* --------------------------------------------------------------------------
   Fragment targets

   header.site is sticky at --header-h, so a #fragment jump would otherwise put the
   top of the target underneath it. Applied per element rather than to [id] globally,
   so only things actually linked to pay the offset.
   -------------------------------------------------------------------------- */
.anchor-target{scroll-margin-top:calc(var(--header-h) + 20px);}

/* --------------------------------------------------------------------------
   Auth brand bar (_AuthLayout)

   /signin and /signup drop the nav and footer, so this replaces header.site.
   Height matches --header-h on purpose: .auth is calc(100vh - var(--header-h)),
   so the split panel keeps filling exactly the viewport below it.

   Not sticky, unlike header.site: there is nothing to scroll past.
   -------------------------------------------------------------------------- */
header.auth-bar{
  display:flex;align-items:center;
  height:var(--header-h);
  padding:0 var(--gutter);
  background:#fff;
  border-bottom:1px solid var(--line);
}

/* ==========================================================================
   Explore refinements
   ========================================================================== */

/* The media panel is a dark 3D preview now, so the pale placeholder fill showed
   as a flash before the image decoded. Match the artwork instead. */
.cfg-media{background:#0B1424;}

/* A slow scale on hover: the card is a doorway into a 3D model, and the preview
   moving slightly is the cheapest way to say so. overflow:hidden on .cfg crops it. */
.cfg-media img{transition:transform .5s cubic-bezier(.2,.7,.3,1);}
.cfg:hover .cfg-media img{transform:scale(1.045);}

@media (prefers-reduced-motion: reduce){
  .cfg-media img{transition:none;}
  .cfg:hover .cfg-media img{transform:none;}
}

/* The launch button was a full-bleed gradient on every card, so twenty cards read
   as twenty competing primary actions and the titles lost. Quieter by default,
   full colour on hover or keyboard focus -- the card is the thing being scanned,
   the button is what you press once you have chosen. */
.cfg .btn-primary{
  background:#fff;color:var(--blue-deep);
  border:1.5px solid var(--line-strong);box-shadow:none;
}

.cfg:hover .btn-primary,
.cfg .btn-primary:focus-visible{
  background:var(--blue);color:#fff;border-color:transparent;
  box-shadow:var(--sh-primary);
}

/* Four stats rather than three, so they need to wrap rather than stretch. */
.explore-stats{flex-wrap:wrap;row-gap:22px;}

/* The hero search sat at 720px against a 1280px column, which left the right half
   of the hero empty and made the field look like an afterthought on a page whose
   whole purpose is searching. */
.explore-hero .search-wrap{max-width:860px;}

/* Live search: the results fade slightly while a fetch is in flight. Deliberately
   subtle and with no spinner -- responses are tens of milliseconds, and a spinner
   that flashes on every keystroke is worse than a moment of stale content. */
.results.is-loading{opacity:.55;transition:opacity .12s ease;}
.results{transition:opacity .18s ease;}

@media (prefers-reduced-motion: reduce){
  .results,.results.is-loading{transition:none;}
}
