/* Theme */

/* =============================================================
   Color System v2
   Hex-based palette. Four scales (Purple, Blue, Green, Yellow)
   each with dark / medium / regular / light stops, plus flat
   brand tokens and the Fusion gradient.
   ============================================================= */

:root {

  /* ── Grey scale ─────────────────────────────────────────── */
  --c-grey-00: #000000;
  --c-grey-01: #0D0D18;
  --c-grey-02: #161722;
  --c-grey-03: #252736;
  --c-grey-04: #36384A;
  --c-grey-05: #6A6B83;
  --c-grey-06: #A3A4BF;
  --c-grey-07: #D5D6EA;
  --c-grey-08: #E8E9F3;
  --c-grey-09: #F5F5F8;
  --c-grey-10: #FDFDFD;

  /* Page/body canvas + text — the single source of truth for the page.
     `body` background/color and the bg-glow edge fade reference these, so a
     fade dissolves into whatever the page is and text stays legible on it.
     Override both at page/template scope to flip a page light (see the
     body.bg-* rules in _typography.css). */
  --body-bg: var(--c-grey-01);
  --body-fg: var(--c-grey-09);

  /* ── Brand ─────────────────────────────────────────────── */
  --c-periwinkle:        #4864FF;
  --c-periwinkle-light:  #7A8FFF;
  --c-aqua:              #1ED4AA;
  --c-coral:             #FF815C;
  --c-black:             #000000;
  --c-white:             #FFFFFF;

  /* Fusion gradient (use --c-fusion with background-image) */
  --c-fusion-from:  #4864FF;
  --c-fusion-to:    #1ED4AA;
  --c-fusion:       linear-gradient(to right, var(--c-fusion-from), var(--c-fusion-to));

  /* ── Purple ─────────────────────────────────────────────── */
  --c-purple-dark:    #330069;
  --c-purple-medium:  #7F39C9;
  --c-purple-regular: #BE81FF;
  --c-purple-light:   #DEBFFF;

  /* ── Blue ───────────────────────────────────────────────── */
  --c-blue-dark:    #004148;
  --c-blue-medium:  #00A1B4;
  --c-blue-regular: #00E5FF;
  --c-blue-light:   #AAF5FF;

  /* ── Green ──────────────────────────────────────────────── */
  --c-green-dark:    #075000;
  --c-green-medium:  #12B902;
  --c-green-regular: #4FFF40;
  --c-green-light:   #BAFFB4;

  /* ── Yellow ─────────────────────────────────────────────── */
  --c-yellow-dark:    #524400;
  --c-yellow-medium:  #C1A000;
  --c-yellow-regular: #FFEE1E;
  --c-yellow-light:   #FFFAB9;

}


/* =============================================================
   TEXT COLOR CLASSES
   ============================================================= */

/* Grey */
.c-grey-00 { color: var(--c-grey-00); }
.c-grey-01 { color: var(--c-grey-01); }
.c-grey-02 { color: var(--c-grey-02); }
.c-grey-03 { color: var(--c-grey-03); }
.c-grey-04 { color: var(--c-grey-04); }
.c-grey-05 { color: var(--c-grey-05); }
.c-grey-06 { color: var(--c-grey-06); }
.c-grey-07 { color: var(--c-grey-07); }
.c-grey-08 { color: var(--c-grey-08); }
.c-grey-09 { color: var(--c-grey-09); }
.c-grey-10 { color: var(--c-grey-10); }

/* Brand */
.c-periwinkle       { color: var(--c-periwinkle); }
.c-periwinkle-light { color: var(--c-periwinkle-light); }
.c-aqua             { color: var(--c-aqua); }
.c-coral            { color: var(--c-coral); }
.c-black            { color: var(--c-black); }
.c-white            { color: var(--c-white); }

/* Purple */
.c-purple-dark    { color: var(--c-purple-dark); }
.c-purple-medium  { color: var(--c-purple-medium); }
.c-purple-regular { color: var(--c-purple-regular); }
.c-purple-light   { color: var(--c-purple-light); }
.c-purple         { color: var(--c-purple-regular); }

/* Blue */
.c-blue-dark    { color: var(--c-blue-dark); }
.c-blue-medium  { color: var(--c-blue-medium); }
.c-blue-regular { color: var(--c-blue-regular); }
.c-blue-light   { color: var(--c-blue-light); }
.c-blue         { color: var(--c-blue-regular); }

/* Green */
.c-green-dark    { color: var(--c-green-dark); }
.c-green-medium  { color: var(--c-green-medium); }
.c-green-regular { color: var(--c-green-regular); }
.c-green-light   { color: var(--c-green-light); }
.c-green         { color: var(--c-green-regular); }

/* Yellow */
.c-yellow-dark    { color: var(--c-yellow-dark); }
.c-yellow-medium  { color: var(--c-yellow-medium); }
.c-yellow-regular { color: var(--c-yellow-regular); }
.c-yellow-light   { color: var(--c-yellow-light); }
.c-yellow         { color: var(--c-yellow-regular); }


/* =============================================================
   BACKGROUND COLOR CLASSES
   ============================================================= */

/* Grey */
.bg-grey-00 { background-color: var(--c-grey-00); }
.bg-grey-01 { background-color: var(--c-grey-01); }
.bg-grey-02 { background-color: var(--c-grey-02); }
.bg-grey-03 { background-color: var(--c-grey-03); }
.bg-grey-04 { background-color: var(--c-grey-04); }
.bg-grey-05 { background-color: var(--c-grey-05); }
.bg-grey-06 { background-color: var(--c-grey-06); }
.bg-grey-07 { background-color: var(--c-grey-07); }
.bg-grey-08 { background-color: var(--c-grey-08); }
.bg-grey-09 { background-color: var(--c-grey-09); }
.bg-grey-10 { background-color: var(--c-grey-10); }

/* Brand */
.bg-periwinkle       { background-color: var(--c-periwinkle); }
.bg-periwinkle-light { background-color: var(--c-periwinkle-light); }
.bg-aqua             { background-color: var(--c-aqua); }
.bg-coral            { background-color: var(--c-coral); }
.bg-black            { background-color: var(--c-black); }
.bg-white            { background-color: var(--c-white); }

/* Fusion gradient */
.bg-fusion { background-image: var(--c-fusion); }

/* Purple */
.bg-purple-dark    { background-color: var(--c-purple-dark); }
.bg-purple-medium  { background-color: var(--c-purple-medium); }
.bg-purple-regular { background-color: var(--c-purple-regular); }
.bg-purple-light   { background-color: var(--c-purple-light); }
.bg-purple         { background-color: var(--c-purple-regular); }

/* Blue */
.bg-blue-dark    { background-color: var(--c-blue-dark); }
.bg-blue-medium  { background-color: var(--c-blue-medium); }
.bg-blue-regular { background-color: var(--c-blue-regular); }
.bg-blue-light   { background-color: var(--c-blue-light); }
.bg-blue         { background-color: var(--c-blue-regular); }

/* Green */
.bg-green-dark    { background-color: var(--c-green-dark); }
.bg-green-medium  { background-color: var(--c-green-medium); }
.bg-green-regular { background-color: var(--c-green-regular); }
.bg-green-light   { background-color: var(--c-green-light); }
.bg-green         { background-color: var(--c-green-regular); }

/* Yellow */
.bg-yellow-dark    { background-color: var(--c-yellow-dark); }
.bg-yellow-medium  { background-color: var(--c-yellow-medium); }
.bg-yellow-regular { background-color: var(--c-yellow-regular); }
.bg-yellow-light   { background-color: var(--c-yellow-light); }
.bg-yellow         { background-color: var(--c-yellow-regular); }


/* =============================================================
   BORDER COLOR CLASSES
   ============================================================= */

/* Grey */
.b-grey-00 { border: 1px solid var(--c-grey-00); }
.b-grey-01 { border: 1px solid var(--c-grey-01); }
.b-grey-02 { border: 1px solid var(--c-grey-02); }
.b-grey-03 { border: 1px solid var(--c-grey-03); }
.b-grey-04 { border: 1px solid var(--c-grey-04); }
.b-grey-05 { border: 1px solid var(--c-grey-05); }
.b-grey-06 { border: 1px solid var(--c-grey-06); }
.b-grey-07 { border: 1px solid var(--c-grey-07); }
.b-grey-08 { border: 1px solid var(--c-grey-08); }
.b-grey-09 { border: 1px solid var(--c-grey-09); }
.b-grey-10 { border: 1px solid var(--c-grey-10); }

/* Brand */
.b-periwinkle       { border: 1px solid var(--c-periwinkle); }
.b-periwinkle-light { border: 1px solid var(--c-periwinkle-light); }
.b-aqua             { border: 1px solid var(--c-aqua); }
.b-coral            { border: 1px solid var(--c-coral); }
.b-black            { border: 1px solid var(--c-black); }
.b-white            { border: 1px solid var(--c-white); }

/* Purple */
.b-purple-dark    { border: 1px solid var(--c-purple-dark); }
.b-purple-medium  { border: 1px solid var(--c-purple-medium); }
.b-purple-regular { border: 1px solid var(--c-purple-regular); }
.b-purple-light   { border: 1px solid var(--c-purple-light); }
.b-purple         { border: 1px solid var(--c-purple-regular); }

/* Blue */
.b-blue-dark    { border: 1px solid var(--c-blue-dark); }
.b-blue-medium  { border: 1px solid var(--c-blue-medium); }
.b-blue-regular { border: 1px solid var(--c-blue-regular); }
.b-blue-light   { border: 1px solid var(--c-blue-light); }
.b-blue         { border: 1px solid var(--c-blue-regular); }

/* Green */
.b-green-dark    { border: 1px solid var(--c-green-dark); }
.b-green-medium  { border: 1px solid var(--c-green-medium); }
.b-green-regular { border: 1px solid var(--c-green-regular); }
.b-green-light   { border: 1px solid var(--c-green-light); }
.b-green         { border: 1px solid var(--c-green-regular); }

/* Yellow */
.b-yellow-dark    { border: 1px solid var(--c-yellow-dark); }
.b-yellow-medium  { border: 1px solid var(--c-yellow-medium); }
.b-yellow-regular { border: 1px solid var(--c-yellow-regular); }
.b-yellow-light   { border: 1px solid var(--c-yellow-light); }
.b-yellow         { border: 1px solid var(--c-yellow-regular); }


/* =============================================================
   BORDER-TOP / BORDER-BOTTOM CLASSES
   For use as dividers — same color palette as the full-border
   variants above, but applied to one edge only.
   ============================================================= */

/* Grey */
.bt-grey-00 { border-top: 1px solid var(--c-grey-00); }
.bt-grey-01 { border-top: 1px solid var(--c-grey-01); }
.bt-grey-02 { border-top: 1px solid var(--c-grey-02); }
.bt-grey-03 { border-top: 1px solid var(--c-grey-03); }
.bt-grey-04 { border-top: 1px solid var(--c-grey-04); }
.bt-grey-05 { border-top: 1px solid var(--c-grey-05); }
.bt-grey-06 { border-top: 1px solid var(--c-grey-06); }
.bt-grey-07 { border-top: 1px solid var(--c-grey-07); }
.bt-grey-08 { border-top: 1px solid var(--c-grey-08); }
.bt-grey-09 { border-top: 1px solid var(--c-grey-09); }
.bt-grey-10 { border-top: 1px solid var(--c-grey-10); }

.bb-grey-00 { border-bottom: 1px solid var(--c-grey-00); }
.bb-grey-01 { border-bottom: 1px solid var(--c-grey-01); }
.bb-grey-02 { border-bottom: 1px solid var(--c-grey-02); }
.bb-grey-03 { border-bottom: 1px solid var(--c-grey-03); }
.bb-grey-04 { border-bottom: 1px solid var(--c-grey-04); }
.bb-grey-05 { border-bottom: 1px solid var(--c-grey-05); }
.bb-grey-06 { border-bottom: 1px solid var(--c-grey-06); }
.bb-grey-07 { border-bottom: 1px solid var(--c-grey-07); }
.bb-grey-08 { border-bottom: 1px solid var(--c-grey-08); }
.bb-grey-09 { border-bottom: 1px solid var(--c-grey-09); }
.bb-grey-10 { border-bottom: 1px solid var(--c-grey-10); }

/* Brand */
.bt-periwinkle       { border-top: 1px solid var(--c-periwinkle); }
.bt-periwinkle-light { border-top: 1px solid var(--c-periwinkle-light); }
.bt-aqua             { border-top: 1px solid var(--c-aqua); }
.bt-coral            { border-top: 1px solid var(--c-coral); }
.bt-black            { border-top: 1px solid var(--c-black); }
.bt-white            { border-top: 1px solid var(--c-white); }

.bb-periwinkle       { border-bottom: 1px solid var(--c-periwinkle); }
.bb-periwinkle-light { border-bottom: 1px solid var(--c-periwinkle-light); }
.bb-aqua             { border-bottom: 1px solid var(--c-aqua); }
.bb-coral            { border-bottom: 1px solid var(--c-coral); }
.bb-black            { border-bottom: 1px solid var(--c-black); }
.bb-white            { border-bottom: 1px solid var(--c-white); }

/* Purple */
.bt-purple-dark    { border-top: 1px solid var(--c-purple-dark); }
.bt-purple-medium  { border-top: 1px solid var(--c-purple-medium); }
.bt-purple-regular { border-top: 1px solid var(--c-purple-regular); }
.bt-purple-light   { border-top: 1px solid var(--c-purple-light); }
.bt-purple         { border-top: 1px solid var(--c-purple-regular); }

.bb-purple-dark    { border-bottom: 1px solid var(--c-purple-dark); }
.bb-purple-medium  { border-bottom: 1px solid var(--c-purple-medium); }
.bb-purple-regular { border-bottom: 1px solid var(--c-purple-regular); }
.bb-purple-light   { border-bottom: 1px solid var(--c-purple-light); }
.bb-purple         { border-bottom: 1px solid var(--c-purple-regular); }

/* Blue */
.bt-blue-dark    { border-top: 1px solid var(--c-blue-dark); }
.bt-blue-medium  { border-top: 1px solid var(--c-blue-medium); }
.bt-blue-regular { border-top: 1px solid var(--c-blue-regular); }
.bt-blue-light   { border-top: 1px solid var(--c-blue-light); }
.bt-blue         { border-top: 1px solid var(--c-blue-regular); }

.bb-blue-dark    { border-bottom: 1px solid var(--c-blue-dark); }
.bb-blue-medium  { border-bottom: 1px solid var(--c-blue-medium); }
.bb-blue-regular { border-bottom: 1px solid var(--c-blue-regular); }
.bb-blue-light   { border-bottom: 1px solid var(--c-blue-light); }
.bb-blue         { border-bottom: 1px solid var(--c-blue-regular); }

/* Green */
.bt-green-dark    { border-top: 1px solid var(--c-green-dark); }
.bt-green-medium  { border-top: 1px solid var(--c-green-medium); }
.bt-green-regular { border-top: 1px solid var(--c-green-regular); }
.bt-green-light   { border-top: 1px solid var(--c-green-light); }
.bt-green         { border-top: 1px solid var(--c-green-regular); }

.bb-green-dark    { border-bottom: 1px solid var(--c-green-dark); }
.bb-green-medium  { border-bottom: 1px solid var(--c-green-medium); }
.bb-green-regular { border-bottom: 1px solid var(--c-green-regular); }
.bb-green-light   { border-bottom: 1px solid var(--c-green-light); }
.bb-green         { border-bottom: 1px solid var(--c-green-regular); }

/* Yellow */
.bt-yellow-dark    { border-top: 1px solid var(--c-yellow-dark); }
.bt-yellow-medium  { border-top: 1px solid var(--c-yellow-medium); }
.bt-yellow-regular { border-top: 1px solid var(--c-yellow-regular); }
.bt-yellow-light   { border-top: 1px solid var(--c-yellow-light); }
.bt-yellow         { border-top: 1px solid var(--c-yellow-regular); }

.bb-yellow-dark    { border-bottom: 1px solid var(--c-yellow-dark); }
.bb-yellow-medium  { border-bottom: 1px solid var(--c-yellow-medium); }
.bb-yellow-regular { border-bottom: 1px solid var(--c-yellow-regular); }
.bb-yellow-light   { border-bottom: 1px solid var(--c-yellow-light); }
.bb-yellow         { border-bottom: 1px solid var(--c-yellow-regular); }

:root {
  --spacing-4xs: clamp(0.25rem, 0.227vw + 0.193rem, 0.375rem);
  --spacing-3xs: clamp(0.375rem, 0.227vw + 0.318rem, 0.5rem);
  --spacing-2xs: clamp(0.5rem, 0.227vw + 0.443rem, 0.625rem);
  --spacing-xs: clamp(0.625rem, 0.227vw + 0.568rem, 0.75rem);
  --spacing-s: clamp(0.75rem, 0.227vw + 0.693rem, 0.875rem);
  --spacing-m: clamp(0.875rem, 0.227vw + 0.818rem, 1rem);
  --spacing-l: clamp(1rem, 0.751vw + 0.824rem, 1.5rem);
  --spacing-xl: clamp(1.5rem, 0.909vw + 1.273rem, 2rem);
  --spacing-2xl: clamp(2rem, 1.818vw + 1.545rem, 3rem);
  --spacing-3xl: clamp(3rem, 1.818vw + 2.545rem, 4rem);
  --spacing-4xl: clamp(4rem, 1.818vw + 3.545rem, 5rem);
  --spacing-5xl: clamp(5rem, 1.818vw + 4.545rem, 6rem);
  --spacing-6xl: clamp(6rem, 1.818vw + 5.545rem, 7rem);
  --spacing-7xl: clamp(7rem, 1.818vw + 6.545rem, 8rem);
  --spacing-8xl: clamp(8rem, 1.818vw + 7.545rem, 9rem);
}

/* ========== Padding ========== */

.p-4xs {
  padding: var(--spacing-4xs);
}
.p-3xs {
  padding: var(--spacing-3xs);
}
.p-2xs {
  padding: var(--spacing-2xs);
}
.p-xs {
  padding: var(--spacing-xs);
}
.p-s {
  padding: var(--spacing-s);
}
.p-m {
  padding: var(--spacing-m);
}
.p-l {
  padding: var(--spacing-l);
}
.p-xl {
  padding: var(--spacing-xl);
}
.p-2xl {
  padding: var(--spacing-2xl);
}
.p-3xl {
  padding: var(--spacing-3xl);
}
.p-4xl {
  padding: var(--spacing-4xl);
}
.p-5xl {
  padding: var(--spacing-5xl);
}
.p-6xl {
  padding: var(--spacing-6xl);
}
.p-7xl {
  padding: var(--spacing-7xl);
}
.p-8xl {
  padding: var(--spacing-8xl);
}

/* ========== Padding Bottom ========== */

.pb-4xs {
  padding-bottom: var(--spacing-4xs);
}
.pb-3xs {
  padding-bottom: var(--spacing-3xs);
}
.pb-2xs {
  padding-bottom: var(--spacing-2xs);
}
.pb-xs {
  padding-bottom: var(--spacing-xs);
}
.pb-s {
  padding-bottom: var(--spacing-s);
}
.pb-m {
  padding-bottom: var(--spacing-m);
}
.pb-l {
  padding-bottom: var(--spacing-l);
}
.pb-xl {
  padding-bottom: var(--spacing-xl);
}
.pb-2xl {
  padding-bottom: var(--spacing-2xl);
}
.pb-3xl {
  padding-bottom: var(--spacing-3xl);
}
.pb-4xl {
  padding-bottom: var(--spacing-4xl);
}
.pb-5xl {
  padding-bottom: var(--spacing-5xl);
}
.pb-6xl {
  padding-bottom: var(--spacing-6xl);
}
.pb-7xl {
  padding-bottom: var(--spacing-7xl);
}
.pb-8xl {
  padding-bottom: var(--spacing-8xl);
}

/* ========== Padding Bottom ========== */

.pt-4xs {
  padding-top: var(--spacing-4xs);
}
.pt-3xs {
  padding-top: var(--spacing-3xs);
}
.pt-2xs {
  padding-top: var(--spacing-2xs);
}
.pt-xs {
  padding-top: var(--spacing-xs);
}
.pt-s {
  padding-top: var(--spacing-s);
}
.pt-m {
  padding-top: var(--spacing-m);
}
.pt-l {
  padding-top: var(--spacing-l);
}
.pt-xl {
  padding-top: var(--spacing-xl);
}
.pt-2xl {
  padding-top: var(--spacing-2xl);
}
.pt-3xl {
  padding-top: var(--spacing-3xl);
}
.pt-4xl {
  padding-top: var(--spacing-4xl);
}
.pt-5xl {
  padding-top: var(--spacing-5xl);
}
.pt-6xl {
  padding-top: var(--spacing-6xl);
}
.pt-7xl {
  padding-top: var(--spacing-7xl);
}
.pt-8xl {
  padding-top: var(--spacing-8xl);
}

/* ========== Padding Right ========== */

