/* =========================================================================
   Split 50 / 50 — hover studies
   Figma: CW / node 1170:5752 (default) + 1170:5701 (hover state)

   Two copies of the same section, each with a different button behaviour:

     .cw-split--morph   the frame's own state — the 44px ring turns into a
                        diamond, the arrow holds still.
     .cw-split--plain   Figma node 1211:6001. The ring grows 44 → 50 keeping
                        its pale stroke, and the arrow scales up by a tenth —
                        every coordinate of the hover frame is the resting one
                        times 1.1, its 1.65 stroke included, so it is one
                        uniform scale rather than a reshape. The glyph is the
                        node's thin stroked chevron, not the filled arrow the
                        three blocks above use. The button lives on its own as
                        .cw-btn--chev, because .cw-cta reuses it in white.

     .cw-split--sweep   Figma node 1184:5971. The ring grows 44 → 52 and a
                        dark stroke draws itself around it, starting at 12
                        o'clock and running clockwise; the middle frame is the
                        right half dark, which is what a half-done clockwise
                        sweep from the top looks like. On unhover the stroke
                        does not rewind — it keeps going the same way round,
                        the tail chasing the head until nothing is left. That
                        is the second half of one continuous lap, so the two
                        halves are separate keyframes driven by micro-interactions.js.

     .cw-split--grow    the ring grows 44 → 52 from its centre, and the arrow
                        swaps: it flies off to the right and returns from the
                        left. The swap runs on entry only — leaving the module
                        just shrinks the ring back. It is a keyframe animation
                        (a transition cannot express the flight), started by
                        micro-interactions.js on mouseenter and focus.

   Type comes from styles.css (--sans / --mono, the Adobe kit faces);
   everything else is local to the block so it can be lifted into the page.
   ========================================================================= */

/* the page canvas the blocks sit on */
body { background: #272727; }

.cw-split {
  --panel:      #e8ecfc;                    /* Figma blue/10            */
  --panel-ink:  #02030b;                    /* Figma text/primary       */
  --panel-rule: rgba(2, 3, 11, .32);        /* Line 4                   */
  --btn-ring:       rgba(12, 25, 89, .3);
  --btn-ring-hover: rgba(12, 25, 89, .55);

  /* one curve and one duration for the whole morph, so the ring colour and
     the shape move as a single gesture rather than in two beats */
  --morph-ease: cubic-bezier(.65, 0, .35, 1);   /* easeInOutCubic */
  --morph-dur:  .45s;

  background: transparent;      /* the page canvas shows through the gutter */
  padding: 84px 54px;
}

.cw-split__inner {
  display: grid;
  grid-template-columns: 1fr 1fr;   /* the frame's two 640s */
  max-width: 1280px;
  margin: 0 auto;
}

/* ------------------------------------------------------------ left half -- */
.cw-panel {
  background: var(--panel);
  color: var(--panel-ink);
  min-height: 780px;
  padding: 40px;
  display: flex;
  flex-direction: column;
}

/* the panel holds all three arrangements; the spacing that used to live on
   .cw-panel moved here so only the visible one drives the layout */
.cw-split__layout {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 64px;
}
.cw-split__layout[hidden] { display: none; }

.cw-eyebrow { display: flex; align-items: center; gap: 10px; }
.cw-eyebrow__mark { flex: none; width: 10px; height: 10px; }
.cw-eyebrow__mark svg { display: block; }
.cw-eyebrow__text {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 14px;
  line-height: 16px;
  text-transform: uppercase;
}

/* ---------------------------------------------------------------- items -- */
.cw-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-bottom: 1px solid var(--panel-rule);
}
.cw-item { border-top: 1px solid var(--panel-rule); }

.cw-item__link {
  display: flex;
  align-items: center;
  gap: 40px;
  padding: 40px 20px 40px 0;
  color: inherit;
  text-decoration: none;
  outline: none;
}

.cw-item__text { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 24px; }
.cw-item__title {
  font-size: 24px;
  line-height: 28px;
  font-weight: 500;
  letter-spacing: -.72px;
}
.cw-item__body { font-size: 16px; line-height: 22px; font-weight: 400; }

.cw-item__link:focus-visible .cw-item__title {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ------------------------------------------------------ button, shared -- */
.cw-btn {
  position: relative;
  flex: none;
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
}

/* The ring is its own layer so the arrow is never dragged along by it. */
.cw-btn__ring {
  position: absolute;
  left: 50%;
  top: 50%;
  /* centred by translate, not by `inset:0; margin:auto` — margin:auto is
     over-constrained once the ring outgrows the 48px button box and drops it
     2px off centre, which is exactly what the grow behaviour does. */
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
  border: 1.5px solid var(--btn-ring);
  border-radius: 22px;          /* a true circle at 44px */
}

.cw-btn__icon {
  position: relative;
  width: 22.627px;              /* the 16px glyph turned 45° */
  height: 22.627px;
  display: grid;
  place-items: center;
}
.cw-btn__icon svg { display: block; transform: rotate(45deg); }

/* The round mask the arrow flies out of. Sized to match the ring at rest;
   each variant grows it in step with its own ring. */
.cw-btn__clip {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);   /* same reason as the ring */
  width: 44px;
  height: 44px;
  border-radius: 50%;
  overflow: hidden;             /* the runway the arrow flies off */
  display: grid;
  place-items: center;
}