.pr-4xs {
  padding-right: var(--spacing-4xs);
}
.pr-3xs {
  padding-right: var(--spacing-3xs);
}
.pr-2xs {
  padding-right: var(--spacing-2xs);
}
.pr-xs {
  padding-right: var(--spacing-xs);
}
.pr-s {
  padding-right: var(--spacing-s);
}
.pr-m {
  padding-right: var(--spacing-m);
}
.pr-l {
  padding-right: var(--spacing-l);
}
.pr-xl {
  padding-right: var(--spacing-xl);
}
.pr-2xl {
  padding-right: var(--spacing-2xl);
}
.pr-3xl {
  padding-right: var(--spacing-3xl);
}
.pr-4xl {
  padding-right: var(--spacing-4xl);
}
.pr-5xl {
  padding-right: var(--spacing-5xl);
}
.pr-6xl {
  padding-right: var(--spacing-6xl);
}
.pr-7xl {
  padding-right: var(--spacing-7xl);
}
.pr-8xl {
  padding-right: var(--spacing-8xl);
}

/* ========== Padding Left ========== */

.pl-4xs {
  padding-left: var(--spacing-4xs);
}
.pl-3xs {
  padding-left: var(--spacing-3xs);
}
.pl-2xs {
  padding-left: var(--spacing-2xs);
}
.pl-xs {
  padding-left: var(--spacing-xs);
}
.pl-s {
  padding-left: var(--spacing-s);
}
.pl-m {
  padding-left: var(--spacing-m);
}
.pl-l {
  padding-left: var(--spacing-l);
}
.pl-xl {
  padding-left: var(--spacing-xl);
}
.pl-2xl {
  padding-left: var(--spacing-2xl);
}
.pl-3xl {
  padding-left: var(--spacing-3xl);
}
.pl-4xl {
  padding-left: var(--spacing-4xl);
}
.pl-5xl {
  padding-left: var(--spacing-5xl);
}
.pl-6xl {
  padding-left: var(--spacing-6xl);
}
.pl-7xl {
  padding-left: var(--spacing-7xl);
}
.pl-8xl {
  padding-left: var(--spacing-8xl);
}

/* ========== Padding Cancel ========== */

.p-t-0 {
  padding-top: 0;
}
.p-r-0 {
  padding-right: 0;
}
.p-b-0 {
  padding-bottom: 0;
}
.p-l-0 {
  padding-left: 0;
}

/* ========== Margin ========== */

.m-s {
  margin: var(--spacing-s);
}
.m-m {
  margin: var(--spacing-m);
}
.m-l {
  margin: var(--spacing-l);
}
.m-xl {
  margin: var(--spacing-xl);
}
.m-2xl {
  margin: var(--spacing-2xl);
}
.m-3xl {
  margin: var(--spacing-3xl);
}
.m-4xl {
  margin: var(--spacing-4xl);
}

/* ========== Margin Bottom ========== */

.mb-s {
  margin-bottom: var(--spacing-s);
}
.mb-m {
  margin-bottom: var(--spacing-m);
}
.mb-l {
  margin-bottom: var(--spacing-l);
}
.mb-xl {
  margin-bottom: var(--spacing-xl);
}
.mb-2xl {
  margin-bottom: var(--spacing-2xl);
}
.mb-3xl {
  margin-bottom: var(--spacing-3xl);
}
.mb-4xl {
  margin-bottom: var(--spacing-4xl);
}

/* ========== Margin Top ========== */

.mt-s {
  margin-top: var(--spacing-s);
}
.mt-m {
  margin-top: var(--spacing-m);
}
.mt-l {
  margin-top: var(--spacing-l);
}
.mt-xl {
  margin-top: var(--spacing-xl);
}
.mt-2xl {
  margin-top: var(--spacing-2xl);
}
.mt-3xl {
  margin-top: var(--spacing-3xl);
}
.mt-4xl {
  margin-top: var(--spacing-4xl);
}

/* ========== Margin Right ========== */

.mr-s {
  margin-right: var(--spacing-s);
}
.mr-m {
  margin-right: var(--spacing-m);
}
.mr-l {
  margin-right: var(--spacing-l);
}
.mr-xl {
  margin-right: var(--spacing-xl);
}
.mr-2xl {
  margin-right: var(--spacing-2xl);
}
.mr-3xl {
  margin-right: var(--spacing-3xl);
}
.mr-4xl {
  margin-right: var(--spacing-4xl);
}

/* ========== Margin Left ========== */

.ml-s {
  margin-left: var(--spacing-s);
}
.ml-m {
  margin-left: var(--spacing-m);
}
.ml-l {
  margin-left: var(--spacing-l);
}
.ml-xl {
  margin-left: var(--spacing-xl);
}
.ml-2xl {
  margin-left: var(--spacing-2xl);
}
.ml-3xl {
  margin-left: var(--spacing-3xl);
}
.ml-4xl {
  margin-left: var(--spacing-4xl);
}

/* Gap */

.gap-s {
  gap: var(--spacing-s);
}
.gap-m {
  gap: var(--spacing-m);
}
.gap-l {
  gap: var(--spacing-l);
}
.gap-xl {
  gap: var(--spacing-xl);
}
.gap-2xl {
  gap: var(--spacing-2xl);
}
.gap-3xl {
  gap: var(--spacing-3xl);
}
.gap-4xl {
  gap: var(--spacing-4xl);
}