/* ------------------------------ the arrow swap, shared by blocks 2 and 4 -- */

.cw-btn--swap {
  --swap-dur: .5s;
  --swap-out: 40px;   /* clears either ring: 26 + half the widest glyph */
}

/* Out to the right, in from the left. The jump between the two sides happens
   while the glyph is outside the clip, so it is never seen. */
@keyframes cw-arrow-swap {
  0% {
    transform: translateX(0);
    animation-timing-function: cubic-bezier(.55, 0, 1, .45);   /* accelerate out */
  }
  49% {
    transform: translateX(var(--swap-out));
    animation-timing-function: steps(1, end);   /* jump, do not sweep back */
  }
  50% {
    transform: translateX(calc(var(--swap-out) * -1));
    animation-timing-function: cubic-bezier(0, .55, .45, 1);   /* decelerate in */
  }
  100% { transform: translateX(0); }
}

/* micro-interactions.js adds this on mouseenter and on focus, and drops it again on
   animationend so the next entry can restart it. */
.cw-btn--swap .cw-btn__icon.is-swapping {
  animation: cw-arrow-swap var(--swap-dur) both;
}

/* ============================================ behaviour 1 — circle → diamond */

.cw-split--morph .cw-btn__ring {
  transition:
    transform     var(--morph-dur) var(--morph-ease),
    border-radius var(--morph-dur) var(--morph-ease),
    border-color  var(--morph-dur) var(--morph-ease);
  will-change: transform, border-radius;
}

/* rotate 45° and scale to .915 → a 40.2px square standing on its corner,
   54.9px point to point. Both numbers are the hover frame's. */
.cw-split--morph :is(.cw-item__link, .cw-arrow-link):is(:hover, :focus-visible) .cw-btn__ring {
  transform: translate(-50%, -50%) rotate(45deg) scale(.915);
  border-radius: 4.6px;         /* ≈ the frame's 4.25 once scaled */
  border-color: var(--btn-ring-hover);
}

/* ---------------------------------------------------------- block marker -- */

/* Block header — Figma node 1318:6306. The number on the left, nine round
   buttons on the right, both flush with the block's own edges (the frame puts
   the button row at 964 and it ends at 1388, which is where the 1280 block
   ends). The number carries no description of the block: it is the label. */
.cw-marker {
  --marker-white: #fcfaf5;      /* Core White */
  --marker-black: #282828;      /* Core Black */

  max-width: 1280px;
  margin: 0 auto 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  color: var(--marker-white);
}

.cw-marker__num {
  font-family: var(--sans);
  font-size: 44px;
  line-height: 48px;
  font-weight: 500;
  letter-spacing: -1.32px;
}

/* swatches, a small separator dot, then the layout numbers — the frame puts
   24px on either side of the dot */
.cw-marker__tools { display: flex; align-items: center; gap: 24px; }
.cw-marker__swatches,
.cw-marker__layouts { display: flex; gap: 8px; }

.cw-marker__sep {
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, .5);
}

.cw-marker__swatch {
  width: 40px;
  height: 40px;
  flex: none;
  padding: 0;
  border-radius: 100px;
  /* the ring is a border in the swatch's own colour until it is picked, so
     the disc stays a full 40px either way rather than shrinking by 4 */
  border: 2px solid var(--swatch);
  background: var(--swatch);
  cursor: pointer;
  transition: border-color .2s ease;
}
.cw-marker__swatch[aria-pressed="true"] { border-color: #fff; }
.cw-marker__swatch:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

.cw-marker__btn {
  width: 40px;
  height: 40px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid #fff;
  border-radius: 100px;
  background: transparent;
  color: var(--marker-white);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 22px;
  font-weight: 400;
  cursor: pointer;
  transition: background-color .2s ease, color .2s ease;
}
.cw-marker__btn:hover { background: rgba(255, 255, 255, .16); }
.cw-marker__btn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

.cw-marker__btn[aria-pressed="true"] {
  background: #fff;
  color: var(--marker-black);
}

@media (max-width: 1024px) {
  .cw-marker { flex-wrap: wrap; gap: 16px; margin-bottom: 24px; }
  .cw-marker__num { font-size: 34px; line-height: 38px; letter-spacing: -1px; }
  .cw-marker__tools { flex-wrap: wrap; }
  .cw-marker__btn { width: 34px; height: 34px; font-size: 14px; }
}

.cw-split, .cw-cta { scroll-margin-top: 24px; }

/* ============================================ behaviour 2 — grow + arrow swap */

.cw-split--grow {
  --grow-dur:  .45s;
  --grow-ease: cubic-bezier(.65, 0, .35, 1);
}

/* Ring and clip grow together on the same tick, so the arrow always vanishes
   exactly at the outline and never floats outside it. */
.cw-split--grow .cw-btn__ring,
.cw-split--grow .cw-btn__clip {
  transition:
    width         var(--grow-dur) var(--grow-ease),
    height        var(--grow-dur) var(--grow-ease),
    border-color  var(--grow-dur) var(--grow-ease);
}

.cw-split--grow .cw-btn__ring { border-radius: 50%; }

/* width/height rather than scale() — a scaled ring would thicken its own
   1.5px stroke to 1.77 on the way up. */
.cw-split--grow :is(.cw-item__link, .cw-arrow-link):is(:hover, :focus-visible) .cw-btn__ring {
  width: 52px;
  height: 52px;
  border-color: var(--btn-ring-hover);
}

.cw-split--grow :is(.cw-item__link, .cw-arrow-link):is(:hover, :focus-visible) .cw-btn__clip {
  width: 52px;
  height: 52px;
}

/* The title underlines itself left to right as the arrow flies. It is a
   background on an inline wrapper rather than a bar across the title block,
   because two of the three titles wrap and a block-wide rule would run well
   past the shorter one. box-decoration-break makes both line fragments carry
   their own rule. */
.cw-split--grow .cw-item__title-ink {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1.5px;
  padding-bottom: 3px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  transition: background-size var(--grow-dur) var(--grow-ease);
}
.cw-split--grow .cw-item__link:hover .cw-item__title-ink,
.cw-split--grow .cw-item__link:focus-visible .cw-item__title-ink {
  background-size: 100% 1.5px;
}
/* the shared focus underline would double up with it here */
.cw-split--grow .cw-item__link:focus-visible .cw-item__title { text-decoration: none; }

/* ======================================= behaviour 3 — grow + stroke sweep */

.cw-split--sweep {
  --sweep-dur:  .45s;
  --sweep-ease: cubic-bezier(.65, 0, .35, 1);
}

/* the pale ring underneath, same growth as behaviour 2 */
.cw-split--sweep .cw-btn__ring {
  border-radius: 50%;
  transition:
    width  var(--sweep-dur) var(--sweep-ease),
    height var(--sweep-dur) var(--sweep-ease);
}
.cw-split--sweep :is(.cw-item__link, .cw-arrow-link):is(:hover, :focus-visible) .cw-btn__ring {
  width: 52px;
  height: 52px;
}

/* The dark stroke rides on top of the pale one at the same radius, so by the
   end it has covered it completely — which is the third frame. The box is a
   fixed 52 and the circle's own r is animated instead of scaling the svg,
   so the 1.5px stroke never thickens. pathLength="1" normalises the dash to
   0..1, so the dash keeps working while r changes. */
.cw-split--sweep .cw-btn__sweep {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) rotate(-90deg);   /* start at 12 o'clock */
  width: 52px;
  height: 52px;
  overflow: visible;
  pointer-events: none;
}
.cw-split--sweep .cw-btn__sweep circle {
  fill: none;
  stroke: var(--panel-ink);
  stroke-width: 1.5;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;         /* nothing drawn at rest */
  r: 21.25px;                   /* the 44px ring's centreline */
  transition: r var(--sweep-dur) var(--sweep-ease);
}
.cw-split--sweep :is(.cw-item__link, .cw-arrow-link):is(:hover, :focus-visible) .cw-btn__sweep circle {
  r: 25.25px;                   /* the 52px ring's centreline */
}

/* With pathLength 1 the dash pattern is [1 drawn, 1 gap] and the offset slides
   it along the path. Offset 1 and offset -1 both land on the gap, so both read
   as an empty ring — but they empty from opposite ends, which is the whole
   point here:

     1  →  0    the head runs clockwise from 12, the ring fills in
     0  → -1    the tail runs clockwise after it, the ring empties ahead

   Going 0 → 1 instead would rewind the head back the way it came, which is
   what this used to do. */
@keyframes cw-sweep-in  { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes cw-sweep-out { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -1; } }

.cw-split--sweep .cw-btn__sweep circle.is-drawing {
  animation: cw-sweep-in var(--sweep-dur) var(--sweep-ease) forwards;
}
.cw-split--sweep .cw-btn__sweep circle.is-clearing {
  animation: cw-sweep-out var(--sweep-dur) var(--sweep-ease) forwards;
}