@font-face {
  font-display: swap;
  font-family: GT-Flexa Text;
  src: url(https://go.shipfusion.com/hubfs/sf-theme/fonts/gt-flexa/GT-Flexa-Standard-Black.woff2) format("woff2"), url(https://go.shipfusion.com/hubfs/sf-theme/fonts/gt-flexa/GT-Flexa-Standard-Black.woff) format("woff");
  font-weight: 900;
}

@font-face {
  font-display: swap;
  font-family: GT-Flexa Text;
  src: url(https://go.shipfusion.com/hubfs/sf-theme/fonts/gt-flexa/GT-Flexa-Standard-Bold.woff2) format("woff2"), url(https://go.shipfusion.com/hubfs/sf-theme/fonts/gt-flexa/GT-Flexa-Standard-Bold.woff) format("woff");
  font-weight: 700;
}

@font-face {
  font-display: swap;
  font-family: GT-Flexa Text;
  src: url(https://go.shipfusion.com/hubfs/sf-theme/fonts/gt-flexa/GT-Flexa-Standard-Medium.woff2) format("woff2"), url(https://go.shipfusion.com/hubfs/sf-theme/fonts/gt-flexa/GT-Flexa-Standard-Medium.woff) format("woff");
  font-weight: 500;
}

@font-face {
  font-display: swap;
  font-family: GT-Flexa Text;
  src: url(https://go.shipfusion.com/hubfs/sf-theme/fonts/gt-flexa/GT-Flexa-Standard-Regular.woff2) format("woff2"), url(https://go.shipfusion.com/hubfs/sf-theme/fonts/gt-flexa/GT-Flexa-Standard-Regular.woff) format("woff");
  font-weight: 400;
}

html {
  scroll-behavior: smooth;
}

body {
  font-family: Inter, Helvetica, Helvetica Neue, Arial, sans-serif;
  text-wrap: balance;
  overflow-wrap: break-word;
  background-color: var(--body-bg);
  color: var(--body-fg);
}

/* Light page templates set the body canvas via a bg-* utility (e.g.
   blank-light.html → body class="bg-grey-10"). Mirror that onto --body-bg
   AND flip --body-fg to a dark text color, scoped to <body> so neither
   leaks into nested bg-grey-10 cards. This keeps the bg-glow edge fade
   dissolving into the page (fade-follows-body) and body/heading text
   legible (headings inherit body color). Add a sibling line for any other
   utility used as a page canvas. */
body.bg-grey-10 { --body-bg: var(--c-grey-10); --body-fg: var(--c-grey-01); }
body.bg-grey-09 { --body-bg: var(--c-grey-09); --body-fg: var(--c-grey-01); }
body.bg-white   { --body-bg: var(--c-white);   --body-fg: var(--c-grey-01); }

.t-pretty {
  text-wrap: pretty;
}

/* Icons — sizing/alignment for Font Awesome.

   Covers both kit modes:
     - `<i class="fa-solid fa-…">`           (webfont, when kit serves CSS)
     - `<svg class="svg-inline--fa fa-…">`   (default — kit replaces <i> with SVG)
   Each FA style class (.fa-solid / .fa-regular / .fa-brands / .fa-light /
   .fa-thin / .fa-sharp) is matched explicitly. `.svg-inline--fa` catches the
   SVG injected at runtime. */

.fa-solid,
.fa-regular,
.fa-brands,
.fa-light,
.fa-thin,
.fa-sharp,
.svg-inline--fa {
  font-size: 1em;
  line-height: 1;
  vertical-align: middle;
}

.icon-text {
  display: inline-flex;
  align-items: center;
}

/* Hero/display headings only: pin the inline FA icon's box so the deferred
   FA-kit swap can't shift the line vertically. Before injection the empty
   <i> inherits the heading's large line-height (a tall flex item); the
   injected .svg-inline--fa is line-height:1 — that collapse nudges the line.
   Forcing line-height:1 + a 1em box keeps it identical before/after. Scoped
   to .h-display, so icon rendering in buttons/links/body is unchanged. */
.h-display .icon-text > i[class*="fa-"],
.h-display .icon-text > .svg-inline--fa {
  line-height: 1;
  height: 1em;
}

/* Paragraphs */

p,
.p {
  font-size: clamp(0.875rem, 0.455vw + 0.761rem, 1.125rem);
  line-height: clamp(1.488rem, 0.568vw + 1.345rem, 1.8rem);
  margin: 0;
}

.p-small {
  font-size: clamp(0.75rem, 0.227vw + 0.693rem, 0.875rem);
  line-height: clamp(1.275rem, 0.386vw + 1.178rem, 1.488rem);
  margin: 0;
  font-weight: 400;
}

/* Headings */

h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0;
  font-family: "GT-Flexa Text", Helvetica, Helvetica Neue, Arial, sans-serif;
}

.h1,
.h2,
.h3,
.h4,
.h5,
.h6,
.h-display {
  margin: 0;
  font-family: "GT-Flexa Text", Helvetica, Helvetica Neue, Arial, sans-serif;
}

h1,
.h-display {
  font-size: clamp(3rem, 2.727vw + 2.318rem, 4.5rem);
  line-height: clamp(3.3rem, 3vw + 2.55rem, 4.95rem);
  font-weight: 500;
  margin: 0;
}

.h-display-l {
  font-size: clamp(4.5rem, 4.545vw + 3.364rem, 7rem);
  line-height: clamp(4.95rem, 5vw + 3.7rem, 7.7rem);
  font-weight: 500;
  font-family: "GT-Flexa Text", Helvetica, Helvetica Neue, Arial, sans-serif;
  margin: 0;
}

h1,
.h1 {
  font-size: clamp(2.5rem, 1.818vw + 2.045rem, 3.5rem);
  line-height: clamp(3rem, 1.545vw + 2.614rem, 3.85rem);
  font-weight: 400;
}

h2,
.h2 {
  font-size: clamp(2rem, 1.818vw + 1.545rem, 3rem);
  line-height: clamp(2.4rem, 1.636vw + 1.991rem, 3.3rem);
  font-weight: 400;
}

h3,
.h3 {
  font-size: clamp(1.75rem, 1.364vw + 1.409rem, 2.5rem);
  line-height: clamp(2.275rem, 1.318vw + 1.945rem, 3rem);
  font-weight: 400;
}

h4,
.h4 {
  font-size: clamp(1.5rem, 0.909vw + 1.273rem, 2rem);
  line-height: clamp(1.95rem, 0.818vw + 1.745rem, 2.4rem);
  font-weight: 400;
}

h5,
.h5 {
  font-size: clamp(1.125rem, 0.682vw + 0.955rem, 1.5rem);
  line-height: clamp(1.688rem, 1.023vw + 1.432rem, 2.25rem);
  font-weight: 400;
}

h6,
.h6 {
  font-size: clamp(0.875rem, 0.455vw + 0.761rem, 1.125rem);
  line-height: clamp(1.4rem, 0.727vw + 1.218rem, 1.8rem);
  font-weight: 400;
  text-transform: uppercase;
}

/* Lists */

ul {
  padding-left: 1.5em;
}

li {
  margin: 0;
  line-height: clamp(1.488rem, 0.568vw + 1.345rem, 1.8rem);
}

li + li {
  margin-top: var(--spacing-2xs);
}

ul.li-check,
.li-check ul,
ul.li-check-dark,
.li-check-dark ul,
ul.li-xmark,
.li-xmark ul {
  list-style: none;
  padding: 0;
}

.li-check li,
.li-check-dark li,
.li-xmark li {
  position: relative;
  padding-left: var(--spacing-xl);
}

.li-check li::before,
.li-check-dark li::before,
.li-xmark li::before {
  content: "";

  position: absolute;
  left: 0;
  top: 0.2rem;

  width: var(--spacing-l);
  height: var(--spacing-l);
  border-radius: var(--spacing-4xs);

  /* Icon renders as an inline SVG via background-image. Self-contained — no
     webfont dependency, so it works regardless of how Font Awesome is loaded
     (kit, CDN, or not at all). Box (border + size + radius) stays on the
     pseudo-element; the SVG fills the inner area centered at ~55%. */
  background-position: center;
  background-repeat: no-repeat;
  background-size: 55%;
}

/* Stroke color is baked into each SVG to match the box border. */
.li-check li::before {
  background-color: transparent;
  border: 1px solid var(--c-aqua);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231ED4AA' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
}

.li-check-dark li::before {
  background-color: var(--c-grey-02);
  border: 1px solid var(--c-grey-05);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23D5D6EA' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
}

.li-xmark li::before {
  background-color: transparent;
  border: 1px solid var(--c-coral);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FF815C' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><line x1='18' y1='6' x2='6' y2='18'/><line x1='6' y1='6' x2='18' y2='18'/></svg>");
}

.li-none li,
li.li-none {
  list-style: none;
  padding-left: 0;
}

.li-none li::before,
li.li-none::before {
  content: none;
  display: none;
}

ul,
ol {
  margin: 0;
}

ul ul,
ol ul,
ul ol,
ol ol {
  margin: 0;
}

/* No list */
ul.no-list,
ol.no-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

ul.no-list > li,
ol.no-list > li {
  position: static;
  padding-left: 0;
  margin: 0;
  line-height: inherit;
}

ul.no-list > li::before,
ol.no-list > li::before {
  content: none; /* hides the checkmark */
  display: none;
}

/* Code blocks */

pre {
  overflow: auto;
}

code {
  vertical-align: bottom;
}

/* Blockquotes */

blockquote {
  border-left: 2px solid var(--c-grey-05);
  margin: 0;
  padding-left: var(--spacing-xs);
}

/* Text Align */
.t-align-center {
  text-align: center;
}

.t-align-left {
  text-align: left;
}

.t-align-right {
  text-align: right;
}

/* Text Transform */

.t-uppercase {
  text-transform: uppercase;
}

/* Text Decoration */

.t-line-through {
  text-decoration: line-through;
  text-decoration-thickness: 0.4px;
}

.div-dots {
  width: 100%;
  height: 2px;
  background-image: radial-gradient(circle, oklch(var(--c-l-3) var(--c-c) var(--c-h-0) / 32%) 1px, transparent 1px);
  background-size: var(--spacing-s);
  background-repeat: repeat-x;
  margin-top: var(--spacing-3xl);
  margin-bottom: var(--spacing-3xl);
}

.div-line {
  width: 100%;
  height: 1px;
  margin-top: var(--spacing-xl);
  margin-bottom: var(--spacing-xl);
}

.div-bar {
  width: 1px;
  min-height: 24px;
}

.media-fg {
  position: relative;
}

.media-fg img {
  display: block;
  max-width: 100%;
  height: auto;
}

.p-t-0 .media-fg {
  border-radius: 0 0 var(--spacing-xs) var(--spacing-xs);
  top: -1px;
}

.p-r-0 .media-fg {
  border-radius: var(--spacing-xs) 0 0 var(--spacing-xs);
  right: -1px;
}

.p-b-0 .media-fg {
  border-radius: var(--spacing-xs) var(--spacing-xs) 0 0;
  bottom: -4px;
}

.p-l-0 .media-fg {
  border-radius: 0 var(--spacing-xs) var(--spacing-xs) 0;
  left: -1px;
}

.media-bg {
  position: relative;
}

/* ── iframe-wrap ──────────────────────────────────────────────────────
 * Wrapper for embedded iframes (animations, embeds, demos).
 *
 * Paste into a rich text / media_src field:
 *
 *   <div class="iframe-wrap iframe-w-160 iframe-aspect-16-9">
 *     <iframe src="..."></iframe>
 *   </div>
 *
 * For non-standard ratios, override the variable inline:
 *
 *   <div class="iframe-wrap iframe-w-160" style="--iframe-aspect: 1920/1380">
 *     <iframe src="..."></iframe>
 *   </div>
 *
 * Width variants overscale the wrapper for visual bleed past its column.
 * Mobile (< 991px) clamps width back to 100%.
 * ─────────────────────────────────────────────────────────────────── */

.iframe-wrap {
  --iframe-w: 100%;
  --iframe-aspect: 16 / 9;

  position: relative;
  width: var(--iframe-w);
  aspect-ratio: var(--iframe-aspect);
  overflow: visible;
}

.iframe-wrap iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* Width scale */
.iframe-w-100 { --iframe-w: 100%; }
.iframe-w-110 { --iframe-w: 110%; }
.iframe-w-120 { --iframe-w: 120%; }
.iframe-w-130 { --iframe-w: 130%; }
.iframe-w-140 { --iframe-w: 140%; }
.iframe-w-150 { --iframe-w: 150%; }
.iframe-w-160 { --iframe-w: 160%; }
.iframe-w-180 { --iframe-w: 180%; }
.iframe-w-200 { --iframe-w: 200%; }

/* Aspect ratio variants */
.iframe-aspect-16-9 { --iframe-aspect: 16 / 9; }
.iframe-aspect-4-3  { --iframe-aspect: 4 / 3; }
.iframe-aspect-3-2  { --iframe-aspect: 3 / 2; }
.iframe-aspect-1-1  { --iframe-aspect: 1 / 1; }
.iframe-aspect-9-16 { --iframe-aspect: 9 / 16; }

@media (max-width: 991px) {
  .iframe-wrap { --iframe-w: 100%; }
}

/* ── bg-glow — section background: CSS radial blobs + wavy rotating SVG
   rings + tint + grain. Markup is injected by the bg-glow runtime in
   js/animations.js (auto-finds .bg-glow hosts: sections, cards, containers).
   Replaced the heavier 6-layer SVG-gradient system. Variants bg-glow-1/2/3
   + bg-glow-fade-top / bg-glow-fade-bottom modifiers. ──────────────────── */
.bg-glow {
  position: relative;
  background-color: var(--bg-canvas, #000000);
  overflow: hidden;
  isolation: isolate;
  contain: paint;

  /* canvas + atmosphere */
  --bg-canvas: #000000;
  --bg-speed: 10s;
  --bg-darkness: 0;
  --bg-grain: 1;

  /* Blob 1 (radial) */
  --blob1-start: #4864ff;
  --blob1-mid: #4864ff;
  --blob1-end: rgba(0, 0, 0, 0);
  --opacity-blob1: 0.5;
  --blob1-cx: 24%;
  --blob1-cy: 110%;
  --blob1-size-x: 24%;
  --blob1-size-y: 37%;
  --blob1-mobile-cx: -4%;
  --blob1-mobile-cy: 93%;
  --blob1-mobile-size-x: 50%;
  --blob1-mobile-size-y: 22%;
  --blob1-stop-mid: 0%;
  --blob1-stop-end: 200%;
  --blob1-drift: 0.9;
  --blob1-overlay-c1: #1ed4aa;
  --blob1-overlay-c2: #1ed4aa;
  --blob1-overlay-c3: #4864ff;
  --blob1-overlay-stop-mid: 50%;
  --blob1-overlay-angle: 217deg;
  --blob1-overlay-blend: normal;
  --blob1-overlay-opacity: 1;

  /* Blob 2 (radial) */
  --blob2-start: #4864ff;
  --blob2-mid: #4864ff;
  --blob2-end: rgba(0, 0, 0, 0);
  --opacity-blob2: 0.42;
  --blob2-cx: 91%;
  --blob2-cy: -32%;
  --blob2-size-x: 30%;
  --blob2-size-y: 55%;
  --blob2-mobile-cx: 86%;
  --blob2-mobile-cy: 10%;
  --blob2-mobile-size-x: 29%;
  --blob2-mobile-size-y: 22%;
  --blob2-stop-mid: 0%;
  --blob2-stop-end: 200%;
  --blob2-drift: 1.4;
  --blob2-overlay-c1: #4864ff;
  --blob2-overlay-c2: #4864ff;
  --blob2-overlay-c3: #be81ff;
  --blob2-overlay-stop-mid: 50%;
  --blob2-overlay-angle: 101deg;
  --blob2-overlay-blend: normal;
  --blob2-overlay-opacity: 1;

  /* Ring 1 (wavy) */
  --ring1-start: #be81ff;
  --ring1-end: #4864ff;
  --opacity-ring1: 0.5;
  /* path geometry (consumed by runtime JS) */
  --ring1-cx: 91%;
  --ring1-cy: -14%;
  --ring1-base-r: 52%;
  --ring1-mobile-cx: 72%;
  --ring1-mobile-cy: 1%;
  --ring1-mobile-base-r: 28%;
  --ring1-waviness: 4%;
  --ring1-waves: 4;
  --ring1-gradient-angle: 134deg;
  --ring1-gradient-stop-start: 51%;
  --ring1-gradient-stop-end: 100%;
  --ring1-rotate: 66s;
  --ring1-rotate-dir: normal;
  --blur-ring1: 12px;
  --stroke-ring1: 60;

  /* Ring 2 (wavy) */
  --ring2-start: #1ed4aa;
  --ring2-end: #4864ff;
  --opacity-ring2: 0.46;
  /* path geometry (consumed by runtime JS) */
  --ring2-cx: 30%;
  --ring2-cy: 99%;
  --ring2-base-r: 38%;
  --ring2-mobile-cx: 36%;
  --ring2-mobile-cy: 99%;
  --ring2-mobile-base-r: 25%;
  --ring2-waviness: 9%;
  --ring2-waves: 3;
  --ring2-gradient-angle: 169deg;
  --ring2-gradient-stop-start: 40%;
  --ring2-gradient-stop-end: 100%;
  --ring2-rotate: 94s;
  --ring2-rotate-dir: reverse;
  --blur-ring2: 20px;
  --stroke-ring2: 80;

  /* ── Fade-bottom modifier defaults ── */
  --bg-glow-fade-color:  var(--body-bg, #0D0D18);
  --bg-glow-fade-height: 40%;
}


/* ── Variant 1 · bg-glow-1 ── */
.bg-glow-1 {
  /* canvas + atmosphere */
  --bg-canvas: #000000;
  --bg-speed: 10s;
  --bg-darkness: 0;
  --bg-grain: 1;

  /* Blob 1 (radial) */
  --blob1-start: #4864ff;
  --blob1-mid: #4864ff;
  --blob1-end: rgba(0, 0, 0, 0);
  --opacity-blob1: 0.5;
  --blob1-cx: 0%;
  --blob1-cy: 72%;
  --blob1-size-x: 31%;
  --blob1-size-y: 50%;
  --blob1-mobile-cx: 0%;
  --blob1-mobile-cy: 69%;
  --blob1-mobile-size-x: 50%;
  --blob1-mobile-size-y: 22%;
  --blob1-stop-mid: 60%;
  --blob1-stop-end: 100%;
  --blob1-drift: 0.9;
  --blob1-overlay-c1: #4864ff;
  --blob1-overlay-c2: #be81ff;
  --blob1-overlay-c3: #4864ff;
  --blob1-overlay-stop-mid: 50%;
  --blob1-overlay-angle: 191deg;
  --blob1-overlay-blend: normal;
  --blob1-overlay-opacity: 1;

  /* Blob 2 (radial) */
  --blob2-start: #1ed4aa;
  --blob2-mid: #1ed4aa;
  --blob2-end: rgba(0, 0, 0, 0);
  --opacity-blob2: 0.42;
  --blob2-cx: 100%;
  --blob2-cy: 20%;
  --blob2-size-x: 29%;
  --blob2-size-y: 46%;
  --blob2-mobile-cx: 100%;
  --blob2-mobile-cy: 24%;
  --blob2-mobile-size-x: 29%;
  --blob2-mobile-size-y: 22%;
  --blob2-stop-mid: 50%;
  --blob2-stop-end: 116%;
  --blob2-drift: 1.4;
  --blob2-overlay-c1: #4864ff;
  --blob2-overlay-c2: #1ed4aa;
  --blob2-overlay-c3: #1ed4aa;
  --blob2-overlay-stop-mid: 50%;
  --blob2-overlay-angle: 217deg;
  --blob2-overlay-blend: normal;
  --blob2-overlay-opacity: 1;

  /* Ring 1 (wavy) */
  --ring1-start: #4864ff;
  --ring1-end: #1ed4aa;
  --opacity-ring1: 0.55;
  /* path geometry (consumed by runtime JS) */
  --ring1-cx: 104%;
  --ring1-cy: 20%;
  --ring1-base-r: 44%;
  --ring1-mobile-cx: 96%;
  --ring1-mobile-cy: 16%;
  --ring1-mobile-base-r: 52%;
  --ring1-waviness: 4%;
  --ring1-waves: 4;
  --ring1-gradient-angle: 4deg;
  --ring1-gradient-stop-start: 47%;
  --ring1-gradient-stop-end: 66%;
  --ring1-rotate: 80s;
  --ring1-rotate-dir: normal;
  --blur-ring1: 12px;
  --stroke-ring1: 60;

  /* Ring 2 (wavy) */
  --ring2-start: #4864ff;
  --ring2-end: #ff815c;
  --opacity-ring2: 0.46;
  /* path geometry (consumed by runtime JS) */
  --ring2-cx: 1%;
  --ring2-cy: 72%;
  --ring2-base-r: 30%;
  --ring2-mobile-cx: 30%;
  --ring2-mobile-cy: 71%;
  --ring2-mobile-base-r: 25%;
  --ring2-waviness: 9%;
  --ring2-waves: 3;
  --ring2-gradient-angle: 169deg;
  --ring2-gradient-stop-start: 27%;
  --ring2-gradient-stop-end: 100%;
  --ring2-rotate: 94s;
  --ring2-rotate-dir: reverse;
  --blur-ring2: 20px;
  --stroke-ring2: 80;
}


/* ── Variant 2 · bg-glow-2 ── */
.bg-glow-2 {
  /* canvas + atmosphere */
  --bg-canvas: #000000;
  --bg-speed: 10s;
  --bg-darkness: 0;
  --bg-grain: 1;

  /* Blob 1 (radial) */
  --blob1-start: #4864ff;
  --blob1-mid: #4864ff;
  --blob1-end: rgba(0, 0, 0, 0);
  --opacity-blob1: 0.5;
  --blob1-cx: 24%;
  --blob1-cy: -20%;
  --blob1-size-x: 24%;
  --blob1-size-y: 37%;
  --blob1-mobile-cx: -4%;
  --blob1-mobile-cy: -5%;
  --blob1-mobile-size-x: 50%;
  --blob1-mobile-size-y: 22%;
  --blob1-stop-mid: 0%;
  --blob1-stop-end: 200%;
  --blob1-drift: 0.9;
  --blob1-overlay-c1: #1ed4aa;
  --blob1-overlay-c2: #1ed4aa;
  --blob1-overlay-c3: #4864ff;
  --blob1-overlay-stop-mid: 50%;
  --blob1-overlay-angle: 217deg;
  --blob1-overlay-blend: normal;
  --blob1-overlay-opacity: 1;

  /* Blob 2 (radial) */
  --blob2-start: #4864ff;
  --blob2-mid: #4864ff;
  --blob2-end: rgba(0, 0, 0, 0);
  --opacity-blob2: 0.42;
  --blob2-cx: 91%;
  --blob2-cy: 136%;
  --blob2-size-x: 30%;
  --blob2-size-y: 55%;
  --blob2-mobile-cx: 100%;
  --blob2-mobile-cy: 90%;
  --blob2-mobile-size-x: 29%;
  --blob2-mobile-size-y: 22%;
  --blob2-stop-mid: 0%;
  --blob2-stop-end: 200%;
  --blob2-drift: 1.4;
  --blob2-overlay-c1: #4864ff;
  --blob2-overlay-c2: #be81ff;
  --blob2-overlay-c3: #be81ff;
  --blob2-overlay-stop-mid: 50%;
  --blob2-overlay-angle: 101deg;
  --blob2-overlay-blend: normal;
  --blob2-overlay-opacity: 1;

  /* Ring 1 (wavy) */
  --ring1-start: #be81ff;
  --ring1-end: #4864ff;
  --opacity-ring1: 0.5;
  /* path geometry (consumed by runtime JS) */
  --ring1-cx: 91%;
  --ring1-cy: 110%;
  --ring1-base-r: 52%;
  --ring1-mobile-cx: 72%;
  --ring1-mobile-cy: 89%;
  --ring1-mobile-base-r: 28%;
  --ring1-waviness: 4%;
  --ring1-waves: 4;
  --ring1-gradient-angle: 134deg;
  --ring1-gradient-stop-start: 51%;
  --ring1-gradient-stop-end: 100%;
  --ring1-rotate: 66s;
  --ring1-rotate-dir: normal;
  --blur-ring1: 12px;
  --stroke-ring1: 60;

  /* Ring 2 (wavy) */
  --ring2-start: #1ed4aa;
  --ring2-end: #4864ff;
  --opacity-ring2: 0.46;
  /* path geometry (consumed by runtime JS) */
  --ring2-cx: 30%;
  --ring2-cy: 4%;
  --ring2-base-r: 38%;
  --ring2-mobile-cx: 36%;
  --ring2-mobile-cy: 4%;
  --ring2-mobile-base-r: 25%;
  --ring2-waviness: 9%;
  --ring2-waves: 3;
  --ring2-gradient-angle: 169deg;
  --ring2-gradient-stop-start: 40%;
  --ring2-gradient-stop-end: 100%;
  --ring2-rotate: 94s;
  --ring2-rotate-dir: reverse;
  --blur-ring2: 20px;
  --stroke-ring2: 80;
}


/* ── Variant 3 · bg-glow-3 ── */
.bg-glow-3 {
  /* canvas + atmosphere */
  --bg-canvas: #000000;
  --bg-speed: 10s;
  --bg-darkness: 0;
  --bg-grain: 1;

  /* Blob 1 (radial) */
  --blob1-start: #4864ff;
  --blob1-mid: #4864ff;
  --blob1-end: rgba(0, 0, 0, 0);
  --opacity-blob1: 0.5;
  --blob1-cx: 85%;
  --blob1-cy: 100%;
  --blob1-size-x: 37%;
  --blob1-size-y: 50%;
  --blob1-mobile-cx: 97%;
  --blob1-mobile-cy: 97%;
  --blob1-mobile-size-x: 71%;
  --blob1-mobile-size-y: 37%;
  --blob1-stop-mid: 0%;
  --blob1-stop-end: 100%;
  --blob1-drift: 0.9;
  --blob1-overlay-c1: #ff815c;
  --blob1-overlay-c2: #be81ff;
  --blob1-overlay-c3: #4864ff;
  --blob1-overlay-stop-mid: 50%;
  --blob1-overlay-angle: 25deg;
  --blob1-overlay-blend: normal;
  --blob1-overlay-opacity: 1;

  /* Blob 2 (radial) */
  --blob2-start: #1ed4aa;
  --blob2-mid: #1ed4aa;
  --blob2-end: rgba(0, 0, 0, 0);
  --opacity-blob2: 0.42;
  --blob2-cx: 8%;
  --blob2-cy: 0%;
  --blob2-size-x: 46%;
  --blob2-size-y: 49%;
  --blob2-mobile-cx: -5%;
  --blob2-mobile-cy: 8%;
  --blob2-mobile-size-x: 78%;
  --blob2-mobile-size-y: 36%;
  --blob2-stop-mid: 0%;
  --blob2-stop-end: 116%;
  --blob2-drift: 1.4;
  --blob2-overlay-c1: #1ed4aa;
  --blob2-overlay-c2: #7f39c9;
  --blob2-overlay-c3: #1ed4aa;
  --blob2-overlay-stop-mid: 50%;
  --blob2-overlay-angle: 91deg;
  --blob2-overlay-blend: normal;
  --blob2-overlay-opacity: 1;

  /* Ring 1 (wavy) */
  --ring1-start: #4864ff;
  --ring1-end: #1ed4aa;
  --opacity-ring1: 0;
  /* path geometry (consumed by runtime JS) */
  --ring1-cx: 108%;
  --ring1-cy: 33%;
  --ring1-base-r: 44%;
  --ring1-mobile-cx: 96%;
  --ring1-mobile-cy: 16%;
  --ring1-mobile-base-r: 52%;
  --ring1-waviness: 4%;
  --ring1-waves: 4;
  --ring1-gradient-angle: 165deg;
  --ring1-gradient-stop-start: 47%;
  --ring1-gradient-stop-end: 66%;
  --ring1-rotate: 78s;
  --ring1-rotate-dir: normal;
  --blur-ring1: 12px;
  --stroke-ring1: 60;

  /* Ring 2 (wavy) */
  --ring2-start: #4864ff;
  --ring2-end: #ff815c;
  --opacity-ring2: 0;
  /* path geometry (consumed by runtime JS) */
  --ring2-cx: 1%;
  --ring2-cy: 60%;
  --ring2-base-r: 30%;
  --ring2-mobile-cx: 30%;
  --ring2-mobile-cy: 71%;
  --ring2-mobile-base-r: 25%;
  --ring2-waviness: 9%;
  --ring2-waves: 3;
  --ring2-gradient-angle: 169deg;
  --ring2-gradient-stop-start: 27%;
  --ring2-gradient-stop-end: 100%;
  --ring2-rotate: 94s;
  --ring2-rotate-dir: reverse;
  --blur-ring2: 20px;
  --stroke-ring2: 80;
}


/* ── Variant 4 · bg-glow-4 ── */
.bg-glow-4 {
  /* canvas + atmosphere */
  --bg-canvas: #000000;
  --bg-speed: 10s;
  --bg-darkness: 0;
  --bg-grain: 1;

  /* Blob 1 (radial) */
  --blob1-start: #4864ff;
  --blob1-mid: #4864ff;
  --blob1-end: rgba(0, 0, 0, 0);
  --opacity-blob1: 0.5;
  --blob1-cx: 85%;
  --blob1-cy: 10%;
  --blob1-size-x: 37%;
  --blob1-size-y: 50%;
  --blob1-mobile-cx: 120%;
  --blob1-mobile-cy: 23%;
  --blob1-mobile-size-x: 75%;
  --blob1-mobile-size-y: 40%;
  --blob1-stop-mid: 0%;
  --blob1-stop-end: 100%;
  --blob1-drift: 0.9;
  --blob1-overlay-c1: #ff815c;
  --blob1-overlay-c2: #be81ff;
  --blob1-overlay-c3: #4864ff;
  --blob1-overlay-stop-mid: 50%;
  --blob1-overlay-angle: 25deg;
  --blob1-overlay-blend: normal;
  --blob1-overlay-opacity: 1;

  /* Blob 2 (radial) */
  --blob2-start: #1ed4aa;
  --blob2-mid: #1ed4aa;
  --blob2-end: rgba(0, 0, 0, 0);
  --opacity-blob2: 0.42;
  --blob2-cx: 8%;
  --blob2-cy: 90%;
  --blob2-size-x: 46%;
  --blob2-size-y: 49%;
  --blob2-mobile-cx: 0%;
  --blob2-mobile-cy: 84%;
  --blob2-mobile-size-x: 47%;
  --blob2-mobile-size-y: 34%;
  --blob2-stop-mid: 0%;
  --blob2-stop-end: 116%;
  --blob2-drift: 1.4;
  --blob2-overlay-c1: #1ed4aa;
  --blob2-overlay-c2: #7f39c9;
  --blob2-overlay-c3: #1ed4aa;
  --blob2-overlay-stop-mid: 50%;
  --blob2-overlay-angle: 91deg;
  --blob2-overlay-blend: normal;
  --blob2-overlay-opacity: 1;

  /* Ring 1 (wavy) */
  --ring1-start: #4864ff;
  --ring1-end: #1ed4aa;
  --opacity-ring1: 0;
  /* path geometry (consumed by runtime JS) */
  --ring1-cx: 108%;
  --ring1-cy: 33%;
  --ring1-base-r: 44%;
  --ring1-mobile-cx: 96%;
  --ring1-mobile-cy: 16%;
  --ring1-mobile-base-r: 52%;
  --ring1-waviness: 4%;
  --ring1-waves: 4;
  --ring1-gradient-angle: 165deg;
  --ring1-gradient-stop-start: 47%;
  --ring1-gradient-stop-end: 66%;
  --ring1-rotate: 78s;
  --ring1-rotate-dir: normal;
  --blur-ring1: 12px;
  --stroke-ring1: 60;

  /* Ring 2 (wavy) */
  --ring2-start: #4864ff;
  --ring2-end: #ff815c;
  --opacity-ring2: 0;
  /* path geometry (consumed by runtime JS) */
  --ring2-cx: 1%;
  --ring2-cy: 60%;
  --ring2-base-r: 30%;
  --ring2-mobile-cx: 30%;
  --ring2-mobile-cy: 71%;
  --ring2-mobile-base-r: 25%;
  --ring2-waviness: 9%;
  --ring2-waves: 3;
  --ring2-gradient-angle: 169deg;
  --ring2-gradient-stop-start: 27%;
  --ring2-gradient-stop-end: 100%;
  --ring2-rotate: 94s;
  --ring2-rotate-dir: reverse;
  --blur-ring2: 20px;
  --stroke-ring2: 80;
}


/* ── Variant 5 · bg-glow-5 ── */
.bg-glow-5 {
  /* canvas + atmosphere */
  --bg-canvas: #ffffff;
  --bg-speed: 10s;
  --bg-darkness: 0;
  --bg-grain: 1;

  /* Blob 1 (radial) */
  --blob1-start: #4864ff;
  --blob1-mid: #4864ff;
  --blob1-end: rgba(255, 255, 255, 0);
  --opacity-blob1: 0.5;
  --blob1-cx: 24%;
  --blob1-cy: 110%;
  --blob1-size-x: 24%;
  --blob1-size-y: 37%;
  --blob1-mobile-cx: -4%;
  --blob1-mobile-cy: 93%;
  --blob1-mobile-size-x: 50%;
  --blob1-mobile-size-y: 22%;
  --blob1-stop-mid: 0%;
  --blob1-stop-end: 200%;
  --blob1-drift: 0.9;
  --blob1-overlay-c1: #1ed4aa;
  --blob1-overlay-c2: #1ed4aa;
  --blob1-overlay-c3: #4864ff;
  --blob1-overlay-stop-mid: 50%;
  --blob1-overlay-angle: 0deg;
  --blob1-overlay-blend: normal;
  --blob1-overlay-opacity: 1;

  /* Blob 2 (radial) */
  --blob2-start: #4864ff;
  --blob2-mid: #4864ff;
  --blob2-end: rgba(255, 255, 255, 0);
  --opacity-blob2: 0.42;
  --blob2-cx: 91%;
  --blob2-cy: -32%;
  --blob2-size-x: 30%;
  --blob2-size-y: 55%;
  --blob2-mobile-cx: 86%;
  --blob2-mobile-cy: 10%;
  --blob2-mobile-size-x: 29%;
  --blob2-mobile-size-y: 22%;
  --blob2-stop-mid: 0%;
  --blob2-stop-end: 200%;
  --blob2-drift: 1.4;
  --blob2-overlay-c1: #4864ff;
  --blob2-overlay-c2: #4864ff;
  --blob2-overlay-c3: #be81ff;
  --blob2-overlay-stop-mid: 50%;
  --blob2-overlay-angle: 101deg;
  --blob2-overlay-blend: normal;
  --blob2-overlay-opacity: 1;

  /* Ring 1 (wavy) */
  --ring1-start: #be81ff;
  --ring1-end: #4864ff;
  --opacity-ring1: 0.5;
  /* path geometry (consumed by runtime JS) */
  --ring1-cx: 91%;
  --ring1-cy: -14%;
  --ring1-base-r: 52%;
  --ring1-mobile-cx: 72%;
  --ring1-mobile-cy: 1%;
  --ring1-mobile-base-r: 28%;
  --ring1-waviness: 4%;
  --ring1-waves: 4;
  --ring1-gradient-angle: 134deg;
  --ring1-gradient-stop-start: 51%;
  --ring1-gradient-stop-end: 100%;
  --ring1-rotate: 66s;
  --ring1-rotate-dir: normal;
  --blur-ring1: 12px;
  --stroke-ring1: 60;

  /* Ring 2 (wavy) */
  --ring2-start: #1ed4aa;
  --ring2-end: #4864ff;
  --opacity-ring2: 0.46;
  /* path geometry (consumed by runtime JS) */
  --ring2-cx: 12%;
  --ring2-cy: 99%;
  --ring2-base-r: 38%;
  --ring2-mobile-cx: 36%;
  --ring2-mobile-cy: 99%;
  --ring2-mobile-base-r: 25%;
  --ring2-waviness: 9%;
  --ring2-waves: 3;
  --ring2-gradient-angle: 169deg;
  --ring2-gradient-stop-start: 40%;
  --ring2-gradient-stop-end: 100%;
  --ring2-rotate: 94s;
  --ring2-rotate-dir: reverse;
  --blur-ring2: 20px;
  --stroke-ring2: 80;
}


/* ── Variant 6 · bg-glow-6 ── */
.bg-glow-6 {
  /* canvas + atmosphere */
  --bg-canvas: #ffffff;
  --bg-speed: 10s;
  --bg-darkness: 0;
  --bg-grain: 1;

  /* Blob 1 (radial) */
  --blob1-start: #4864ff;
  --blob1-mid: #4864ff;
  --blob1-end: rgba(255, 255, 255, 0);
  --opacity-blob1: 0.5;
  --blob1-cx: 0%;
  --blob1-cy: 72%;
  --blob1-size-x: 31%;
  --blob1-size-y: 50%;
  --blob1-mobile-cx: 0%;
  --blob1-mobile-cy: 69%;
  --blob1-mobile-size-x: 50%;
  --blob1-mobile-size-y: 22%;
  --blob1-stop-mid: 60%;
  --blob1-stop-end: 100%;
  --blob1-drift: 0.9;
  --blob1-overlay-c1: #4864ff;
  --blob1-overlay-c2: #be81ff;
  --blob1-overlay-c3: #4864ff;
  --blob1-overlay-stop-mid: 50%;
  --blob1-overlay-angle: 191deg;
  --blob1-overlay-blend: normal;
  --blob1-overlay-opacity: 1;

  /* Blob 2 (radial) */
  --blob2-start: #1ed4aa;
  --blob2-mid: #1ed4aa;
  --blob2-end: rgba(255, 255, 255, 0);
  --opacity-blob2: 0.42;
  --blob2-cx: 100%;
  --blob2-cy: 20%;
  --blob2-size-x: 29%;
  --blob2-size-y: 46%;
  --blob2-mobile-cx: 100%;
  --blob2-mobile-cy: 24%;
  --blob2-mobile-size-x: 29%;
  --blob2-mobile-size-y: 22%;
  --blob2-stop-mid: 50%;
  --blob2-stop-end: 116%;
  --blob2-drift: 1.4;
  --blob2-overlay-c1: #4864ff;
  --blob2-overlay-c2: #1ed4aa;
  --blob2-overlay-c3: #1ed4aa;
  --blob2-overlay-stop-mid: 50%;
  --blob2-overlay-angle: 217deg;
  --blob2-overlay-blend: normal;
  --blob2-overlay-opacity: 1;

  /* Ring 1 (wavy) */
  --ring1-start: #4864ff;
  --ring1-end: #1ed4aa;
  --opacity-ring1: 0;
  /* path geometry (consumed by runtime JS) */
  --ring1-cx: 104%;
  --ring1-cy: 20%;
  --ring1-base-r: 44%;
  --ring1-mobile-cx: 96%;
  --ring1-mobile-cy: 16%;
  --ring1-mobile-base-r: 52%;
  --ring1-waviness: 4%;
  --ring1-waves: 4;
  --ring1-gradient-angle: 4deg;
  --ring1-gradient-stop-start: 47%;
  --ring1-gradient-stop-end: 66%;
  --ring1-rotate: 80s;
  --ring1-rotate-dir: normal;
  --blur-ring1: 12px;
  --stroke-ring1: 60;

  /* Ring 2 (wavy) */
  --ring2-start: #4864ff;
  --ring2-end: #ff815c;
  --opacity-ring2: 0;
  /* path geometry (consumed by runtime JS) */
  --ring2-cx: 1%;
  --ring2-cy: 72%;
  --ring2-base-r: 30%;
  --ring2-mobile-cx: 30%;
  --ring2-mobile-cy: 71%;
  --ring2-mobile-base-r: 25%;
  --ring2-waviness: 9%;
  --ring2-waves: 3;
  --ring2-gradient-angle: 169deg;
  --ring2-gradient-stop-start: 27%;
  --ring2-gradient-stop-end: 100%;
  --ring2-rotate: 94s;
  --ring2-rotate-dir: reverse;
  --blur-ring2: 20px;
  --stroke-ring2: 80;
}


/* ── Variant 7 · bg-glow-7 ── */
.bg-glow-7 {
  /* canvas + atmosphere */
  --bg-canvas: #3352ff;
  --bg-speed: 10s;
  --bg-darkness: 0;
  --bg-grain: 1;

  /* Blob 1 (radial) */
  --blob1-start: #4864ff;
  --blob1-mid: #4864ff;
  --blob1-end: rgba(0, 0, 0, 0);
  --opacity-blob1: 0.5;
  --blob1-cx: 10%;
  --blob1-cy: 78%;
  --blob1-size-x: 50%;
  --blob1-size-y: 62%;
  --blob1-mobile-cx: 0%;
  --blob1-mobile-cy: 69%;
  --blob1-mobile-size-x: 50%;
  --blob1-mobile-size-y: 22%;
  --blob1-stop-mid: 0%;
  --blob1-stop-end: 100%;
  --blob1-drift: 0.9;
  --blob1-overlay-c1: #4864ff;
  --blob1-overlay-c2: #be81ff;
  --blob1-overlay-c3: #1ed4aa;
  --blob1-overlay-stop-mid: 50%;
  --blob1-overlay-angle: 281deg;
  --blob1-overlay-blend: normal;
  --blob1-overlay-opacity: 1;

  /* Blob 2 (radial) */
  --blob2-start: #1ed4aa;
  --blob2-mid: #1ed4aa;
  --blob2-end: rgba(0, 0, 0, 0);
  --opacity-blob2: 0.42;
  --blob2-cx: 93%;
  --blob2-cy: 35%;
  --blob2-size-x: 29%;
  --blob2-size-y: 46%;
  --blob2-mobile-cx: 100%;
  --blob2-mobile-cy: 24%;
  --blob2-mobile-size-x: 29%;
  --blob2-mobile-size-y: 22%;
  --blob2-stop-mid: 0%;
  --blob2-stop-end: 116%;
  --blob2-drift: 1.4;
  --blob2-overlay-c1: #1ed4aa;
  --blob2-overlay-c2: #7f39c9;
  --blob2-overlay-c3: #4864ff;
  --blob2-overlay-stop-mid: 50%;
  --blob2-overlay-angle: 217deg;
  --blob2-overlay-blend: normal;
  --blob2-overlay-opacity: 1;

  /* Ring 1 (wavy) */
  --ring1-start: #4864ff;
  --ring1-end: #1ed4aa;
  --opacity-ring1: 0;
  /* path geometry (consumed by runtime JS) */
  --ring1-cx: 108%;
  --ring1-cy: 33%;
  --ring1-base-r: 44%;
  --ring1-mobile-cx: 96%;
  --ring1-mobile-cy: 16%;
  --ring1-mobile-base-r: 52%;
  --ring1-waviness: 4%;
  --ring1-waves: 4;
  --ring1-gradient-angle: 165deg;
  --ring1-gradient-stop-start: 47%;
  --ring1-gradient-stop-end: 66%;
  --ring1-rotate: 78s;
  --ring1-rotate-dir: normal;
  --blur-ring1: 12px;
  --stroke-ring1: 60;

  /* Ring 2 (wavy) */
  --ring2-start: #4864ff;
  --ring2-end: #ff815c;
  --opacity-ring2: 0;
  /* path geometry (consumed by runtime JS) */
  --ring2-cx: 1%;
  --ring2-cy: 60%;
  --ring2-base-r: 30%;
  --ring2-mobile-cx: 30%;
  --ring2-mobile-cy: 71%;
  --ring2-mobile-base-r: 25%;
  --ring2-waviness: 9%;
  --ring2-waves: 3;
  --ring2-gradient-angle: 169deg;
  --ring2-gradient-stop-start: 27%;
  --ring2-gradient-stop-end: 100%;
  --ring2-rotate: 94s;
  --ring2-rotate-dir: reverse;
  --blur-ring2: 20px;
  --stroke-ring2: 80;
}


/* ── Variant 8 · bg-glow-8 ── */
.bg-glow-8 {
  /* canvas + atmosphere */
  --bg-canvas: #3352ff;
  --bg-speed: 10s;
  --bg-darkness: 0;
  --bg-grain: 1;

  /* Blob 1 (radial) */
  --blob1-start: #4864ff;
  --blob1-mid: #1ed4aa;
  --blob1-end: rgba(0, 0, 0, 0);
  --opacity-blob1: 0.5;
  --blob1-cx: 16%;
  --blob1-cy: 100%;
  --blob1-size-x: 31%;
  --blob1-size-y: 50%;
  --blob1-mobile-cx: 0%;
  --blob1-mobile-cy: 69%;
  --blob1-mobile-size-x: 50%;
  --blob1-mobile-size-y: 22%;
  --blob1-stop-mid: 0%;
  --blob1-stop-end: 128%;
  --blob1-drift: 0.9;
  --blob1-overlay-c1: #4864ff;
  --blob1-overlay-c2: #4864ff;
  --blob1-overlay-c3: #1ed4aa;
  --blob1-overlay-stop-mid: 50%;
  --blob1-overlay-angle: 191deg;
  --blob1-overlay-blend: normal;
  --blob1-overlay-opacity: 1;

  /* Blob 2 (radial) */
  --blob2-start: #1ed4aa;
  --blob2-mid: #1ed4aa;
  --blob2-end: rgba(0, 0, 0, 0);
  --opacity-blob2: 0.42;
  --blob2-cx: 92%;
  --blob2-cy: 0%;
  --blob2-size-x: 29%;
  --blob2-size-y: 46%;
  --blob2-mobile-cx: 100%;
  --blob2-mobile-cy: 24%;
  --blob2-mobile-size-x: 29%;
  --blob2-mobile-size-y: 22%;
  --blob2-stop-mid: 0%;
  --blob2-stop-end: 116%;
  --blob2-drift: 1.4;
  --blob2-overlay-c1: #1ed4aa;
  --blob2-overlay-c2: #4864ff;
  --blob2-overlay-c3: #1ed4aa;
  --blob2-overlay-stop-mid: 50%;
  --blob2-overlay-angle: 217deg;
  --blob2-overlay-blend: normal;
  --blob2-overlay-opacity: 1;

  /* Ring 1 (wavy) */
  --ring1-start: #4864ff;
  --ring1-end: #ff815c;
  --opacity-ring1: 0.55;
  /* path geometry (consumed by runtime JS) */
  --ring1-cx: 104%;
  --ring1-cy: 12%;
  --ring1-base-r: 44%;
  --ring1-mobile-cx: 96%;
  --ring1-mobile-cy: 16%;
  --ring1-mobile-base-r: 52%;
  --ring1-waviness: 4%;
  --ring1-waves: 4;
  --ring1-gradient-angle: 322deg;
  --ring1-gradient-stop-start: 32%;
  --ring1-gradient-stop-end: 75%;
  --ring1-rotate: 78s;
  --ring1-rotate-dir: normal;
  --blur-ring1: 12px;
  --stroke-ring1: 60;

  /* Ring 2 (wavy) */
  --ring2-start: #4864ff;
  --ring2-end: #1ed4aa;
  --opacity-ring2: 0.46;
  /* path geometry (consumed by runtime JS) */
  --ring2-cx: 16%;
  --ring2-cy: 92%;
  --ring2-base-r: 30%;
  --ring2-mobile-cx: 30%;
  --ring2-mobile-cy: 71%;
  --ring2-mobile-base-r: 25%;
  --ring2-waviness: 9%;
  --ring2-waves: 3;
  --ring2-gradient-angle: 153deg;
  --ring2-gradient-stop-start: 44%;
  --ring2-gradient-stop-end: 60%;
  --ring2-rotate: 94s;
  --ring2-rotate-dir: reverse;
  --blur-ring2: 20px;
  --stroke-ring2: 80;
}


/* ── Variant 9 · bg-glow-9 ── */
.bg-glow-9 {
  /* canvas + atmosphere */
  --bg-canvas: #000000;
  --bg-speed: 10s;
  --bg-darkness: 0;
  --bg-grain: 1;

  /* Blob 1 (radial) */
  --blob1-start: #4864ff;
  --blob1-mid: #4864ff;
  --blob1-end: rgba(0, 0, 0, 0);
  --opacity-blob1: 0.5;
  --blob1-cx: 67%;
  --blob1-cy: 126%;
  --blob1-size-x: 24%;
  --blob1-size-y: 37%;
  --blob1-mobile-cx: 93%;
  --blob1-mobile-cy: 92%;
  --blob1-mobile-size-x: 50%;
  --blob1-mobile-size-y: 22%;
  --blob1-stop-mid: 0%;
  --blob1-stop-end: 200%;
  --blob1-drift: 0.9;
  --blob1-overlay-c1: #1ed4aa;
  --blob1-overlay-c2: #1ed4aa;
  --blob1-overlay-c3: #4864ff;
  --blob1-overlay-stop-mid: 50%;
  --blob1-overlay-angle: 217deg;
  --blob1-overlay-blend: normal;
  --blob1-overlay-opacity: 1;

  /* Blob 2 (radial) */
  --blob2-start: #4864ff;
  --blob2-mid: #4864ff;
  --blob2-end: rgba(0, 0, 0, 0);
  --opacity-blob2: 0.42;
  --blob2-cx: 38%;
  --blob2-cy: -50%;
  --blob2-size-x: 30%;
  --blob2-size-y: 55%;
  --blob2-mobile-cx: 8%;
  --blob2-mobile-cy: 9%;
  --blob2-mobile-size-x: 45%;
  --blob2-mobile-size-y: 22%;
  --blob2-stop-mid: 0%;
  --blob2-stop-end: 200%;
  --blob2-drift: 1.4;
  --blob2-overlay-c1: #4864ff;
  --blob2-overlay-c2: #4864ff;
  --blob2-overlay-c3: #be81ff;
  --blob2-overlay-stop-mid: 50%;
  --blob2-overlay-angle: 101deg;
  --blob2-overlay-blend: normal;
  --blob2-overlay-opacity: 1;

  /* Ring 1 (wavy) */
  --ring1-start: #be81ff;
  --ring1-end: #4864ff;
  --opacity-ring1: 0.5;
  /* path geometry (consumed by runtime JS) */
  --ring1-cx: 43%;
  --ring1-cy: -15%;
  --ring1-base-r: 52%;
  --ring1-mobile-cx: 35%;
  --ring1-mobile-cy: 10%;
  --ring1-mobile-base-r: 28%;
  --ring1-waviness: 4%;
  --ring1-waves: 4;
  --ring1-gradient-angle: 134deg;
  --ring1-gradient-stop-start: 51%;
  --ring1-gradient-stop-end: 100%;
  --ring1-rotate: 66s;
  --ring1-rotate-dir: normal;
  --blur-ring1: 12px;
  --stroke-ring1: 60;

  /* Ring 2 (wavy) */
  --ring2-start: #1ed4aa;
  --ring2-end: #4864ff;
  --opacity-ring2: 0.46;
  /* path geometry (consumed by runtime JS) */
  --ring2-cx: 63%;
  --ring2-cy: 108%;
  --ring2-base-r: 38%;
  --ring2-mobile-cx: 61%;
  --ring2-mobile-cy: 91%;
  --ring2-mobile-base-r: 25%;
  --ring2-waviness: 9%;
  --ring2-waves: 3;
  --ring2-gradient-angle: 169deg;
  --ring2-gradient-stop-start: 40%;
  --ring2-gradient-stop-end: 100%;
  --ring2-rotate: 94s;
  --ring2-rotate-dir: reverse;
  --blur-ring2: 20px;
  --stroke-ring2: 80;
}


/* ── Variant 10 · bg-glow-10 ── */
.bg-glow-10 {
  /* canvas + atmosphere */
  --bg-canvas: #000000;
  --bg-speed: 10s;
  --bg-darkness: 0;
  --bg-grain: 1;

  /* Blob 1 (radial) */
  --blob1-start: #4864ff;
  --blob1-mid: #4864ff;
  --blob1-end: rgba(0, 0, 0, 0);
  --opacity-blob1: 0.5;
  --blob1-cx: 35%;
  --blob1-cy: 126%;
  --blob1-size-x: 24%;
  --blob1-size-y: 37%;
  --blob1-mobile-cx: -9%;
  --blob1-mobile-cy: 92%;
  --blob1-mobile-size-x: 50%;
  --blob1-mobile-size-y: 22%;
  --blob1-stop-mid: 0%;
  --blob1-stop-end: 200%;
  --blob1-drift: 0.9;
  --blob1-overlay-c1: #be81ff;
  --blob1-overlay-c2: #be81ff;
  --blob1-overlay-c3: #4864ff;
  --blob1-overlay-stop-mid: 50%;
  --blob1-overlay-angle: 225deg;
  --blob1-overlay-blend: normal;
  --blob1-overlay-opacity: 1;

  /* Blob 2 (radial) */
  --blob2-start: #4864ff;
  --blob2-mid: #4864ff;
  --blob2-end: rgba(0, 0, 0, 0);
  --opacity-blob2: 0.42;
  --blob2-cx: 82%;
  --blob2-cy: -50%;
  --blob2-size-x: 30%;
  --blob2-size-y: 55%;
  --blob2-mobile-cx: 105%;
  --blob2-mobile-cy: 9%;
  --blob2-mobile-size-x: 45%;
  --blob2-mobile-size-y: 22%;
  --blob2-stop-mid: 0%;
  --blob2-stop-end: 200%;
  --blob2-drift: 1.4;
  --blob2-overlay-c1: #4864ff;
  --blob2-overlay-c2: #4864ff;
  --blob2-overlay-c3: #1ed4aa;
  --blob2-overlay-stop-mid: 50%;
  --blob2-overlay-angle: 360deg;
  --blob2-overlay-blend: normal;
  --blob2-overlay-opacity: 1;

  /* Ring 1 (wavy) */
  --ring1-start: #1ed4aa;
  --ring1-end: #4864ff;
  --opacity-ring1: 0.5;
  /* path geometry (consumed by runtime JS) */
  --ring1-cx: 79%;
  --ring1-cy: -15%;
  --ring1-base-r: 52%;
  --ring1-mobile-cx: 69%;
  --ring1-mobile-cy: 10%;
  --ring1-mobile-base-r: 28%;
  --ring1-waviness: 4%;
  --ring1-waves: 4;
  --ring1-gradient-angle: 134deg;
  --ring1-gradient-stop-start: 51%;
  --ring1-gradient-stop-end: 100%;
  --ring1-rotate: 66s;
  --ring1-rotate-dir: normal;
  --blur-ring1: 12px;
  --stroke-ring1: 60;

  /* Ring 2 (wavy) */
  --ring2-start: #be81ff;
  --ring2-end: #4864ff;
  --opacity-ring2: 0.46;
  /* path geometry (consumed by runtime JS) */
  --ring2-cx: 39%;
  --ring2-cy: 104%;
  --ring2-base-r: 38%;
  --ring2-mobile-cx: 34%;
  --ring2-mobile-cy: 91%;
  --ring2-mobile-base-r: 25%;
  --ring2-waviness: 9%;
  --ring2-waves: 3;
  --ring2-gradient-angle: 169deg;
  --ring2-gradient-stop-start: 40%;
  --ring2-gradient-stop-end: 100%;
  --ring2-rotate: 94s;
  --ring2-rotate-dir: reverse;
  --blur-ring2: 20px;
  --stroke-ring2: 80;
}


/* ── Mobile breakpoint swap ─────────────────────────────────────────
   Below 991px (sf-theme mobile boundary), each shape's active
   position/size var switches to its mobile-* counterpart. */
@media (max-width: 991px) {
  .bg-glow {
    --blob1-cx:     var(--blob1-mobile-cx);
    --blob1-cy:     var(--blob1-mobile-cy);
    --blob1-size-x: var(--blob1-mobile-size-x);
    --blob1-size-y: var(--blob1-mobile-size-y);
    --blob2-cx:     var(--blob2-mobile-cx);
    --blob2-cy:     var(--blob2-mobile-cy);
    --blob2-size-x: var(--blob2-mobile-size-x);
    --blob2-size-y: var(--blob2-mobile-size-y);
    --ring1-cx:     var(--ring1-mobile-cx);
    --ring1-cy:     var(--ring1-mobile-cy);
    --ring1-base-r: var(--ring1-mobile-base-r);
    --ring2-cx:     var(--ring2-mobile-cx);
    --ring2-cy:     var(--ring2-mobile-cy);
    --ring2-base-r: var(--ring2-mobile-base-r);
  }
}


/* ── Layer scaffolding ──────────────────────────────────────────── */

.bg-glow .bg-layer {
  position: absolute;
  inset: -10%;
  width: 120%;
  height: 120%;
  pointer-events: none;
}
.bg-glow .bg-layer svg { width: 100%; height: 100%; display: block; overflow: visible; }

.bg-glow .bg-layer--blob1 { z-index: 0; opacity: var(--opacity-blob1); }
.bg-glow .bg-layer--blob2 { z-index: 1; opacity: var(--opacity-blob2); }
.bg-glow .bg-layer--ring1 { z-index: 2; opacity: var(--opacity-ring1); filter: blur(var(--blur-ring1)) saturate(1.15); }
.bg-glow .bg-layer--ring2 { z-index: 3; opacity: var(--opacity-ring2); filter: blur(var(--blur-ring2)) saturate(1.15); }


/* ── Blob shapes ────────────────────────────────────────────────── */

.bg-glow .bg-shape--blob1 {
  position: absolute; inset: 0;
  isolation: isolate;
  background: radial-gradient(
    ellipse var(--blob1-size-x) var(--blob1-size-y)
    at var(--blob1-cx) var(--blob1-cy)
    in oklab,
    var(--blob1-start),
    var(--blob1-mid) var(--blob1-stop-mid),
    var(--blob1-end) var(--blob1-stop-end)
  );
  animation: glowBlobDriftA calc(var(--bg-speed) * var(--blob1-drift)) ease-in-out infinite;
  will-change: transform;
}

/* Linear overlay clipped by a copy of the radial used as alpha mask, so
   it only renders within the blob's shape. mix-blend-mode + parent
   isolation confine the blend to the radial below it.  The composed
   gradient string is set inline by the runtime onto
   --blob1-overlay-gradient. */
.bg-glow .bg-shape--blob1::after {
  content: '';
  position: absolute; inset: 0;
  background: var(--blob1-overlay-gradient, none);
  -webkit-mask-image: radial-gradient(
    ellipse var(--blob1-size-x) var(--blob1-size-y)
    at var(--blob1-cx) var(--blob1-cy),
    var(--blob1-start),
    var(--blob1-mid) var(--blob1-stop-mid),
    var(--blob1-end) var(--blob1-stop-end)
  );
  mask-image: radial-gradient(
    ellipse var(--blob1-size-x) var(--blob1-size-y)
    at var(--blob1-cx) var(--blob1-cy),
    var(--blob1-start),
    var(--blob1-mid) var(--blob1-stop-mid),
    var(--blob1-end) var(--blob1-stop-end)
  );
  mix-blend-mode: var(--blob1-overlay-blend, normal);
  pointer-events: none;
}

.bg-glow .bg-shape--blob2 {
  position: absolute; inset: 0;
  isolation: isolate;
  background: radial-gradient(
    ellipse var(--blob2-size-x) var(--blob2-size-y)
    at var(--blob2-cx) var(--blob2-cy)
    in oklab,
    var(--blob2-start),
    var(--blob2-mid) var(--blob2-stop-mid),
    var(--blob2-end) var(--blob2-stop-end)
  );
  animation: glowBlobDriftB calc(var(--bg-speed) * var(--blob2-drift)) ease-in-out infinite;
  will-change: transform;
}
.bg-glow .bg-shape--blob2::after {
  content: '';
  position: absolute; inset: 0;
  background: var(--blob2-overlay-gradient, none);
  -webkit-mask-image: radial-gradient(
    ellipse var(--blob2-size-x) var(--blob2-size-y)
    at var(--blob2-cx) var(--blob2-cy),
    var(--blob2-start),
    var(--blob2-mid) var(--blob2-stop-mid),
    var(--blob2-end) var(--blob2-stop-end)
  );
  mask-image: radial-gradient(
    ellipse var(--blob2-size-x) var(--blob2-size-y)
    at var(--blob2-cx) var(--blob2-cy),
    var(--blob2-start),
    var(--blob2-mid) var(--blob2-stop-mid),
    var(--blob2-end) var(--blob2-stop-end)
  );
  mix-blend-mode: var(--blob2-overlay-blend, normal);
  pointer-events: none;
}


/* Subtle drift — ±5% translate, ±10% scale. */
@keyframes glowBlobDriftA {
  0%, 100% { transform: translate(-3%, -2%) scale(1); }
  33%      { transform: translate(2%, 3%)   scale(1.08); }
  66%      { transform: translate(4%, -3%)  scale(0.95); }
}
@keyframes glowBlobDriftB {
  0%, 100% { transform: translate(2%, 1%)   scale(1); }
  35%      { transform: translate(-3%, 4%)  scale(0.92); }
  70%      { transform: translate(-5%, -2%) scale(1.1); }
}


/* ── Ring shapes ────────────────────────────────────────────────── */

.bg-glow .bg-shape--ring1,
.bg-glow .bg-shape--ring2 {
  transform-box: fill-box;
  transform-origin: center;
  will-change: transform;
}
.bg-glow .bg-layer--ring1 path { stroke-width: var(--stroke-ring1); fill: none; }
.bg-glow .bg-layer--ring2 path { stroke-width: var(--stroke-ring2); fill: none; }

.bg-glow .bg-shape--ring1 {
  animation: glowRingRotate var(--ring1-rotate) linear infinite;
  animation-direction: var(--ring1-rotate-dir);
}
.bg-glow .bg-shape--ring2 {
  animation: glowRingRotate var(--ring2-rotate) linear infinite;
  animation-direction: var(--ring2-rotate-dir);
}
@keyframes glowRingRotate {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}


/* ── Tint + grain ───────────────────────────────────────────────── */

.bg-glow > .bg-glow-tint {
  position: absolute; inset: 0;
  z-index: 7;
  pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 50%, transparent 0%, rgba(0, 0, 0, var(--bg-darkness)) 100%),
    linear-gradient(180deg,
      rgba(0, 0, 0, calc(var(--bg-darkness) * 0.4)) 0%,
      rgba(0, 0, 0, calc(var(--bg-darkness) * 0.7)) 100%);
}
.bg-glow > .bg-glow-grain {
  position: absolute; inset: 0;
  /* z-index 7 (same level as tint, rendered after tint via DOM order so
     it still overlays it). Critically, this keeps the grain BELOW both
     fade modifiers (::before / ::after at z 8), so the fade colors
     aren't distorted by the overlay blend mode. */
  z-index: 7;
  pointer-events: none;
  opacity: var(--bg-grain);
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.5 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}


/* ── Fade-bottom modifier — dissolves section bottom into the body
      color so the section reads as continuous with what follows. */
.bg-glow.bg-glow-fade-bottom::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: var(--bg-glow-fade-height, 40%);
  z-index: 8;
  pointer-events: none;
  background: linear-gradient(to bottom, transparent, var(--bg-glow-fade-color, #0D0D18));
}

/* ── Fade-top modifier — symmetric to fade-bottom on the top edge.
      Shares --bg-glow-fade-color and --bg-glow-fade-height with the
      bottom variant. Use both classes together to fade both edges. */
.bg-glow.bg-glow-fade-top::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  height: var(--bg-glow-fade-height, 40%);
  z-index: 8;
  pointer-events: none;
  background: linear-gradient(to top, transparent, var(--bg-glow-fade-color, #0D0D18));
}


/* ── Content always above bg layers ─────────────────────────────── */
.bg-glow > *:not(.bg-layer):not(.bg-layer--blob1):not(.bg-layer--blob2):not(.bg-layer--ring1):not(.bg-layer--ring2):not(.bg-glow-tint):not(.bg-glow-grain) {
  position: relative;
  z-index: 9;
}


/* ── Reduced motion — kill all animations ──────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .bg-glow .bg-shape--blob1,
  .bg-glow .bg-shape--blob2,
  .bg-glow .bg-shape--ring1,
  .bg-glow .bg-shape--ring2 { animation: none; }
}


/* ── .bg-frosted: cohesive frosted-glass surface family.

   Recipe (shared across all variants):
     - solid color canvas
     - two off-frame radial blobs (top-right + bottom-left) with multi-stop
       Gaussian-ish falloff
     - feTurbulence grain layer via mix-blend-mode: overlay
     - barely-visible top-edge highlight ("glass bevel")

   Self-contained (no SVG / filter:blur), so it can sit inside
   3D-transformed elements like a flip-card face where filter on a
   child would break backface-visibility.

   Three CSS variables drive the palette:
     --bg-frosted-base   : the canvas color
     --bg-frosted-blob-a : the top-right blob
     --bg-frosted-blob-b : the bottom-left blob

   Variants below override those three vars and inherit everything else,
   matching the .bg-glow-1/2/3 pattern (base class + modifier).

   Usage:
     class="bg-frosted"                — default (periwinkle / aqua / coral)
     class="bg-frosted bg-frosted-aqua"
     class="bg-frosted bg-frosted-coral"
     class="bg-frosted bg-frosted-purple" */
.bg-frosted {
  /* Palette tokens — override in variants below. */
  --bg-frosted-base:   var(--c-periwinkle);
  --bg-frosted-blob-a: var(--c-aqua);
  --bg-frosted-blob-b: var(--c-coral);

  position: relative;
  isolation: isolate;
  overflow: hidden;
  color: var(--c-grey-10);

  background-color: var(--bg-frosted-base);
  background-image:
    radial-gradient(circle at 82% 12%,
      color-mix(in srgb, var(--bg-frosted-blob-a) 85%, transparent) 0%,
      color-mix(in srgb, var(--bg-frosted-blob-a) 55%, transparent) 18%,
      color-mix(in srgb, var(--bg-frosted-blob-a) 22%, transparent) 40%,
      color-mix(in srgb, var(--bg-frosted-blob-a) 6%,  transparent) 60%,
      transparent 78%
    ),
    radial-gradient(circle at -8% 108%,
      color-mix(in srgb, var(--bg-frosted-blob-b) 85%, transparent) 0%,
      color-mix(in srgb, var(--bg-frosted-blob-b) 55%, transparent) 20%,
      color-mix(in srgb, var(--bg-frosted-blob-b) 25%, transparent) 42%,
      color-mix(in srgb, var(--bg-frosted-blob-b) 8%,  transparent) 65%,
      transparent 85%
    );
}

.bg-frosted::before {
  /* grain — identical feTurbulence SVG to .bg-glow-grain */
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.22;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.5 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

.bg-frosted::after {
  /* top-edge highlight — barely-visible frosted-glass bevel */
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0) 12%);
}

.bg-frosted > * {
  position: relative;
  z-index: 1;
}

/* ── Variants — only the palette swaps. Composition, grain, highlight,
   and falloff stops all inherit from .bg-frosted. */

/* Aqua canvas, periwinkle + purple blobs. Fresh, jewel-toned.
   Mood: tech / interactive / data surfaces. */
.bg-frosted-aqua {
  --bg-frosted-base:   var(--c-aqua);
  --bg-frosted-blob-a: var(--c-periwinkle);
  --bg-frosted-blob-b: var(--c-purple-regular);
}

/* Coral canvas, aqua + periwinkle blobs. Warm sunset, energetic.
   Mood: CTAs / momentum / promotional surfaces. */
.bg-frosted-coral {
  --bg-frosted-base:   var(--c-coral);
  --bg-frosted-blob-a: var(--c-aqua);
  --bg-frosted-blob-b: var(--c-periwinkle);
}

/* Purple canvas, periwinkle + aqua blobs. Soft, dreamy.
   Mood: editorial / storytelling / case-study surfaces. */
.bg-frosted-purple {
  --bg-frosted-base:   var(--c-purple-regular);
  --bg-frosted-blob-a: var(--c-periwinkle);
  --bg-frosted-blob-b: var(--c-aqua);
}

/* ── Dark variants — built for WHITE text on top.
   Same recipe (grain, highlight, falloff) and the family's inherited
   near-white text color (--c-grey-10); only the canvas goes dark and the
   blobs use the brighter brand hues so they read as glows, not washes.
   The dark base is what gives white text its contrast. */

/* Charcoal-navy canvas, periwinkle + aqua glow. Versatile default dark. */
.bg-frosted-night {
  --bg-frosted-base:   var(--c-grey-02);
  --bg-frosted-blob-a: var(--c-periwinkle);
  --bg-frosted-blob-b: var(--c-aqua);
}

/* Deep purple canvas, purple + periwinkle glow. Editorial / premium. */
.bg-frosted-violet {
  --bg-frosted-base:   var(--c-purple-dark);
  --bg-frosted-blob-a: var(--c-purple-regular);
  --bg-frosted-blob-b: var(--c-periwinkle);
}

/* Deep teal canvas, aqua + periwinkle glow. Tech / data surfaces. */
.bg-frosted-ocean {
  --bg-frosted-base:   var(--c-blue-dark);
  --bg-frosted-blob-a: var(--c-aqua);
  --bg-frosted-blob-b: var(--c-periwinkle);
}

/* ── .bg-glass: true frosted-glass surface — backdrop blur + translucent
   tint + gradient sheen + feTurbulence grain + inner glow + hairline edge.

   Unlike .bg-frosted (opaque colored canvas), this blurs the content BEHIND
   it, so it needs real content/background behind the element to read.

   Composability (this class loads after _colors.css, so it would otherwise
   win every shorthand): the edge/glow/bevel are box-shadow layers and it sets
   no border or color — so b-*, bt-*, rounded-*, p-* and c-* all compose:
     class="bg-glass rounded-l p-xl b-aqua c-grey-01"

   Tinting: the tint IS the sheen color (a low-alpha sheen layered on top of
   the translucent --glass-fill body). Use the bg-glass-* variants below, or
   set inline: style="--glass-tint: var(--c-aqua)". Dial the sheen with
   --glass-sheen (default 8%) and the body with --glass-fill. Don't combine
   with the opaque bg-* classes — they'd cover the fill.
   Usage: class="bg-glass rounded-l p-xl"  /  class="bg-glass bg-glass-aqua" */
.bg-glass {
  position: relative;
  isolation: isolate;
  overflow: hidden;

  /* Tint = the sheen color; --glass-sheen = its strength. Only the gradient
     sheen is tinted (low alpha), so the panel stays glassy. Variants below
     just swap --glass-tint. */
  --glass-tint: var(--c-white);
  --glass-sheen: 8%;
  /* Translucent body — lets a moving/glow background show through (dimmed)
     instead of a backdrop-filter blur, which is a no-op over flat backgrounds
     and a per-frame repaint cost over an animated bg-glow. Tune per instance
     via --glass-fill: raise alpha to protect text, lower to reveal more glow. */
  --glass-fill: rgba(13, 13, 24, 0.64);
  background-color: var(--glass-fill);
  background-image: linear-gradient(135deg,
    transparent 0%,
    color-mix(in srgb, var(--glass-tint) var(--glass-sheen), transparent) 100%);

  /* Edge, inner glow and bevel are box-shadow layers, NOT the border
     property — so b-*, bt-*, rounded-* utilities compose cleanly on top.
     No color set here, so c-* utilities win for text. Held in a variable so
     hover utilities (.h-glow) can ADD a halo instead of replacing the stack —
     see the .bg-glass.h-glow rules in _interactions.css. */
  --glass-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.16),
    inset 0 0 28px 1px rgba(255, 255, 255, 0.1),
    inset 0 1px 0 0 rgba(255, 255, 255, 0.28),
    0 22px 48px rgba(0, 0, 0, 0.12);
  box-shadow: var(--glass-shadow);
}

.bg-glass::before {
  /* grain — feTurbulence noise, same recipe family as .bg-glow-grain */
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.18;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.5 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

.bg-glass > * { position: relative; z-index: 1; }

/* ── Tint variants — pair: class="bg-glass bg-glass-aqua". Each just swaps
   the sheen color; strength is the shared --glass-sheen (8%). */
.bg-glass-periwinkle { --glass-tint: var(--c-periwinkle); }
.bg-glass-aqua       { --glass-tint: var(--c-aqua); }
.bg-glass-coral      { --glass-tint: var(--c-coral); }
.bg-glass-purple     { --glass-tint: var(--c-purple-regular); }
.bg-glass-dark       { --glass-tint: var(--c-grey-01); }
.bg-glass-light      { --glass-tint: var(--c-white); }

/* ── Frost — the LIGHT panel variant. The base .bg-glass body is a dark
   translucent fill (--glass-fill: rgba(13,13,24,.64)) tuned for the dark
   theme / bg-glow; frost flips it to a bright translucent body so the card
   reads light — over the dark glow (colored light bleeds through the low
   opacity) or on a light bg-grey-10 body. The inset highlight stack is
   flipped too: white bevels vanish on a light panel, so the edge becomes a
   dark hairline (defines the shape on light) plus one bright top bevel, and
   the drop shadow is deepened to separate it from a light background.
   Sheen is off (white-on-white is invisible); pair a bg-glass-* tint after
   it to reintroduce a colored sheen. Like .bg-glass it sets no text color —
   add c-grey-01 for the (now required) dark text.
   Usage: class="bg-glass bg-glass-frost rounded-l p-xl c-grey-01" */
.bg-glass-frost {
  --glass-fill: rgba(255, 255, 255, 0.68);
  --glass-tint: var(--c-white);
  --glass-sheen: 0%;
  --glass-shadow:
    inset 0 0 0 1px rgba(13, 13, 24, 0.06),
    inset 0 1px 0 0 rgba(255, 255, 255, 0.9),
    0 12px 32px rgba(0, 0, 0, 0.1);
}

/* ── .icon-glow: soft radial bloom behind an icon or any element that
   needs an ambient color halo. Color is parameterized via
   --icon-glow-color (defaults to aqua); set it inline or via a
   wrapping class to recolor.

   Pairs naturally with .icon-slot (which provides position: relative
   + isolation: isolate). On any other host, the rule re-establishes
   those itself so the z-index: -1 pseudo stays scoped.
   Usage: class="icon-slot icon-glow"
       or class="icon-slot icon-glow" style="--icon-glow-color: var(--c-coral);" */
.icon-glow {
  position: relative;
  isolation: isolate;
}

.icon-glow::before {
  content: "";
  position: absolute;
  inset: -60%;
  z-index: -1;
  pointer-events: none;
  --_g: var(--icon-glow-color, var(--c-aqua));
  background: radial-gradient(circle at center,
    color-mix(in srgb, var(--_g) 28%, transparent) 0%,
    color-mix(in srgb, var(--_g) 14%, transparent) 25%,
    color-mix(in srgb, var(--_g) 5%, transparent)  48%,
    transparent 72%);
}

:root {
  --btn-font-size: clamp(0.75rem, 0.227vw + 0.693rem, 0.875rem);
  --btn-font-weight: 400;

  --btn-radius: 999px;
  --btn-padding-y: var(--spacing-2xs);
  --btn-padding-x: var(--spacing-l);
  --btn-shadow: 0 0 0 var(--c-periwinkle) / 0%;
  --btn-shadow-hover: 0 16px 32px rgba(72, 100, 255, 0.12);
  --btn-transition: 200ms ease;
}

/* ── Anchors ──────────────────────────────────────────────────── */

a {
  cursor: pointer;
  color: inherit;
  margin: 0;
  font-size: var(--btn-font-size);
}

.link {
  text-decoration: none;
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  transition: all 200ms ease;
}

.link-text {
  transition: all 200ms ease;
}

.link-icon-1 {
  margin-left: var(--spacing-xs);
  transition: transform 200ms ease;
}

.link:hover .link-icon-1 {
  transform: translateX(var(--spacing-4xs));
}

.link-text-2 {
  transform: translateX(0);
  transition: transform 200ms ease;
}

.link:hover .link-text-2 {
  transform: translateX(24px);
}

.link-icon-2 {
  margin: 0;
  opacity: 0;
  width: 0;
  transition: all 400ms ease;
}

.link:hover .link-icon-2 {
  opacity: 1;
  transform: translateX(0);
}

.link-secondary {
  color: inherit;
}

.link-secondary:hover {
  color: var(--c-periwinkle-light);
}

/* ── Buttons ──────────────────────────────────────────────────────
 *
 * Composition: btn + type + (optional) color + (optional) btn-arrow
 *
 *   <a class="btn">…</a>                                 default primary
 *   <a class="btn btn-primary">…</a>                     primary (explicit)
 *   <a class="btn btn-secondary">…</a>                   transparent + border
 *   <a class="btn btn-primary btn-coral">…</a>           coral filled
 *   <a class="btn btn-secondary btn-aqua">…</a>          aqua-bordered, fills on hover
 *   <a class="btn btn-primary btn-arrow">…</a>           with right-side arrow circle
 *
 * The system is token-based: type classes consume CSS custom properties
 * (--btn-bg, --btn-text, --btn-border, and their *-hover variants); color
 * modifier classes override those tokens. Each color has a special-case
 * rule for .btn-secondary because secondary fills with the color on hover
 * (rather than swapping to white like primary does).
 *
 * Per-instance overrides still work — drop a style="--btn-bg: red" on any
 * element for a one-off color.
 * ──────────────────────────────────────────────────────────────────── */

.button,
.hs-button,
.btn {
  /* Defaults — periwinkle pill that swaps to aqua on hover. These tokens
     are what the color modifier classes below override. */
  --btn-bg:           var(--c-periwinkle);
  --btn-bg-hover:     var(--c-aqua);
  --btn-text:         var(--c-white);
  --btn-text-hover:   var(--c-black);
  --btn-border:       transparent;
  --btn-border-hover: transparent;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.04em;

  padding: var(--btn-padding-y) var(--btn-padding-x);
  border-radius: var(--btn-radius);
  border: 1px solid var(--btn-border);
  outline: none;

  background-color: var(--btn-bg);
  color: var(--btn-text);
  font-size: var(--btn-font-size);
  font-weight: var(--btn-font-weight);

  cursor: pointer;
  box-shadow: var(--btn-shadow);
  transform: translateY(0);

  transition:
    background-color var(--btn-transition),
    color var(--btn-transition),
    border-color var(--btn-transition),
    box-shadow var(--btn-transition),
    transform var(--btn-transition);
}

.button:hover,
.hs-button:hover,
.btn:hover {
  background-color: var(--btn-bg-hover);
  color: var(--btn-text-hover);
  border-color: var(--btn-border-hover);
  box-shadow: var(--btn-shadow-hover);
  transform: translateY(-2px);
}

.button:active,
.hs-button:active,
.btn:active {
  transform: translateY(0);
}

.button:focus-visible,
.hs-button:focus-visible,
.btn:focus-visible {
  outline: 2px solid var(--c-grey-07);
  outline-offset: 2px;
}

.button[disabled],
.hs-button[disabled],
.btn[disabled],
.btn.is-disabled {
  opacity: 0.6;
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}

/* FA icons sit slightly below the cap-height center of uppercase button
   text. Nudge them up to optically center. Matches both <i class="fa-…">
   (webfont mode) and the .svg-inline--fa SVG injected by the kit. */
.button .fa-solid,        .button .fa-regular,        .button .fa-brands,        .button .fa-light,        .button .fa-thin,        .button .fa-sharp,        .button .svg-inline--fa,
.hs-button .fa-solid,     .hs-button .fa-regular,     .hs-button .fa-brands,     .hs-button .fa-light,     .hs-button .fa-thin,     .hs-button .fa-sharp,     .hs-button .svg-inline--fa,
.btn .fa-solid,           .btn .fa-regular,           .btn .fa-brands,           .btn .fa-light,           .btn .fa-thin,           .btn .fa-sharp,           .btn .svg-inline--fa,
.link .fa-solid,          .link .fa-regular,          .link .fa-brands,          .link .fa-light,          .link .fa-thin,          .link .fa-sharp,          .link .svg-inline--fa {
  transform: translateY(-1px);
}

/* ── Type variants ──
   btn-primary is the implicit default; the explicit class is provided so
   markup reads consistently. btn-secondary inverts to a bordered transparent
   pill — its color tokens differ because secondary's "color" is its border,
   not its background. */

.btn-primary {
  /* Inherits defaults from the base button rule. Listed here for clarity
     and to give markup an explicit class to opt back into primary if it's
     also receiving btn-secondary from another source. */
}

.btn-secondary {
  --btn-bg:           transparent;
  --btn-bg-hover:     transparent;
  --btn-text:         var(--c-grey-09);
  --btn-text-hover:   var(--c-grey-09);
  --btn-border:       var(--c-grey-07);
  --btn-border-hover: var(--c-aqua);
}

/* ── Color modifiers ──
   Each color sets the same set of tokens. The .btn-secondary.btn-{color}
   override flips the hover pattern so secondary fills with the color on
   hover instead of swapping to white. */

/* periwinkle — same hue as the default, but explicit. Useful on secondary
   to get a periwinkle-bordered button that fills with periwinkle on hover. */
.btn-periwinkle {
  --btn-bg:           var(--c-periwinkle);
  --btn-bg-hover:     var(--c-white);
  --btn-text:         var(--c-white);
  --btn-text-hover:   var(--c-periwinkle);
  --btn-border:       var(--c-periwinkle);
  --btn-border-hover: var(--c-periwinkle);
}
.btn-secondary.btn-periwinkle {
  --btn-bg:           transparent;
  --btn-bg-hover:     var(--c-periwinkle);
  --btn-text:         var(--c-periwinkle);
  --btn-text-hover:   var(--c-white);
}

/* coral */
.btn-coral {
  --btn-bg:           var(--c-coral);
  --btn-bg-hover:     var(--c-white);
  --btn-text:         var(--c-white);
  --btn-text-hover:   var(--c-coral);
  --btn-border:       var(--c-coral);
  --btn-border-hover: var(--c-coral);
}
.btn-secondary.btn-coral {
  --btn-bg:           transparent;
  --btn-bg-hover:     var(--c-coral);
  --btn-text:         var(--c-coral);
  --btn-text-hover:   var(--c-white);
}

/* aqua */
.btn-aqua {
  --btn-bg:           var(--c-aqua);
  --btn-bg-hover:     var(--c-white);
  --btn-text:         var(--c-black);
  --btn-text-hover:   var(--c-aqua);
  --btn-border:       var(--c-aqua);
  --btn-border-hover: var(--c-aqua);
}
.btn-secondary.btn-aqua {
  --btn-bg:           transparent;
  --btn-bg-hover:     var(--c-aqua);
  --btn-text:         var(--c-aqua);
  --btn-text-hover:   var(--c-black);
}

/* purple */
.btn-purple {
  --btn-bg:           var(--c-purple-regular);
  --btn-bg-hover:     var(--c-white);
  --btn-text:         var(--c-white);
  --btn-text-hover:   var(--c-purple-regular);
  --btn-border:       var(--c-purple-regular);
  --btn-border-hover: var(--c-purple-regular);
}
.btn-secondary.btn-purple {
  --btn-bg:           transparent;
  --btn-bg-hover:     var(--c-purple-regular);
  --btn-text:         var(--c-purple-regular);
  --btn-text-hover:   var(--c-white);
}

/* white — for use on dark surfaces */
.btn-white {
  --btn-bg:           var(--c-white);
  --btn-bg-hover:     var(--c-black);
  --btn-text:         var(--c-black);
  --btn-text-hover:   var(--c-white);
  --btn-border:       var(--c-white);
  --btn-border-hover: var(--c-white);
}
.btn-secondary.btn-white {
  --btn-bg:           transparent;
  --btn-bg-hover:     var(--c-white);
  --btn-text:         var(--c-white);
  --btn-text-hover:   var(--c-black);
}

/* black */
.btn-black {
  --btn-bg:           var(--c-black);
  --btn-bg-hover:     var(--c-white);
  --btn-text:         var(--c-white);
  --btn-text-hover:   var(--c-black);
  --btn-border:       var(--c-black);
  --btn-border-hover: var(--c-black);
}
.btn-secondary.btn-black {
  --btn-bg:           transparent;
  --btn-bg-hover:     var(--c-black);
  --btn-text:         var(--c-black);
  --btn-text-hover:   var(--c-white);
}

/* ── btn-arrow ──
   Self-contained right-side accent: black circle with a coral arrow that
   rotates 45° → 0° on hover. Implemented as a ::after pseudo-element with
   an inline SVG data URI so it works on any button without per-module
   markup. No HubL conditional required.
   ────────────────────────────────────────────────────────────── */

.btn-arrow {
  position: relative;
  padding-right: 2.75em;
}

.btn-arrow::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  aspect-ratio: 1;
  box-sizing: border-box;
  border-radius: 999px;
  border: 2px solid var(--btn-bg);
  background-color: var(--c-black);
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%23FF815C" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>');
  background-repeat: no-repeat;
  background-position: center;
  background-size: 45%;
  transform: rotate(45deg);
  transition: transform var(--btn-transition), border-color var(--btn-transition);
}

.btn-arrow:hover::after {
  transform: rotate(0deg);
  border-color: var(--btn-bg-hover);
}

/* btn-arrow is primary-only — secondary buttons drop the circle and the
   reserved right-side padding. */
.btn-secondary.btn-arrow {
  padding-right: var(--btn-padding-x);
}

.btn-secondary.btn-arrow::after {
  display: none;
}

/* ── Button Group ── */

.btn-group {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--spacing-s);
}

/* ── Chips ──────────────────────────────────────────────────────
 *
 * Composition: chip + (optional) color
 *
 *   <span class="chip">…</span>                 default — grey border, grey-07 text
 *   <span class="chip chip-coral">…</span>      coral border + coral text
 *   <span class="chip chip-aqua">…</span>       aqua border + aqua text
 *
 * Token-based like buttons. Color modifier classes override --chip-bg,
 * --chip-text, --chip-border (+ -hover variants). Per-instance overrides
 * still work — drop style="--chip-border: red" on any element for a one-off.
 * Chips are bordered-only by default (no filled variant); for a filled chip
 * set --chip-bg via inline style or a project-local class.
 * ──────────────────────────────────────────────────────────────────── */

.chip {
  --chip-bg:           transparent;
  --chip-bg-hover:     transparent;
  --chip-text:         var(--c-grey-07);
  /* Hover text follows the chip's own text color (resolved lazily at use, so
     color modifiers below that only set --chip-text carry through to hover).
     Override per-instance/variant if a distinct hover text is ever needed. */
  --chip-text-hover:   var(--chip-text);
  --chip-border:       var(--c-grey-04);
  --chip-border-hover: var(--c-aqua);

  text-decoration: none;
  display: inline-flex;
  flex-direction: row;
  padding: var(--spacing-4xs) var(--spacing-m);
  border-radius: var(--btn-radius);

  background-color: var(--chip-bg);
  color: var(--chip-text);
  border: 1px solid var(--chip-border);

  font-size: var(--btn-font-size);
  text-transform: uppercase;
  letter-spacing: 0.04em;

  transition:
    background-color var(--btn-transition),
    color var(--btn-transition),
    border-color var(--btn-transition);
}

.chip:hover {
  background-color: var(--chip-bg-hover);
  color: var(--chip-text-hover);
  border-color: var(--chip-border-hover);
}

/* ── Color modifiers ──
   Tint the border and text. Setting --chip-text also drives the hover text
   (see --chip-text-hover above), and --chip-border-hover keeps the same color
   on hover (no swap to aqua like the default chip does) — so colored chips
   stay fully on-brand on hover. */

.chip-periwinkle {
  --chip-text:         var(--c-periwinkle);
  --chip-border:       var(--c-periwinkle);
  --chip-border-hover: var(--c-periwinkle);
}

.chip-coral {
  --chip-text:         var(--c-coral);
  --chip-border:       var(--c-coral);
  --chip-border-hover: var(--c-coral);
}

.chip-aqua {
  --chip-text:         var(--c-aqua);
  --chip-border:       var(--c-aqua);
  --chip-border-hover: var(--c-aqua);
}

.chip-purple {
  --chip-text:         var(--c-purple-regular);
  --chip-border:       var(--c-purple-regular);
  --chip-border-hover: var(--c-purple-regular);
}

.chip-white {
  --chip-text:         var(--c-white);
  --chip-border:       var(--c-white);
  --chip-border-hover: var(--c-white);
}

.chip-black {
  --chip-text:         var(--c-black);
  --chip-border:       var(--c-black);
  --chip-border-hover: var(--c-black);
}

/* Sections */

.section {
  padding-left: var(--spacing-l);
  padding-right: var(--spacing-l);
  scroll-margin-top: 100px;
}

/* Containers */

.container-s {
  margin: auto;
  max-width: 48rem;
}
.container-m {
  margin: auto;
  max-width: 64rem;
}
.container-l {
  margin: auto;
  max-width: 80rem;
}

.container-full {
  margin: auto;
  max-width: 100%;
}

/* Wrapper */

.wrapper {
  width: 100%;
}

.logo-wrapper {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: var(--spacing-xl);
  height: var(--spacing-xl);
}

.logo-wrapper img{
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.logo {
  width: auto;
  height: var(--spacing-xl);
}

/* Logo cell — fixed-frame slot for normalizing logo display in
   carousels, sliders, or grids. Inner <img> / <svg> sizes to fit
   without distortion. Override --logo-cell-w / --logo-cell-h
   inline or via a modifier class to resize per-context. */

.logo-cell {
  --logo-cell-w: var(--spacing-8xl);
  --logo-cell-h: var(--spacing-3xl);
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--logo-cell-w);
  height: var(--logo-cell-h);
  padding: var(--spacing-2xs) var(--spacing-s);
  box-sizing: border-box;
  flex-shrink: 0;
}

.logo-cell-s {
  --logo-cell-w: var(--spacing-6xl);
  --logo-cell-h: var(--spacing-2xl);
}

.logo-cell-l {
  --logo-cell-w: calc(var(--spacing-8xl) + var(--spacing-3xl));
  --logo-cell-h: var(--spacing-4xl);
}

.logo-cell img,
.logo-cell svg {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* Card width utilities — fixed slide/card widths. Global (NOT module-scoped)
   so they apply on every page regardless of which modules are present. Used by
   slider-horizontal cards (.slider-card) and slider-carousel slides
   (.marquee-slide), set per-slide via the Slide Style field. Each module's
   mobile override (cards → near-full-width) stays in that module's own CSS. */

.card-w-xs  { width: 14rem; }
.card-w-s   { width: 18rem; }
.card-w-m   { width: 22rem; }
.card-w-l   { width: 28rem; }
.card-w-xl  { width: 34rem; }
.card-w-2xl { width: 40rem; }
.card-w-3xl { width: 48rem; }
.card-w-4xl { width: 56rem; }

/* Content-hugging slide — width follows the slide's own content instead of a
   fixed card size. For marquees of small, mixed-width items (logos, badges)
   where a fixed card-w-* leaves large empty gaps; spacing is then controlled
   entirely by the carousel gap. The card-w- prefix also opts out of the
   slider-carousel fallback min-width. */
.card-w-auto { width: max-content; }

/* Badge — fixed-width image slot. Width is set by the size variant; height
   auto-derives from the image's intrinsic aspect ratio so badges never
   distort. flex-shrink: 0 keeps them sized correctly in tight flex rows. */

.badge {
  --badge-w: var(--spacing-6xl);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--badge-w);
  flex-shrink: 0;
}

.badge-xs { --badge-w: var(--spacing-3xl); }
.badge-s  { --badge-w: var(--spacing-4xl); }
.badge-m  { --badge-w: var(--spacing-6xl); }
.badge-l  { --badge-w: var(--spacing-8xl); }

@media (max-width: 991px) {
  .badge-xs { --badge-w: var(--spacing-2xl); }
  .badge-s  { --badge-w: var(--spacing-3xl); }
  .badge-m  { --badge-w: var(--spacing-4xl); }
  .badge-l  { --badge-w: var(--spacing-6xl); }
}

.badge img,
.badge svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Optional fixed-height slot. Pair with a badge size (width); the image
   scales to fit inside the box, centered, preserving its aspect ratio — so
   cards whose source images have different aspect ratios align vertically.
   Opt-in: the object-fit override is scoped to badge-h-* so plain badges
   (logo rows, tight flex) keep their intrinsic auto-height behaviour. */

.badge-h-xs { height: var(--spacing-4xl); }
.badge-h-s  { height: var(--spacing-5xl); }
.badge-h-m  { height: var(--spacing-6xl); }
.badge-h-l  { height: var(--spacing-8xl); }

.badge[class*="badge-h-"] img,
.badge[class*="badge-h-"] svg {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Height-driven badge — locks the slot HEIGHT and lets WIDTH follow the image's
   aspect ratio (the inverse of plain .badge, which locks width). For badge rows
   that mix square and wide logos sharing a common source height, so they align
   on one baseline instead of a common width. The height reuses the badge-size
   scale (--badge-w set by badge-xs/s/m/l), so `badge badge-s badge-fluid`
   locks to the small size and stays in step with the square badges beside it. */
.badge-fluid { width: auto; height: var(--badge-w); }
.badge-fluid img,
.badge-fluid svg { width: auto; height: 100%; }

/* Icon slot — fixed-size frame for inline icons (SVG or image). Sibling
   to .logo-cell / .badge. Sized by --icon-slot-w / --icon-slot-h so it
   can be re-themed in place; position: relative + isolation: isolate so
   companion utilities like .icon-glow can use ::before z-index: -1
   without falling behind ancestor backgrounds. Inherits currentColor,
   so any `c-*` color class on the slot tints stroke='currentColor'
   SVGs to brand. */

.icon-slot {
  --icon-slot-w: var(--spacing-2xl);
  --icon-slot-h: var(--spacing-2xl);
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-slot-w);
  height: var(--icon-slot-h);
  flex-shrink: 0;
}

.icon-slot-s { --icon-slot-w: var(--spacing-xl);  --icon-slot-h: var(--spacing-xl);  }
.icon-slot-m { --icon-slot-w: var(--spacing-2xl); --icon-slot-h: var(--spacing-2xl); }
.icon-slot-l { --icon-slot-w: var(--spacing-4xl); --icon-slot-h: var(--spacing-4xl); }

.icon-slot svg,
.icon-slot img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* Dividers */

.v-line {
  width: 1px;
  height: var(--spacing-xl);
  background-color: var(--c-purple-medium);
}

.h-line {
  width: var(--spacing-xl);
  height: 1px;
  background-color: var(--c-purple-medium);
}

/* Grid */

.g-cols-12 {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 1fr));
}
.g-rows-12 {
  display: grid;
  grid-template-rows: repeat(1, minmax(0, 1fr));
}

@media (min-width: 991px) {
  .g-cols-12 {
    grid-template-columns: repeat(12, minmax(0, 1fr));
  }
  .g-rows-12 {
    grid-template-rows: repeat(12, minmax(0, 1fr));
  }
}

/* Grid Column Span */

.g-col-span-1,
.g-col-span-2,
.g-col-span-3,
.g-col-span-4,
.g-col-span-5,
.g-col-span-6,
.g-col-span-7,
.g-col-span-8,
.g-col-span-9,
.g-col-span-10,
.g-col-span-11,
.g-col-span-12 {
  grid-column: span 1 / span 1;
}

@media (min-width: 991px) {
  .g-col-span-1 {
    grid-column: span 1 / span 1;
  }
  .g-col-span-2 {
    grid-column: span 2 / span 2;
  }
  .g-col-span-3 {
    grid-column: span 3 / span 3;
  }
  .g-col-span-4 {
    grid-column: span 4 / span 4;
  }
  .g-col-span-5 {
    grid-column: span 5 / span 5;
  }
  .g-col-span-6 {
    grid-column: span 6 / span 6;
  }
  .g-col-span-7 {
    grid-column: span 7 / span 7;
  }
  .g-col-span-8 {
    grid-column: span 8 / span 8;
  }
  .g-col-span-9 {
    grid-column: span 9 / span 9;
  }
  .g-col-span-10 {
    grid-column: span 10 / span 10;
  }
  .g-col-span-11 {
    grid-column: span 11 / span 11;
  }
  .g-col-span-12 {
    grid-column: span 12 / span 12;
  }
}

/* Grid Row Span */

.g-row-span-1,
.g-row-span-2,
.g-row-span-3,
.g-row-span-4,
.g-row-span-5,
.g-row-span-6,
.g-row-span-7,
.g-row-span-8,
.g-row-span-9,
.g-row-span-10,
.g-row-span-11,
.g-row-span-12 {
  grid-row: span 1 / span 1;
}

@media (min-width: 640px) {
  .g-row-span-1 {
    grid-row: span 1 / span 1;
  }
  .g-row-span-2 {
    grid-row: span 2 / span 2;
  }
  .g-row-span-3 {
    grid-row: span 3 / span 3;
  }
  .g-row-span-4 {
    grid-row: span 4 / span 4;
  }
  .g-row-span-5 {
    grid-row: span 5 / span 5;
  }
  .g-row-span-6 {
    grid-row: span 6 / span 6;
  }
  .g-row-span-7 {
    grid-row: span 7 / span 7;
  }
  .g-row-span-8 {
    grid-row: span 8 / span 8;
  }
  .g-row-span-9 {
    grid-row: span 9 / span 9;
  }
  .g-row-span-10 {
    grid-row: span 10 / span 10;
  }
  .g-row-span-11 {
    grid-row: span 11 / span 11;
  }
  .g-row-span-12 {
    grid-row: span 12 / span 12;
  }
}

.grid-strech {
  justify-self: stretch;
}

/* Order */

.g-order-2 {
  order: 2;
}

@media (min-width: 991px) {
  .g-order-2 {
    order: 0;
  }
}

/* Step card & badge — sequential process flow ("How it works" pattern).
   Apply .step-card to each card; a dashed connector draws in the gap
   to the LEFT of every step-card except the first, visually linking
   adjacent steps. .step-badge styles a numbered pill (01, 02, …)
   sitting at the top of each card. */

.step-card {
  position: relative;
}

.step-card + .step-card::before {
  content: '';
  position: absolute;
  top: calc(var(--spacing-l) + 28px); /* card padding + half badge height */
  left: calc(-1 * var(--spacing-l));   /* extend left into the gap */
  width: var(--spacing-l);              /* span the full gap */
  border-top: 2px dashed var(--c-grey-04);
  z-index: 0;
  pointer-events: none;
}

@media (max-width: 991px) {
  .step-card + .step-card::before { display: none; }
}

.step-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background-color: var(--c-periwinkle);
  color: var(--c-white);
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  position: relative;
  z-index: 1; /* sit on top of the dashed line */
}