/* ===================== behaviour 4 — plain grow, as a reusable button ======

   Figma node 1211:6001. Written against the button rather than the section so
   the CTA block below can reuse it: it reacts to hover on whatever link wraps
   it, and takes its ring colour and glyph colour from the surrounding block. */

.cw-btn--chev {
  --chev-dur:   .3s;            /* quicker than the blocks above */
  --chev-ease:  cubic-bezier(.65, 0, .35, 1);
  --chev-scale: 1.1;            /* 9.5 → 10.45, 1.5 → 1.65, all of it */
  --chev-grown: 50px;
}

/* the stroke colour is the same in both frames, so only the size moves */
.cw-btn--chev .cw-btn__ring,
.cw-btn--chev .cw-btn__clip {
  border-radius: 50%;
  transition:
    width  var(--chev-dur) var(--chev-ease),
    height var(--chev-dur) var(--chev-ease);
}

/* this button's glyph is the node's own 19 × 20 stroked chevron, drawn upright
   rather than the 16px filled glyph turned 45° that the others use */
.cw-btn--chev .cw-btn__icon {
  width: 19px;
  height: 20px;
}
/* The scale sits on the svg, not on .cw-btn__icon, because the icon's own
   transform belongs to the swap animation — one element cannot carry both. */
.cw-btn--chev .cw-btn__icon svg {
  transform: scale(1);
  overflow: visible;            /* the 1.5px stroke sits on the viewBox edge */
  transition: transform var(--chev-dur) var(--chev-ease);
}

/* A plain scale on the wrapper, so the stroke thickens along with the geometry
   the way the frame draws it — 1.5 up to 1.65. Scaling is what gives that for
   free; a path morph would have held the stroke at 1.5. */
:is(.cw-item__link, .cw-arrow-link, .cw-cta__card):is(:hover, :focus-visible) .cw-btn--chev .cw-btn__ring,
:is(.cw-item__link, .cw-arrow-link, .cw-cta__card):is(:hover, :focus-visible) .cw-btn--chev .cw-btn__clip {
  width:  var(--chev-grown);
  height: var(--chev-grown);
}
:is(.cw-item__link, .cw-arrow-link, .cw-cta__card):is(:hover, :focus-visible) .cw-btn--chev .cw-btn__icon svg {
  transform: scale(var(--chev-scale));
}

/* ----------------------------------------------------------- right half -- */
.cw-media {
  min-height: 780px;
  background: url("assets/micro-interactions-facade.jpg") center / cover no-repeat;
}

/* ----------------------------------------------------------- responsive -- */
@media (max-width: 1024px) {
  .cw-split { padding: 48px 24px; }
  .cw-split__inner { grid-template-columns: 1fr; }
  .cw-panel { min-height: 0; }
  .cw-media { min-height: 420px; order: -1; }
}
@media (max-width: 560px) {
  .cw-panel { padding: 24px; gap: 40px; }
  .cw-item__link { gap: 20px; padding: 28px 0; }
  .cw-item__title { font-size: 20px; line-height: 24px; }
}

@media (prefers-reduced-motion: reduce) {
  .cw-split--morph .cw-btn__ring,
  .cw-split--grow .cw-btn__ring,
  .cw-split--grow .cw-btn__clip,
  .cw-split--grow .cw-item__title-ink,
  .cw-split--sweep .cw-btn__ring,
  .cw-split--sweep .cw-btn__sweep circle,
  .cw-btn--chev .cw-btn__ring,
  .cw-btn--chev .cw-btn__clip,
  .cw-btn--chev .cw-btn__icon svg { transition-duration: .01ms; }
  .cw-split--sweep .cw-btn__sweep circle.is-drawing,
  .cw-split--sweep .cw-btn__sweep circle.is-clearing { animation-duration: .01ms; }
  .cw-split--grow .cw-btn__icon.is-swapping { animation-duration: .01ms; }
}

/* =========================================================================
   CTA block — Figma node 1274:6213

   A hero over two blue cards. Its own thing, not a copy of .cw-split.

   The button states come from the node's own state sheet (1274:6190):
     secondary  a #f3f5fa fill wipes in from the left edge, inside the border
     primary    a 0 4px 2px black/25 shadow drops in
     arrow      .cw-btn--chev from behaviour 4, in white
   ========================================================================= */

.cw-cta {
  --cta-ink:   #02030b;
  --cta-blue:  var(--blue, #1e3fdf);
  --cta-fill:  var(--chip, #f3f5fa);
  --cta-rule:  rgba(12, 25, 89, .3);

  --cta-dur:   .3s;
  --cta-ease:  cubic-bezier(.65, 0, .35, 1);

  /* --- colour schemes, Figma node 1318:6306 -----------------------------
     The swatch picks one of these sets; the layout buttons pick the shape.
     Blue is the default. Only the resting palette is drawn in the frames, so
     the hover accents below are derived rather than specified — flagged where
     that happens. */
  --scheme-hero-bg:      var(--white);
  --scheme-hero-ink:     #02030b;
  --scheme-card-bg:      #1e3fdf;
  --scheme-card-ink:     var(--white);
  --scheme-card-rule:    var(--white);
  --scheme-ring:         rgba(255, 255, 255, .3);
  --scheme-btn-bg:       #02030b;               /* primary, at rest      */
  --scheme-btn-ink:      var(--white);
  --scheme-btn-line:     rgba(12, 25, 89, .3);  /* secondary's outline   */
  --scheme-accent:       #1e3fdf;               /* primary's wipe        */
  --scheme-btn-fill:     var(--chip, #f3f5fa);  /* secondary's wipe      */
  --scheme-btn-fill-ink: #02030b;               /* label once filled     */
  --scheme-veil:         rgba(255, 255, 255, .15);

  background: transparent;      /* the page canvas shows through the gutter */
  padding: 84px 54px;
}

/* only the cards change */
.cw-cta[data-scheme="ink"] { --scheme-card-bg: #02030b; }

/* here the hero inverts too: black ground, white buttons */
.cw-cta[data-scheme="pale"] {
  --scheme-hero-bg:      #02030b;
  --scheme-hero-ink:     var(--white);
  --scheme-card-bg:      #d2d9f9;
  --scheme-card-ink:     #02030b;
  --scheme-card-rule:    #02030b;
  --scheme-ring:         #02030b;
  --scheme-btn-bg:       var(--white);
  --scheme-btn-ink:      #02030b;
  --scheme-btn-line:     var(--white);
  /* a blue wipe under dark text would not read on a white button, and an
     #f3f5fa fill is invisible behind a white label — both take the scheme's
     own colours instead. Derived, not drawn. */
  --scheme-accent:       #d2d9f9;
  --scheme-btn-fill:     var(--white);
  --scheme-btn-fill-ink: #02030b;
  --scheme-veil:         rgba(2, 3, 11, .12);
}

.cw-cta__inner {
  max-width: 1280px;
  margin: 0 auto;
  background: var(--scheme-hero-bg);
  color: var(--scheme-hero-ink);
  transition: background-color var(--cta-dur) var(--cta-ease),
              color var(--cta-dur) var(--cta-ease);
}

/* ------------------------------------------------------------------ hero -- */
.cw-cta__hero {
  max-width: 1033px;
  min-height: 400px;
  padding: 40px;
  display: flex;
  flex-direction: column;
  gap: 40px;
}

.cw-cta__title {
  margin: 0;
  font-size: 44px;
  line-height: 48px;
  font-weight: 500;
  letter-spacing: -1.32px;
}
.cw-cta__lede { margin: 0; font-size: 16px; line-height: 22px; }

.cw-cta__actions { display: flex; flex-wrap: wrap; gap: 24px; }

/* ---------------------------------------------------------------- buttons -- */
.cw-cta__btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 44px;
  padding: 12px 24px;
  border: 0;
  font: inherit;
  font-size: 14px;
  line-height: 20px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.cw-cta__btn > span { position: relative; z-index: 1; }   /* label above the wipe */

.cw-cta__btn--primary {
  background: var(--scheme-btn-bg);
  color: var(--scheme-btn-ink);
  transition: box-shadow var(--cta-dur) var(--cta-ease),
              background-color var(--cta-dur) var(--cta-ease),
              color var(--cta-dur) var(--cta-ease);
}
.cw-cta__btn--secondary {
  background: transparent;
  color: var(--scheme-hero-ink);
  border: 1.5px solid var(--scheme-btn-line);
}

/* --- states from node 1274:6190 (the first CTA) ------------------------- */

/* primary — a blue fill enters from the left and a drop shadow comes with it.
   Its fill is flush to the edge and the full 44 tall, where the secondary's
   sits inside the outline: this button has no border to sit inside of. */
.cw-cta--wipe .cw-cta__btn--primary::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--scheme-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--cta-dur) var(--cta-ease);
}
.cw-cta--wipe .cw-cta__btn--primary:hover::before,
.cw-cta--wipe .cw-cta__btn--primary:focus-visible::before { transform: scaleX(1); }

.cw-cta--wipe .cw-cta__btn--primary:hover,
.cw-cta--wipe .cw-cta__btn--primary:focus-visible {
  box-shadow: 0 4px 2px rgba(0, 0, 0, .25);
}

/* secondary — the fill enters from the left and runs the width of the button.
   It is a pseudo-element inset by the border width, because the state sheet
   draws the fill inside the 1.5px outline, not under it. */
.cw-cta--wipe .cw-cta__btn--secondary::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--scheme-btn-fill);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--cta-dur) var(--cta-ease);
}
.cw-cta--wipe .cw-cta__btn--secondary:hover::before,
.cw-cta--wipe .cw-cta__btn--secondary:focus-visible::before { transform: scaleX(1); }