/* Minimal text variant of .step-badge — no filled circle, no bold,
   absolutely positioned to the top-left of a `position: relative` host
   (e.g. a card face). Pair with a typography class (h6, etc.) on the
   element to control text size/weight. */
.step-badge-minimal {
  position: absolute;
  top: var(--spacing-l);
  left: var(--spacing-l);
  z-index: 1;
  pointer-events: none;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
}

/* Icon Boxes */

.box-xs {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--spacing-4xs);
  width: var(--spacing-xl);
  height: var(--spacing-xl);
  aspect-ratio: 1 /1;
}

.box-s {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--spacing-4xs);
  width: var(--spacing-2xl);
  height: var(--spacing-2xl);
  aspect-ratio: 1 /1;
}

.box-m {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--spacing-4xs);
  width: var(--spacing-3xl);
  height: var(--spacing-3xl);
  aspect-ratio: 1 /1;
}

/* Border radius */

.rounded-s {
  border-radius: var(--spacing-4xs);
}

.rounded-m {
  border-radius: var(--spacing-3xs);
}

.rounded-l {
  border-radius: var(--spacing-2xs);
}


/* Flex */

.flex-column {
  display: flex;
  flex-direction: column;
}

.flex-row {
  display: flex;
  flex-direction: row;
}

.justify-between {
  justify-content: space-between;
}