/* The secondary drops a shadow on hover too, but its own — node 1274:6193
   draws it softer and one pixel deeper than the primary's. */
.cw-cta--wipe .cw-cta__btn--secondary {
  transition: box-shadow var(--cta-dur) var(--cta-ease),
              color var(--cta-dur) var(--cta-ease);
}
.cw-cta--wipe .cw-cta__btn--secondary:hover,
.cw-cta--wipe .cw-cta__btn--secondary:focus-visible {
  box-shadow: 0 4px 3px rgba(0, 0, 0, .15);
  color: var(--scheme-btn-fill-ink);
}

/* --- states from node 1296:6214 (the bounce CTA) ------------------------ */

/* The label leaves through the top of the button and comes back in from the
   bottom. The node's own frames only throw it about 20px, but that is a
   sampled pose, not the extreme: a 20px line box centred in a 44px button
   needs 32px of travel before it is fully outside, so the throw here is 34
   and the swap between the two sides lands while nothing is visible. The
   button clips, which is what the node's overflow-clip on the middle frames
   is there for.

   Out-one-side-in-the-other cannot be a transition, so it is a keyframe that
   micro-interactions.js restarts on entry. */
.cw-cta--roll {
  --label-throw: 34px;          /* 22 to the edge + half the 20px line box */
  --label-dur:   .45s;
}

.cw-cta--roll .cw-cta__btn { overflow: hidden; }

.cw-cta--roll .cw-cta__btn--primary:hover,
.cw-cta--roll .cw-cta__btn--primary:focus-visible {
  box-shadow: 0 3px 4px rgba(0, 0, 0, .15);
}
.cw-cta--roll .cw-cta__btn--secondary {
  transition: box-shadow var(--cta-dur) var(--cta-ease);
}
.cw-cta--roll .cw-cta__btn--secondary:hover,
.cw-cta--roll .cw-cta__btn--secondary:focus-visible {
  box-shadow: 0 3px 8px rgba(0, 0, 0, .15);
}

@keyframes cw-label-roll {
  0% {
    transform: translateY(0);
    animation-timing-function: cubic-bezier(.55, 0, 1, .45);   /* accelerate out */
  }
  49% {
    transform: translateY(calc(var(--label-throw) * -1));
    /* hold, then jump — without this the 49→50 segment interpolates and the
       label sweeps back through the centre in ~4ms, which lands on a rendered
       frame often enough to read as a flicker */
    animation-timing-function: steps(1, end);
  }
  50% {
    transform: translateY(var(--label-throw));
    animation-timing-function: cubic-bezier(0, .55, .45, 1);   /* decelerate in */
  }
  100% { transform: translateY(0); }
}

.cw-cta--roll .cw-cta__btn > span.is-rolling {
  animation: cw-label-roll var(--label-dur) both;
}

/* leaving runs the same keyframes backwards: down and out of the bottom, back
   in over the top. `reverse` mirrors the per-keyframe easing too, so the hold
   and the jump stay a hold and a jump — just at the other end of the window. */
.cw-cta--roll .cw-cta__btn > span.is-rolling-back {
  animation: cw-label-roll var(--label-dur) reverse both;
}

/* --- states from node 1308:6266 (the fade CTA) -------------------------- */

/* No wipe and no travel here: both buttons just change fill.

   The node draws the primary's hover as a rgba(255,255,255,.15) layer sitting
   on the button's own colour, so that is what this is — a veil that fades in,
   rather than a second colour hardcoded. Same result, but it survives the
   base colour changing. */
.cw-cta--fade { --cta-dur: .2s; }

.cw-cta--fade .cw-cta__btn--secondary {
  transition: background-color var(--cta-dur) var(--cta-ease);
}
.cw-cta--fade .cw-cta__btn--secondary:hover,
.cw-cta--fade .cw-cta__btn--secondary:focus-visible {
  background-color: var(--scheme-btn-fill);
  color: var(--scheme-btn-fill-ink);
}

.cw-cta--fade .cw-cta__btn--primary::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--scheme-veil);
  opacity: 0;
  transition: opacity var(--cta-dur) var(--cta-ease);
}
.cw-cta--fade .cw-cta__btn--primary:hover::before,
.cw-cta--fade .cw-cta__btn--primary:focus-visible::before { opacity: 1; }

/* ----------------------------------------------------------------- cards -- */
.cw-cta__cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

/* The whole card is the link, not just the arrow inside it — so the pointer
   and the arrow's animation come from anywhere on the card. */
.cw-cta__card {
  --btn-ring: var(--scheme-ring);   /* the chev button reads this */

  background: var(--scheme-card-bg);
  color: var(--scheme-card-ink);
  min-height: 400px;
  padding: 40px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 40px;
  text-decoration: none;
  cursor: pointer;
  outline: none;
  position: relative;           /* holds the hover overlay */
}
.cw-cta__card:focus-visible { outline: 2px solid var(--scheme-card-ink); outline-offset: -6px; }

/* A flat 10% black wash over the whole card on hover. It sits above the copy
   rather than under it — an overlay darkens everything, which is the point —
   and takes no pointer events so the card stays one clickable surface. */
.cw-cta__card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--cta-dur) var(--cta-ease);
}
.cw-cta__card:hover::after,
.cw-cta__card:focus-visible::after { opacity: .1; }
.cw-cta__card + .cw-cta__card { border-left: 1px solid var(--scheme-card-rule); }

.cw-cta__card-title {
  margin: 0;
  font-size: 44px;
  line-height: 48px;
  font-weight: 500;
  letter-spacing: -1.32px;
}
.cw-cta__card-foot { display: flex; flex-direction: column; gap: 24px; align-items: flex-start; }
.cw-cta__card-body { margin: 0; font-size: 16px; line-height: 22px; }

/* the arrow button's own link; the glyph is currentColor, so white here */
.cw-arrow-link {
  display: inline-flex;
  color: inherit;
  text-decoration: none;
  outline: none;
}
.cw-arrow-link:focus-visible { outline: 2px solid var(--white); outline-offset: 4px; }