.justify-center {
  justify-content: center;
}

.justify-end {
  justify-content: end;
}

/* Desktop-only end-alignment — flips to start on mobile (≤991px).
   Useful for right-aligned button groups that should hug the left edge
   when the layout collapses to one column. */
.justify-end-desktop {
  justify-content: start;
}

@media (min-width: 991px) {
  .justify-end-desktop {
    justify-content: end;
  }
}

.align-end {
  align-items: end;
}

.align-center {
  align-items: center;
}

.align-start {
  align-items: start;
}

.align-stretch {
  align-items: stretch;
}

.flex-wrap {
  flex-wrap: wrap;
}

.flex-nowrap {
  flex-wrap: nowrap;
}

.flex-grow {
  flex-grow: 1;
}

/* Sizing — numeric = percentage, matching the iframe-w-* convention. */

.w-100 {
  width: 100%;
}

.h-100 {
  height: 100%;
}

/* =================================================================
   Sticky — pins a grid/flex child to the top while a taller sibling
   in the same row scrolls past (e.g. a section-builder title column
   beside a long description column).

   Self-sufficient: also sets align-self: start so the item shrinks to
   its content instead of stretching to the row height — a stretched
   item has zero scroll travel and would never appear to "stick". Drop
   `sticky` on the short column; no container change needed.

   top offset defaults to 100px to clear the fixed 72px header (matches
   .section's scroll-margin-top). Override per-instance:
     style="--sticky-top: 140px"

   Desktop-only (≥991px): below that, .g-cols-12 collapses to one column
   and items stack — a sticky title would pin over its own body text and
   read as a bug. No-op on mobile, mirroring .card-align.
   ================================================================= */