/* ------------------------------------------------------------ responsive -- */
@media (max-width: 1024px) {
  .cw-cta { padding: 48px 24px; }
  .cw-cta__cards { grid-template-columns: 1fr; }
  .cw-cta__card + .cw-cta__card { border-left: 0; border-top: 1px solid var(--white); }
  .cw-cta__hero, .cw-cta__card { min-height: 0; }
  .cw-cta__title, .cw-cta__card-title { font-size: 34px; line-height: 38px; letter-spacing: -1px; }
}
@media (max-width: 560px) {
  .cw-cta__hero, .cw-cta__card { padding: 24px; }
  .cw-cta__title, .cw-cta__card-title { font-size: 28px; line-height: 32px; }
  .cw-cta__actions { gap: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .cw-cta__card::after,
  .cw-cta__btn--primary,
  .cw-cta__btn--secondary,
  .cw-cta--wipe .cw-cta__btn--primary::before,
  .cw-cta--wipe .cw-cta__btn--secondary::before,
  .cw-cta--fade .cw-cta__btn--primary::before { transition-duration: .01ms; }
  .cw-cta--roll .cw-cta__btn > span.is-rolling,
  .cw-cta--roll .cw-cta__btn > span.is-rolling-back { animation-duration: .01ms; }
}

/* =========================================================================
   CTA layouts — Figma node 1323:6723

   Eight arrangements of the same block, switched by the header buttons. The
   hero is identical in all eight, so only the card rows below it swap.

   Card title size follows the card's width, which is what the frames do:
   anything 400 wide or more takes Title/1 (44/48, -1.32), the four-up rows
   drop to Title/2 (32/38, -0.96). One exception in the file — layout 6 draws
   its two-up row at Title/2 even though the cards are 640 wide, unlike the
   identical row in layout 4. Treated as a slip and left on Title/1.
   ========================================================================= */

.cw-cta__layout[hidden] { display: none; }

.cw-cta__row { display: flex; }
.cw-cta__row + .cw-cta__row { border-top: 1px solid var(--scheme-card-rule); }

/* equal columns regardless of how much copy each card holds — without this
   they size to their text and a row of unequal blurbs comes out ragged */
.cw-cta__row > .cw-cta__card { flex: 1 0 0; min-width: 0; }

/* four-up cards are narrow enough to step the title down */
.cw-cta__row--4 .cw-cta__card-title {
  font-size: 32px;
  line-height: 38px;
  letter-spacing: -.96px;
}

/* ------------------------------------------------------------- carousel -- */
.cw-cta__carousel {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.cw-cta__carousel::-webkit-scrollbar { display: none; }

.cw-cta__track { display: flex; }

.cw-cta__carousel .cw-cta__card {
  flex: 0 0 var(--card-w);
  width: var(--card-w);
  scroll-snap-align: start;
}

.cw-cta__dots {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 80px;
  padding: 0 40px;
  background: var(--scheme-hero-bg);
}
.cw-cta__dot {
  width: 16px;
  height: 16px;
  flex: none;
  padding: 0;
  border: 0;
  border-radius: 1000px;
  background: var(--scheme-hero-ink);
  opacity: .5;
  cursor: pointer;
  transition: opacity .2s ease;
}
.cw-cta__dot[aria-current="true"] { opacity: 1; }
.cw-cta__dot:focus-visible { outline: 2px solid var(--scheme-hero-ink); outline-offset: 3px; }

@media (max-width: 1024px) {
  .cw-cta__row { flex-direction: column; }
  .cw-cta__row .cw-cta__card + .cw-cta__card { border-left: 0; border-top: 1px solid var(--scheme-card-rule); }
  .cw-cta__row--4 .cw-cta__card-title { font-size: 28px; line-height: 32px; }
  .cw-cta__carousel .cw-cta__card { flex-basis: 85vw; width: 85vw; }
}

/* =========================================================================
   Split layouts — Figma node 1332:6812

   Three arrangements of the left panel, switched by the header buttons.

     1  Figma 1332:6782 — no arrow per row. Titles step up to Title/2 and the
        copy to Feature/Regular, and a single arrow sits at the foot of the
        panel. That arrow is a .cw-arrow-link, which is why every behaviour
        above now answers to one as well as to a row.
     2  Figma 1332:6725 — the arrangement built first: title, copy, arrow.
     3  Figma 1332:6756 — a Title/1 heading under the eyebrow, then rows that
        are title and arrow only, no copy.
   ========================================================================= */

/* ------------------------------------------------ layout 1: feature rows -- */

/* This layout carries the most text, and real line boxes run taller than the
   trimmed ones the frame measures — its list comes out ~97px above the
   frame's 463. The 64px floor on top of that pushed the panel to 832 while
   every other layout sits at 780. Lowering the floor lets space-between
   absorb the difference and keeps all four blocks the same height. */
.cw-split__layout[data-layout="1"] { gap: 24px; }

.cw-feature {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 40px 0;
}
.cw-feature__title {
  font-size: 32px;
  line-height: 38px;
  font-weight: 500;
  letter-spacing: -.96px;
}
.cw-feature__body { font-size: 18px; line-height: 26px; }

/* the panel's own arrow, not attached to any one row */
.cw-split__foot { display: flex; }
.cw-split__foot .cw-arrow-link { color: inherit; text-decoration: none; outline: none; }
.cw-split__foot .cw-arrow-link:focus-visible {
  outline: 2px solid var(--panel-ink);
  outline-offset: 4px;
}

/* ------------------------------------------------------ layout 3: intro -- */
.cw-split__intro { display: flex; flex-direction: column; gap: 40px; }
.cw-split__heading {
  margin: 0;
  font-size: 44px;
  line-height: 48px;
  font-weight: 500;
  letter-spacing: -1.32px;
}

/* rows carry no copy here, so the link is title and arrow only */
.cw-split__layout--titles .cw-item__link { padding: 40px 20px 40px 0; }

@media (max-width: 560px) {
  .cw-feature { padding: 28px 0; gap: 16px; }
  .cw-feature__title { font-size: 26px; line-height: 30px; }
  .cw-feature__body { font-size: 16px; line-height: 24px; }
  .cw-split__heading { font-size: 30px; line-height: 34px; letter-spacing: -1px; }
}

/* =========================================================================
   Scroll reveal

   Text fades up as a block comes into view. Gated on the `js` class the head
   script sets, so with no JavaScript the copy is simply visible rather than
   stuck at zero opacity — the reveal is decoration and must never be the
   reason something cannot be read.

   The switch is a class on the section, not on each element, so a layout that
   was hidden when its block scrolled past is already in its final state by
   the time the buttons reveal it — no second animation, no invisible text.
   ========================================================================= */

.js :is(
  .cw-eyebrow,
  .cw-split__heading,
  .cw-item__title,
  .cw-item__body,
  .cw-feature__title,
  .cw-feature__body,
  .cw-cta__title,
  .cw-cta__lede,
  .cw-cta__actions,
  .cw-cta__card-title,
  .cw-cta__card-body
) {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity   .6s cubic-bezier(.16, 1, .3, 1),
    transform .6s cubic-bezier(.16, 1, .3, 1);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .is-revealed :is(
  .cw-eyebrow,
  .cw-split__heading,
  .cw-item__title,
  .cw-item__body,
  .cw-feature__title,
  .cw-feature__body,
  .cw-cta__title,
  .cw-cta__lede,
  .cw-cta__actions,
  .cw-cta__card-title,
  .cw-cta__card-body
) {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .js :is(
    .cw-eyebrow,
    .cw-split__heading,
    .cw-item__title,
    .cw-item__body,
    .cw-feature__title,
    .cw-feature__body,
    .cw-cta__title,
    .cw-cta__lede,
    .cw-cta__actions,
    .cw-cta__card-title,
    .cw-cta__card-body
  ) {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