@media (min-width: 991px) {
  .sticky {
    position: sticky;
    top: var(--sticky-top, 100px);
    align-self: start;
  }
}

/* =================================================================
   Card alignment (opt-in, per card).

   Add .card-align to each card in a row that should share vertical
   rhythm. Each card:
     - becomes a flex column
     - reserves space for up to 2 lines of title (so 1-line titles
       still take the height of a 2-line title)
     - reserves space for up to 2 lines of description
     - bottom-anchors the links / button group

   Result: sibling cards with .card-align line up at title row,
   description row, and link row, without touching the parent grid
   or affecting any sibling that omits the class. Adding the class
   to a card has zero impact on its neighbors — safe to drop into
   any section-builder / slider / custom layout.

   Tune via CSS variables on the card:
     style="--card-title-lines: 3"   (e.g. for a row with longer titles)
     style="--card-desc-lines: 4"

   Scoped to ≥992px because on mobile cards stack full-width and
   the reserved empty lines read as layout bugs. On mobile the
   class is a no-op and cards flow naturally.
   ================================================================= */

@media (min-width: 992px) {
  .card-align {
    --card-title-lines: 2;
    --card-desc-lines: 2;
    display: flex;
    flex-direction: column;
  }
  .card-align > .title-section {
    min-height: calc(var(--card-title-lines) * 1lh);
  }
  .card-align > .description-section {
    min-height: calc(var(--card-desc-lines) * 1lh);
  }
  .card-align > .links-section,
  .card-align > .btn-group {
    margin-top: auto;
  }
}

:root {
    --hsf-global__font-family: inherit;
    --hsf-global__font-size: clamp(0.75rem, 0.227vw + 0.693rem, 0.875rem);
    --hsf-global__color: var(--c-grey-09);
    --hsf-global-error__color: var(--c-coral);

    --hsf-button__font-size: clamp(0.875rem, 0.227vw + 0.818rem, 1rem);
    --hsf-button__background-color: var(--c-periwinkle);
    --hsf-button__border-radius: 999px;
    --hsf-button__padding: var(--spacing-2xs) var(--spacing-l);

    --hsf-field-label__color: var(--c-grey-07);
    --hsf-field-input__color: var(--c-grey-09);
    --hsf-field-input__background-color: var(--c-grey-02);
    --hsf-field-input__placeholder-color: var(--c-grey-05);
    --hsf-field-input__border-color: var(--c-grey-04);
    --hsf-field-input__border-color-focus: var(--c-periwinkle);
    --hsf-field-input__border-width: 1px;
    --hsf-field-input__border-radius: 10px;
    --hsf-field-input__padding: var(--spacing-s) var(--spacing-m);
    --hsf-field-input__focus-ring: 0 0 0 3px rgba(72, 100, 255, 0.22);
}

/* Form root */

form {
  color: var(--hsf-global__color);
  font-family: var(--hsf-global__font-family);
  font-size: var(--hsf-global__font-size);
}

form fieldset {
  border: 0;
  padding: 0;
  margin: 0;
  max-width: 100% !important;
}

/* Full-width fields must reach the container's right edge. HubSpot's default form
   CSS renders `.form-columns-1` inputs at ~95% and leaves the 2-column gutter margin
   on their `.input` wrapper, so they stop ~34px short (the 2-column fields are fine). */
form .form-columns-1 .hs-input { width: 100% !important; }
form .form-columns-1 .input { margin-right: 0 !important; }

/* Fields */

.hs-form-field {
  margin-bottom: var(--spacing-l);
}

/* Labels */

form label {
  display: block;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--hsf-field-label__color);
  margin-bottom: var(--spacing-2xs);
}

/* Form Title */
.form-title {
  margin-bottom: var(--spacing-m);
}

/* Help text & legends */

form legend,
.hs-field-desc {
  font-size: 0.75rem;
  color: var(--c-grey-06);
  margin-bottom: var(--spacing-2xs);
}

/* Inputs */

form input[type=text],
form input[type=search],
form input[type=email],
form input[type=password],
form input[type=tel],
form input[type=number],
form input[type=url],
form input[type=date],
form input[type=time],
form input[type=file],
form select,
form textarea,
.hs-input {
  display: block;
  width: 100%;
  font-family: inherit;
  font-size: var(--hsf-global__font-size);
  color: var(--hsf-field-input__color);
  background-color: var(--hsf-field-input__background-color);
  border: var(--hsf-field-input__border-width) solid var(--hsf-field-input__border-color);
  border-radius: var(--hsf-field-input__border-radius);
  padding: var(--hsf-field-input__padding);
  transition: border-color 200ms ease, box-shadow 200ms ease, background-color 200ms ease;
  appearance: none;
  -webkit-appearance: none;
}

form input::placeholder,
form textarea::placeholder,
.hs-input::placeholder {
  color: var(--hsf-field-input__placeholder-color);
  opacity: 1;
}

form input:hover,
form select:hover,
form textarea:hover,
.hs-input:hover {
  border-color: var(--c-grey-05);
}

form input:focus,
form select:focus,
form textarea:focus,
.hs-input:focus,
.hs-input:focus-visible {
  outline: none;
  border-color: var(--hsf-field-input__border-color-focus);
  box-shadow: var(--hsf-field-input__focus-ring);
}

form textarea {
  resize: vertical;
  min-height: 120px;
  line-height: 1.5;
}

/* Select chevron */

form select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'><path d='M1 1.5L6 6.5L11 1.5' stroke='%23A3A4BF' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--spacing-m) center;
  padding-right: calc(var(--spacing-m) * 2 + 12px);
}

/* Inputs - checkbox & radio */

form .inputs-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2xs);
}

form .inputs-list > li {
  display: block;
  margin: 0;
}

form .inputs-list label {
  display: inline-flex;
  align-items: center;
  gap: var(--spacing-2xs);
  margin: 0;
  cursor: pointer;
  color: var(--c-grey-08);
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
}

form input[type=checkbox],
form input[type=radio] {
  appearance: none;
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  margin: 0;
  background-color: var(--c-grey-02);
  border: 1px solid var(--c-grey-04);
  cursor: pointer;
  position: relative;
  transition: border-color 150ms ease, background-color 150ms ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

form input[type=checkbox] {
  border-radius: 4px;
}

form input[type=radio] {
  border-radius: 999px;
}

form input[type=checkbox]:hover,
form input[type=radio]:hover {
  border-color: var(--c-grey-06);
}

form input[type=checkbox]:checked,
form input[type=radio]:checked {
  background-color: var(--c-periwinkle);
  border-color: var(--c-periwinkle);
}

form input[type=checkbox]:checked::after {
  content: "";
  width: 4px;
  height: 8px;
  border: solid var(--c-white);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) translate(-1px, -1px);
}

form input[type=radio]:checked::after {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background-color: var(--c-white);
}

form input[type=checkbox]:focus-visible,
form input[type=radio]:focus-visible {
  outline: none;
  box-shadow: var(--hsf-field-input__focus-ring);
}

/* Inputs - date picker */

.hs-dateinput {
  position: relative;
}

.hs-dateinput:before {
  content: '\01F4C5';
  position: absolute;
  right: var(--spacing-m);
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
}

.fn-date-picker .pika-table thead th {
  color: var(--c-grey-09);
}

.fn-date-picker td.is-selected .pika-button {
  background-color: var(--c-periwinkle);
  color: var(--c-white);
}

.fn-date-picker td .pika-button:hover,
.fn-date-picker td .pika-button:focus {
  background-color: var(--c-grey-03);
  color: var(--c-grey-09);
}

/* Inputs - file picker */

form input[type=file] {
  background-color: transparent;
  border: 1px dashed var(--c-grey-04);
  padding: var(--spacing-m);
  cursor: pointer;
}

form input[type=file]::file-selector-button {
  font-family: inherit;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background-color: var(--c-grey-03);
  color: var(--c-grey-09);
  border: 0;
  padding: var(--spacing-2xs) var(--spacing-m);
  border-radius: 999px;
  margin-right: var(--spacing-m);
  cursor: pointer;
  transition: background-color 200ms ease;
}

form input[type=file]::file-selector-button:hover {
  background-color: var(--c-grey-04);
}

/* Headings and richtext */

form .hs-richtext,
form .hs-richtext p {
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--c-grey-07);
  margin: 0 0 var(--spacing-m);
}

form .hs-richtext img {
  max-width: 100% !important;
}

/* GDPR */

.legal-consent-container {
  font-size: 0.75rem;
  color: var(--c-grey-06);
  line-height: 1.55;
}

.legal-consent-container .hs-form-booleancheckbox-display > span,
.legal-consent-container .hs-form-booleancheckbox-display > span p {
  margin-left: var(--spacing-s) !important;
  color: var(--c-grey-07);
}

/* Validation */

.hs-form-required {
  color: var(--c-coral);
  margin-left: 4px;
}

.hs-input.invalid.error,
.hs-input.invalid {
  border-color: var(--c-coral);
}

.hs-input.invalid.error:focus,
.hs-input.invalid:focus {
  box-shadow: 0 0 0 3px rgba(255, 129, 92, 0.22);
}

/* `.hs-error-msgs .hs-error-msg` (0,2,0) is needed to beat `form .inputs-list
   label` (0,1,2) above — HubSpot renders errors as a label inside a ul that also
   carries .inputs-list, so without this the error text inherits the grey list-
   label color instead of the error color (on both themes). */
.hs-error-msg,
.hs-error-msgs label,
.hs-error-msgs .hs-error-msg {
  color: var(--hsf-global-error__color);
  font-size: 0.75rem;
  margin-top: var(--spacing-2xs);
  display: block;
}

/* Submit button — base styling lives in _buttons.css via .hs-button */

form input[type=submit],
form .hs-button {
  cursor: pointer;
  display: inline-flex;
  text-align: center;
  white-space: normal;
}

.hs_submit {
  margin-top: var(--spacing-l);
}

/* Captcha */

.grecaptcha-badge {
  margin: 0 auto;
}

/* Search input — these rules only apply when HubSpot renders the v1 search field on the page. */

.body-container-wrapper .hs-search-field__button {
  padding: var(--spacing-s) var(--spacing-m);
}

.body-container-wrapper .hs-search-field__bar--button-inline .hs-search-field__button {
  margin-left: 6px;
  margin-bottom: 0;
}

.body-container-wrapper .hs-search-field__button svg {
  height: 15px;
  fill: var(--c-white);
}

.body-container-wrapper .hs-search-field__bar > form > .hs-search-field__input {
  padding: var(--hsf-field-input__padding);
}

.body-container-wrapper .hs-search-field__suggestions li a {
  color: var(--c-grey-08);
  padding: var(--spacing-2xs) var(--spacing-m);
  text-decoration: none;
  transition: background-color 200ms ease;
}

.body-container-wrapper .hs-search-field__suggestions li a:hover {
  background-color: var(--c-grey-03);
}

/* ── Light forms (body.bg-grey-10) ──────────────────────────────────────────
   Forms are fully driven by the --hsf-* vars declared in :root (dark defaults).
   On a light page canvas, flip those vars once so every form input, label and
   placeholder inverts to a light field with dark text — no per-form styling.
   Same token-flip mechanism as the body bg/fg in _typography.css. Accents
   (periwinkle button/focus, coral error) already read on both and stay. */
body.bg-grey-10 {
  --hsf-global__color:                  var(--c-grey-01);
  --hsf-field-label__color:             var(--c-grey-03);
  --hsf-field-input__color:             var(--c-grey-01);
  --hsf-field-input__background-color:  var(--c-grey-10);
  --hsf-field-input__placeholder-color: var(--c-grey-06);
  --hsf-field-input__border-color:      var(--c-grey-07);
  /* c-coral (#FF815C) pops on dark but is low-contrast as small text on white —
     darken it toward black for the error message (border/asterisk stay c-coral). */
  --hsf-global-error__color:            color-mix(in oklch, var(--c-coral), var(--c-grey-00) 35%);
}

/* Custom checkbox/radio controls are hardcoded (not --hsf vars) — flip here too.
   The :checked accent (periwinkle) already reads on both themes. */
body.bg-grey-10 form input[type=checkbox],
body.bg-grey-10 form input[type=radio] {
  background-color: var(--c-grey-10);
  border-color: var(--c-grey-07);
}

/* =============================================================
   Tables
   Minimal dark style: hairline row dividers, uppercase header,
   periwinkle accent on hover. Works for both content-editor
   inserted tables and HubSpot module-rendered tables.
   ============================================================= */

table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 var(--spacing-l);
  overflow-wrap: break-word;
  font-size: clamp(0.8125rem, 0.227vw + 0.756rem, 0.9375rem);
  color: var(--c-grey-08);
}

caption {
  text-align: left;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--c-grey-06);
  padding: var(--spacing-s) var(--spacing-m);
  border-bottom: 1px solid var(--c-grey-04);
}

/* Cells */

td,
th {
  vertical-align: top;
  text-align: left;
  padding: var(--spacing-s) var(--spacing-m);
}

/* Header row */

thead th {
  vertical-align: bottom;
  font-size: 0.7rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--c-grey-06);
  border-bottom: 1px solid var(--c-grey-04);
  background-color: transparent;
}

/* Body rows */

tbody td {
  border-bottom: 1px solid var(--c-grey-03);
  color: var(--c-grey-08);
  transition: background-color 200ms ease;
}

tbody tr:last-child td {
  border-bottom: 0;
}

tbody tr:hover td {
  background-color: var(--c-grey-02);
}

/* Footer */

tfoot td,
tfoot th {
  border-top: 1px solid var(--c-grey-04);
  color: var(--c-grey-07);
  font-size: 0.8rem;
}

/* Numeric / right-aligned cells (apply class manually when authoring) */

.t-num,
td.t-num,
th.t-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ── .prose — long-form rich-text rhythm ──────────────────────────────
   Restores vertical rhythm and media/quote/code/link styling for flowing
   HTML produced by HubSpot's render_body() / rich-text fields (blog posts,
   long-form copy). The global reset zeroes margins; this scope re-applies
   spacing only inside .prose, so it never leaks into utility-built layouts.
   Generic and reusable — anywhere long-form HTML renders, not blog-only. */

.prose {
  color: var(--c-grey-08);
}

.prose > :first-child { margin-top: 0; }
.prose > :last-child  { margin-bottom: 0; }

/* Block rhythm */
.prose p,
.prose ul,
.prose ol,
.prose blockquote,
.prose pre,
.prose figure,
.prose table {
  margin: 0 0 var(--spacing-l);
}

/* Headings sit closer to the text they introduce than to what precedes. */
.prose h2,
.prose h3,
.prose h4,
.prose h5,
.prose h6 {
  margin: var(--spacing-2xl) 0 var(--spacing-m);
  color: var(--c-grey-10);
}

/* Media */
.prose img,
.prose video,
.prose iframe {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: var(--spacing-3xs);
}

.prose figure { margin-inline: 0; }

.prose figcaption {
  margin-top: var(--spacing-2xs);
  text-align: center;
  color: var(--c-grey-06);
  font-size: clamp(0.75rem, 0.227vw + 0.693rem, 0.875rem);
}

/* Inline links — distinct from utility .link / buttons. */
.prose a {
  color: var(--c-periwinkle-light);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color 200ms ease;
}

.prose a:hover { color: var(--c-aqua); }

/* Lists */
.prose ul,
.prose ol { padding-left: 1.5em; }

.prose li + li { margin-top: var(--spacing-2xs); }

/* Quotes — brand accent rule, slightly muted text. */
.prose blockquote {
  border-left: 2px solid var(--c-periwinkle);
  padding: var(--spacing-2xs) 0 var(--spacing-2xs) var(--spacing-l);
  color: var(--c-grey-07);
}

/* Code */
.prose code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.875em;
  background: var(--c-grey-02);
  padding: 0.1em 0.4em;
  border-radius: var(--spacing-4xs);
}

.prose pre {
  background: var(--c-grey-02);
  padding: var(--spacing-l);
  border-radius: var(--spacing-3xs);
  overflow: auto;
}

.prose pre code {
  background: none;
  padding: 0;
}

/* Rule */
.prose hr {
  border: 0;
  border-top: 1px solid var(--c-grey-03);
  margin: var(--spacing-2xl) 0;
}

/* ============================================================================
   Blog components — global, component-level styles for the CMS blog (listing
   + post). Sits alongside _tables.css / _forms.css in the elements layer.
   Structure only (aspect ratios, sticky rail, pagination, meta rows); colour,
   spacing, glass/glow surfaces are composed from utilities in the markup.

   Flicker rule (see memory: glass_transform_glow_clash): blog cards sit on
   bg-glass over a bg-glow section, so reveal them with opacity-only
   anim-fade-in — never anim-fade-up/zoom (transform re-samples backdrop).
   ========================================================================== */

/* ── Topic pill bar ──────────────────────────────────────────────────────
   Horizontal, wraps on desktop, scrolls horizontally on mobile so a long
   topic set never stacks into a tall block. Pills are .chip (see _buttons). */
.blog-topics {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-2xs);
}

@media (max-width: 640px) {
  .blog-topics {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .blog-topics::-webkit-scrollbar { display: none; }
  .blog-topics .chip { flex-shrink: 0; }
}

/* Topics + search row: the tags nav wraps its chips internally (it shrinks in
   the row) so the fixed-width search stays pinned top-right beside the first
   row of pills. Stacks to a column on mobile so the search isn't crushed next
   to the horizontally-scrolling pill bar. */
.blog-topics { min-width: 0; }

@media (max-width: 640px) {
  .blog-topics-row { flex-direction: column; align-items: stretch; }
  .blog-topics-row .blog-search { width: 100%; }
}

/* Active pill — generic chip state, reusable beyond the blog. */
.chip.is-active {
  --chip-bg: var(--c-periwinkle);
  --chip-bg-hover: var(--c-periwinkle);
  --chip-text: var(--c-white);
  --chip-text-hover: var(--c-white);
  --chip-border: var(--c-periwinkle);
  --chip-border-hover: var(--c-periwinkle);
}

/* ── Breadcrumb ───────────────────────────────────────────────────────────
   Home / Blog / topic / current, above the post title. Separators are a plain
   "/" via ::before (same char-based convention as .blog-dot) — no FA webfont
   dependency. Colour comes from the grey scale (theme-mirrored on light). */
.blog-breadcrumb__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Inline flow (not flex) so every item — links, "/" separators, and the
   current-page label — sits on one shared text baseline. Flexing each <li>
   introduced a per-item baseline offset that lifted the first crumb. */
.blog-breadcrumb__list li { display: inline; }
.blog-breadcrumb__list li + li::before {
  content: "/";
  margin: 0 var(--spacing-2xs);
  color: var(--c-grey-05);
}
.blog-breadcrumb a { color: var(--c-grey-05); }
.blog-breadcrumb a:hover { color: var(--c-periwinkle); }
.blog-breadcrumb [aria-current="page"] {
  display: inline-block;
  max-width: 32ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
  color: var(--c-grey-03);
}

/* ── Search field ─────────────────────────────────────────────────────── */
.blog-search { position: relative; flex-shrink: 0; width: min(18rem, 100%); }
.blog-search__form { position: relative; display: flex; align-items: center; }

.blog-search input[type="text"],
.blog-search input[type="search"] {
  width: 100%;
  padding: var(--spacing-2xs) var(--spacing-l) var(--spacing-2xs) var(--spacing-2xl);
  background: var(--c-grey-02);
  border: 1px solid var(--c-grey-04);
  border-radius: 999px;
  color: var(--c-grey-09);
  font-family: inherit;
  font-size: var(--btn-font-size);
  transition: border-color 200ms ease, box-shadow 200ms ease;
}

.blog-search input::placeholder { color: var(--c-grey-05); }

.blog-search input:focus {
  outline: none;
  border-color: var(--c-periwinkle);
  box-shadow: 0 0 0 3px rgba(72, 100, 255, 0.22);
}

.blog-search__icon {
  position: absolute;
  left: var(--spacing-m);
  top: 50%;
  transform: translateY(-50%);
  color: var(--c-grey-05);
  pointer-events: none;
}

/* ── Post card ────────────────────────────────────────────────────────────
   Card chrome (glass, radius, padding, glow) comes from utilities. This adds
   the media crop + a subtle zoom that fires from anywhere on the clickable
   card (.is-clickable is the overlay's ancestor — see _interactions.css). */
.blog-card { overflow: hidden; }

.blog-card__media {
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--c-grey-02);
}

.blog-card__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 800ms ease;
}

.blog-card:hover .blog-card__media img { transform: scale(1.05); }

/* Title link — only the title is clickable (the stretched-link overlay can't
   work inside bg-glass). `font: inherit` is essential: the global `a` rule sets
   font-size to the small button size, which would otherwise shrink the heading.
   Inherits the heading's full font + colour; underlines on hover. */
.blog-card__link {
  color: inherit;
  font: inherit;
  text-decoration: none;
}

.blog-card__link:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

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

/* Clamp the title/excerpt so cards in a row stay even without .card-align. */
.blog-card__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.blog-card__excerpt {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── Featured (first) post — wide split on desktop, stacks on mobile. ───── */
@media (min-width: 991px) {
  .blog-featured { flex-direction: row; }
  .blog-featured .blog-card__media { width: 56%; aspect-ratio: auto; }
  .blog-featured .blog-card__body  { width: 44%; justify-content: center; }
  .blog-featured .blog-card__title { -webkit-line-clamp: 3; }
}

/* ── Meta row (author • date • read time) ──────────────────────────────── */
.blog-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--spacing-2xs);
  color: var(--c-grey-05);
}

.blog-dot {
  color: var(--c-grey-05);
  user-select: none;
}

/* ── Author avatar ─────────────────────────────────────────────────────── */
.blog-avatar {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

.blog-avatar-l {
  width: 4.5rem;
  height: 4.5rem;
}

/* ── TLDR / summary box — sits under the post thumbnail. ────────────────── */
.blog-tldr {
  border: 1px solid var(--c-grey-03);
  border-left: 3px solid var(--c-periwinkle);
  border-radius: var(--spacing-3xs);
  background: var(--c-grey-02);
  padding: var(--spacing-l) var(--spacing-xl);
}

.blog-tldr__label {
  display: flex;
  align-items: center;
  gap: var(--spacing-2xs);
  margin-bottom: var(--spacing-2xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--c-periwinkle);
}

/* ── Pagination ────────────────────────────────────────────────────────── */
.blog-pagination {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--spacing-2xs);
}

.blog-pagination a,
.blog-pagination span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  height: 2.5rem;
  padding: 0 var(--spacing-2xs);
  border: 1px solid var(--c-grey-03);
  border-radius: var(--spacing-4xs);
  color: var(--c-grey-07);
  font-size: var(--btn-font-size);
  text-decoration: none;
  transition: border-color 200ms ease, color 200ms ease, background-color 200ms ease;
}

.blog-pagination a:hover {
  border-color: var(--c-periwinkle);
  color: var(--c-grey-10);
}

.blog-pagination .is-active {
  background: var(--c-periwinkle);
  border-color: var(--c-periwinkle);
  color: var(--c-white);
}

.blog-pagination .is-disabled {
  opacity: 0.4;
  pointer-events: none;
}

/* ── Constrain media inside the readable post column. ──────────────────── */
.blog-post__hero-media img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--spacing-3xs);
}

/* ── Light blog post (body.bg-grey-10) ──────────────────────────────────────
   The post template (templates/blog/blog-post.html) flips the body canvas to
   light. These override the blog surfaces + long-form prose colors that are
   hardcoded for the dark theme. Scoped to the light body so the dark defaults —
   and the still-dark blog listing — are untouched. Mid-grey text (c-grey-05/06)
   and accents (c-aqua, c-periwinkle) already read on both and are left alone. */
body.bg-grey-10 .prose { color: var(--body-fg); }
body.bg-grey-10 .prose :is(h1, h2, h3, h4, h5, h6) { color: var(--body-fg); }
body.bg-grey-10 .prose a { color: var(--c-periwinkle); }
body.bg-grey-10 .prose blockquote { color: var(--c-grey-03); }
body.bg-grey-10 .prose :is(code, pre) { background: var(--c-grey-09); }
body.bg-grey-10 .prose hr { border-top-color: var(--c-grey-07); }
body.bg-grey-10 .blog-tldr {
  background: var(--c-grey-09);
  border-color: var(--c-grey-07);
  border-left-color: var(--c-periwinkle);
}

/* Light listing surfaces (search input, card-media placeholder, pagination).
   The .is-active pagination pill keeps its periwinkle fill (not targeted). */
body.bg-grey-10 .blog-search input[type="text"],
body.bg-grey-10 .blog-search input[type="search"] {
  background: var(--c-grey-10);
  border-color: var(--c-grey-07);
  color: var(--c-grey-01);
}
body.bg-grey-10 .blog-search input::placeholder { color: var(--c-grey-05); }
body.bg-grey-10 .blog-card__media { background: var(--c-grey-09); }
body.bg-grey-10 .blog-pagination a,
body.bg-grey-10 .blog-pagination .is-disabled {
  border-color: var(--c-grey-07);
  color: var(--c-grey-03);
}
body.bg-grey-10 .blog-pagination a:hover { color: var(--c-grey-00); }

/* ── Blog listing header glow band ──────────────────────────────────────────
   The hero + filter tags + featured post sit over one glow. Instead of the glow
   being the wrapper AROUND the content (which stretches its shapes to the full
   grid height), it's a fixed 100vh band behind the content, so the shapes keep
   their natural proportions. Blog-scoped — the shared .bg-glow is untouched. */
.blog-header { position: relative; }
.blog-header__glow {
  position: absolute;
  inset: 0 0 auto 0;   /* top-anchored, full width */
  height: 100vh;
  z-index: 0;
  pointer-events: none;
}
.blog-header__content { position: relative; z-index: 1; }

/* ── Blog search — inline results (HubSpot Content Search API) ────────────────
   The form is the pill input row; .blog-search__results is an absolutely
   positioned dropdown anchored to .blog-search. Shown only while searching or
   done (class-gated by js/blog-search.js). */
.blog-search__reset {
  position: absolute;
  right: var(--spacing-s);
  top: 50%;
  transform: translateY(-50%);
  display: none;
  align-items: center;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--c-grey-05);
  padding: var(--spacing-2xs);
}
.blog-search--searching .blog-search__reset,
.blog-search--done .blog-search__reset { display: inline-flex; }

.blog-search__results {
  position: absolute;
  top: calc(100% + var(--spacing-2xs));
  left: 0;
  right: 0;
  z-index: 30;
  display: none;
  flex-direction: column;
  max-height: 60vh;
  overflow-y: auto;
  padding: var(--spacing-2xs);
  background: var(--c-grey-02);
  border: 1px solid var(--c-grey-04);
  border-radius: 14px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);
}
.blog-search--searching .blog-search__results,
.blog-search--done .blog-search__results { display: flex; }

/* "Searching…" hint while the request is in flight (results are cleared). */
.blog-search--searching .blog-search__results::before {
  content: "Searching\2026";
  padding: var(--spacing-s) var(--spacing-m);
  color: var(--c-grey-05);
  font-size: 0.85rem;
}

.blog-search__result {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--spacing-s) var(--spacing-m);
  border-radius: 10px;
  text-decoration: none;
  color: var(--c-grey-09);
}
.blog-search__result:hover,
.blog-search__result:focus-visible {
  background: var(--c-grey-03);
  outline: none;
}
.blog-search__result-title { font-weight: 600; color: var(--c-grey-00); }
.blog-search__result-desc {
  font-size: 0.8rem;
  color: var(--c-grey-05);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.blog-search__result .hs-search-highlight { font-style: normal; color: var(--c-periwinkle); }
.blog-search__zero {
  padding: var(--spacing-s) var(--spacing-m);
  color: var(--c-grey-05);
  font-size: 0.85rem;
}

/* Light theme (blog runs on body.bg-grey-10) */
body.bg-grey-10 .blog-search__results {
  background: var(--c-grey-10);
  border-color: var(--c-grey-08);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12);
}
body.bg-grey-10 .blog-search__result { color: var(--c-grey-02); }
body.bg-grey-10 .blog-search__result:hover,
body.bg-grey-10 .blog-search__result:focus-visible { background: var(--c-grey-09); }
body.bg-grey-10 .blog-search__result-title { color: var(--c-grey-00); }
body.bg-grey-10 .blog-search__reset { color: var(--c-grey-06); }

/* ============================================================================
   Resources listing — minimal additions on top of the blog card system.
   The cards reuse .blog-card / .blog-card__media / __title / __link / __excerpt
   and the filter chips reuse .chip / .blog-topics / .blog-search. Only the type
   badge and the client-side hidden state are resources-specific.

   Flicker rule (see memory: glass_transform_glow_clash): cards sit on bg-glass
   over a bg-glow hero, so they reveal opacity-only (anim-fade-in) — never a
   transform reveal.
   ========================================================================== */

/* Sidebar filter group label ("Topic", "Content Type") — small uppercase
   heading above each chip group. */
.resources-filter__label {
  display: block;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--c-grey-07);
}

/* Type badge — small uppercase eyebrow above the title (Guide / Calculator…). */
.resource-card__label {
  align-self: flex-start;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--c-aqua);
}

/* Client-side filtering toggles the native `hidden` attribute. .blog-card adds
   .flex-column (display:flex), whose class specificity beats the UA
   `[hidden] { display:none }` rule — so filtered cards (and pruned chips / the
   empty message) wouldn't actually hide. Force it, scoped to the listing. */
.resources-listing [hidden] {
  display: none !important;
}

/* sf-theme Animation System
   Add classes in the HubSpot editor CSS class field to enable animations.

   TYPE (pick one):
     anim-fade-up | anim-fade-in | anim-zoom-in | anim-slide-left | anim-slide-right | anim-text-chars

   TRIGGER (optional, default is scroll):
     anim-load        triggers on page load instead of scroll (use on heroes)

   TIMING (optional):
     anim-delay-200   delay before animation starts, in ms (200, 400, 600...)
     anim-duration-900  animation duration, in ms (400, 600, 800, 1000...)

   STAGGER (add to a parent element):
     anim-stagger     staggers direct children that have a type class, 80ms apart
     anim-gap-100     custom stagger gap in ms (use alongside anim-stagger)

   TEXT CHARS - child delay (add to a child span inside anim-text-chars):
     anim-char-gap-500  pauses the char stagger by 500ms before animating that span's chars */


/* Initial states */

.js-anim .anim-fade-up {
  opacity: 0;
  transform: translateY(30px);
}

.js-anim .anim-fade-in {
  opacity: 0;
}

.js-anim .anim-zoom-in {
  opacity: 0;
  transform: scale(0.93);
}

.js-anim .anim-slide-left {
  opacity: 0;
  transform: translateX(-40px);
}

.js-anim .anim-slide-right {
  opacity: 0;
  transform: translateX(40px);
}

/* Parent held hidden until play so the full title can't paint before JS
   splits it into chars (otherwise: flash of the whole title, then it
   vanishes as the .anim-char rule below kicks in, then it animates in).
   The early-reveal bootstrap in base.html adds .anim-play at parse time so
   this hidden window — and the LCP deferral it causes on the hero — stays
   minimal. Reduced motion resets this below. */
.js-anim .anim-text-chars { opacity: 0; }
.js-anim .anim-text-chars.anim-play { opacity: 1; }

.js-anim .anim-text-chars .anim-char {
  opacity: 0;
}


/* Keyframes */

@keyframes sfFadeUp {
  to { opacity: 1; transform: translateY(0); }
}

@keyframes sfFadeIn {
  to { opacity: 1; }
}

@keyframes sfZoomIn {
  to { opacity: 1; transform: scale(1); }
}

@keyframes sfSlideLeft {
  to { opacity: 1; transform: translateX(0); }
}

@keyframes sfSlideRight {
  to { opacity: 1; transform: translateX(0); }
}

@keyframes sfChar {
  from { opacity: 0; }
  to { opacity: 1; }
}


/* Play states — .anim-play added by JS */

.anim-fade-up.anim-play {
  animation: sfFadeUp var(--anim-duration, 800ms) cubic-bezier(0.22, 1, 0.36, 1) var(--anim-delay, 0ms) both;
}

.anim-fade-in.anim-play {
  animation: sfFadeIn var(--anim-duration, 800ms) ease var(--anim-delay, 0ms) both;
}

.anim-zoom-in.anim-play {
  animation: sfZoomIn var(--anim-duration, 800ms) cubic-bezier(0.22, 1, 0.36, 1) var(--anim-delay, 0ms) both;
}

.anim-slide-left.anim-play {
  animation: sfSlideLeft var(--anim-duration, 800ms) cubic-bezier(0.22, 1, 0.36, 1) var(--anim-delay, 0ms) both;
}

.anim-slide-right.anim-play {
  animation: sfSlideRight var(--anim-duration, 800ms) cubic-bezier(0.22, 1, 0.36, 1) var(--anim-delay, 0ms) both;
}

.anim-text-chars.anim-play .anim-char {
  animation: sfChar var(--anim-duration, 400ms) ease var(--anim-char-delay, 0ms) both;
}


/* Done state — belt-and-suspenders after animation completes */

.anim-done {
  opacity: 1 !important;
  transform: none !important;
}

.anim-done .anim-char {
  opacity: 1 !important;
}


/* Reduced motion */

@media (prefers-reduced-motion: reduce) {
  .js-anim .anim-fade-up,
  .js-anim .anim-fade-in,
  .js-anim .anim-zoom-in,
  .js-anim .anim-slide-left,
  .js-anim .anim-slide-right,
  .js-anim .anim-text-chars,
  .js-anim .anim-text-chars .anim-char {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
}

/* h-* — hover-triggered interaction utilities.
 *
 * Distinct from anim-* (scroll-triggered animations in _animations.css).
 * Apply directly to any container. Add a color variant for a different hue.
 */


/* h-glow — soft color halo that fades in on hover.
 *
 *   <div class="card h-glow">                 default periwinkle
 *   <div class="card h-glow h-glow-aqua">
 *   <div class="card h-glow h-glow-coral">
 *
 * Per-instance overrides via --h-glow-color and --h-glow-blur.
 */

.h-glow {
  --h-glow-color: var(--c-periwinkle);
  --h-glow-blur: 40px;

  transition: box-shadow 800ms ease-out;
}

.h-glow:hover {
  box-shadow: 0 0 var(--h-glow-blur) 0 color-mix(in oklch, var(--h-glow-color), transparent 50%);
}

/* Compose with .bg-glass: h-glow would otherwise replace the whole box-shadow
   and wipe the glass edge/glow/bevel/drop. Re-include the glass stack (via its
   --glass-shadow var) and ADD the halo. A transparent halo layer in the resting
   state keeps the layer count equal so the hover transition fades smoothly. */
.bg-glass.h-glow {
  box-shadow:
    var(--glass-shadow),
    0 0 var(--h-glow-blur) 0 transparent;
}

.bg-glass.h-glow:hover {
  box-shadow:
    var(--glass-shadow),
    0 0 var(--h-glow-blur) 0 color-mix(in oklch, var(--h-glow-color), transparent 50%);
}

.h-glow-periwinkle       { --h-glow-color: var(--c-periwinkle); }
.h-glow-periwinkle-light { --h-glow-color: var(--c-periwinkle-light); }
.h-glow-aqua             { --h-glow-color: var(--c-aqua); }
.h-glow-coral            { --h-glow-color: var(--c-coral); }
.h-glow-purple           { --h-glow-color: var(--c-purple-regular); }
.h-glow-blue             { --h-glow-color: var(--c-blue-regular); }


/* h-fade — element dims to a lower opacity on hover. Generalized from the
 * integration-logo hover in the header. Tune the hover target with
 * --h-fade-opacity (default 0.7).
 *
 *   <a class="h-fade"><img …></a>      logo / icon link
 *   <div class="card is-clickable h-fade"> … </div>
 */

.h-fade {
  --h-fade-opacity: 0.7;
  transition: opacity 200ms ease;
}

.h-fade:hover {
  opacity: var(--h-fade-opacity);
}


/* h-scale — element scales up subtly and smoothly on hover. Tune the amount
 * with --h-scale (default 1.03). Keep it small; large values feel jumpy.
 *
 *   <div class="card h-scale"> … </div>
 *   <a class="h-scale" style="--h-scale: 1.05;"><img …></a>
 */

.h-scale {
  --h-scale: 1.03;
  transition: transform 250ms ease-out;
}

/* !important so the hover scale survives on elements that also carry a
   transform-based reveal (anim-fade-up/zoom/slide): once that reveal finishes,
   .anim-done pins `transform: none !important`, which would otherwise win and
   kill the hover. h-scale is meant to compose with anim-*, so it takes precedence
   on hover. */
.h-scale:hover {
  transform: scale(var(--h-scale)) !important;
}


@media (prefers-reduced-motion: reduce) {
  .h-glow,
  .h-fade,
  .h-scale { transition: none; }
  .h-scale:hover { transform: none !important; }
}


/* is-clickable / card-link — make a whole container a single clickable card
 * (the "stretched link" pattern). Put .is-clickable on the card to give it a
 * positioning context, then drop one <a class="card-link"> inside it; the
 * link's ::after expands to cover the entire card, so a click anywhere
 * follows it. Keeps the card a valid <div> (no <a> wrapping headings/images).
 *
 *   <div class="card is-clickable">
 *     …content…
 *     <a class="card-link" href="…" aria-label="…"></a>   (place last)
 *   </div>
 *
 * Hover: drive effects from .is-clickable:hover — it's an ancestor of the
 * overlay, so it fires from anywhere on the card (e.g.
 * .is-clickable:hover .title-section { … }).
 *
 * Inner interactive children (real links/buttons) sit BELOW the overlay and
 * won't receive clicks. To keep one live, lift it above the overlay with
 * position: relative; z-index: 1. */

.is-clickable {
  position: relative;
}

.card-link::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* Hide on mobile */

.d-desktop {}

.d-mobile {}

@media (max-width: 991px) {
  .d-desktop {
    display: none;
  }
}

@media (min-width: 991px) {
  .d-mobile {
    display: none;
  }
}

/* Skip-to-content link — visually hidden until focused, then jumps to
   the top-right corner so keyboard users can bypass the header chrome. */

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--spacing-l);
  z-index: 9999;
  padding: var(--spacing-s) var(--spacing-l);
  background: var(--c-periwinkle);
  color: var(--c-white);
  text-decoration: none;
  border-radius: var(--spacing-2xs);
  font-size: 0.875rem;
  transition: top 150ms ease;
}

.skip-link:focus-visible {
  top: var(--spacing-l);
  outline: 2px solid var(--c-white);
  outline-offset: 2px;
}

/* TBD nav placeholders — links to pages that don't exist yet, marked
   data-tbd-url with href="#". Hidden until the page is built: give the link a
   real href and drop the data-tbd-url attribute to reveal it. Links marked
   data-tbd-url that already have a real href (e.g. All Partners → /partners)
   are intentionally NOT matched, so they stay visible. The full pending list is
   tracked in modules/global/nav-links.md. */
a[data-tbd-url][href="#"],
li:has(> a[data-tbd-url][href="#"]) {
  display: none !important;
}

/* Visually hidden, but present in the DOM for screen readers and crawlers.
   Used for crawlable fallback copy beside non-text content like iframes. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */

/* Document
   ========================================================================== */

/**
 * 1. Correct the line height in all browsers.
 * 2. Prevent adjustments of font size after orientation changes in iOS.
 */

html {
  line-height: 1.15; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
}

/* Sections
   ========================================================================== */

/**
 * Remove the margin in all browsers.
 */

body {
  margin: 0;
}

/**
 * Correct the font size and margin on `h1` elements within `section` and
 * `article` contexts in Chrome, Firefox, and Safari.
 */

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

/* Grouping content
   ========================================================================== */

/**
 * Add the correct box sizing in Firefox.
 */

hr {
  box-sizing: content-box;
  height: 0;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

pre {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/* Text-level semantics
   ========================================================================== */

/**
 * 1. Remove the bottom border in Chrome 57-
 * 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
 */

abbr[title] {
  border-bottom: none; /* 1 */
  text-decoration: underline; /* 2 */
  text-decoration: underline dotted; /* 2 */
}

/**
 * Add the correct font weight in Chrome, Edge, and Safari.
 */

b,
strong {
  font-weight: bolder;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

code,
kbd,
samp {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/**
 * Add the correct font size in all browsers.
 */

small {
  font-size: 80%;
}

/**
 * Prevent `sub` and `sup` elements from affecting the line height in
 * all browsers.
 */

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/* Forms
   ========================================================================== */

/**
 * 1. Change the font styles in all browsers.
 * 2. Remove the margin in Firefox and Safari.
 */

button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-size: 100%; /* 1 */
  line-height: 1.15; /* 1 */
  margin: 0; /* 2 */
}

/**
 * Remove the inheritance of text transform in Edge and Firefox.
 * 1. Remove the inheritance of text transform in Firefox.
 */

button,
select { /* 1 */
  text-transform: none;
}

/**
 * Correct the inability to style clickable types in iOS and Safari.
 */

button,
[type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
}

/**
 * Remove the inner border and padding in Firefox.
 */

button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
  border-style: none;
  padding: 0;
}

/**
 * Restore the focus styles unset by the previous rule.
 */

button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
  outline: 1px dotted ButtonText;
}

/**
 * Correct the padding in Firefox.
 */

fieldset {
  padding: 0.35em 0.75em 0.625em;
}

/**
 * Remove the padding so developers are not caught out when they zero out `fieldset` elements in all browsers.
 */

legend {
  padding: 0;
}

/**
 * Add the correct vertical alignment in Chrome, Firefox, and Opera.
 */

progress {
  vertical-align: baseline;
}

/**
 * Correct the cursor style of increment and decrement buttons in Chrome.
 */

[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
  height: auto;
}

/**
 * 1. Correct the odd appearance in Chrome and Safari.
 * 2. Correct the outline style in Safari.
 */

[type="search"] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}

/**
 * Remove the inner padding in Chrome and Safari on macOS.
 */

[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}

/**
 * 1. Correct the inability to style clickable types in iOS and Safari.
 * 2. Change font properties to `inherit` in Safari.
 */

::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}

/* Interactive
   ========================================================================== */

/*
 * Add the correct display in Edge and Firefox.
 */

details {
  display: block;
}

/*
 * Add the correct display in all browsers.
 */

summary {
  display: list-item;
}

*, *:before, *:after {
  box-sizing: border-box;
}

/* Non-.btn <button> controls (slider arrows, FAQ triggers, etc.) reset to
   inherit their container's look. Element-level specificity, so any component
   or utility class (.btn, .nav-tab, .video-btn, bg-*) overrides it. Loaded
   after _normalize.css to undo its `-webkit-appearance: button`. */
button {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  margin: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: inherit;
  cursor: pointer;
}