/* ==========================================================================
   Pricing (pricing.html)
   The page's title, then a strip of the services, each with its starting price; choosing one
   (a tab list, pricing.js) shows that service's plans as cards below, with
   the service's name and words beside them. The ink block slides and
   stretches along the strip to the service chosen (a white-on-ink copy of
   the strip, cut to it by a clip, so the words invert exactly at its edge).
   Every panel sits in the same grid cell, so the section is always as tall
   as the tallest and nothing below it jumps when the service changes. The
   plans come from tools/pricing/build.py (edit the prices there).
   Motion: on load (see "reveal"), the header, the title letter by letter,
   the line word by word, the strip unrolling tab by tab with its prices
   counting up, each tab's + and then the ink; the cards rise as they come
   into view, prices rolling and any usual price struck through. A change
   of service: the cards and title leave, then the new ones play in.
   On narrow screens the strip and the cards swipe sideways.
   ========================================================================== */

.pricing {
  position: relative;
  z-index: 1;
  padding: clamp(96px, 15vh, 176px) var(--gutter) clamp(96px, 16vh, 180px);
  background: var(--bone);
}

/* Paper grain, as on the rest of the page. */
.pricing::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("../assets/textures/grain.webp") repeat;
  background-size: 160px 160px;
  opacity: 0.55;
  pointer-events: none;
}

.pricing > * {
  position: relative;
}

/* ------------------------------------------------------------------ head */

/* The page: clear of the fixed header, then the title across the width. */
.pricing--page {
  padding-top: calc(var(--header-h) + clamp(24px, 5vh, 64px));
}

.pricing__title {
  margin-top: clamp(20px, 4vh, 44px);
  font-size: clamp(3.75rem, 14.6vw, 17rem);
  font-stretch: var(--wdth-display);
  font-weight: 500;
  line-height: 0.84;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  font-synthesis: none;
}

.pricing__title .pricing__w {
  padding: 0.06em 0.02em 0.02em;
  margin: -0.06em -0.02em -0.02em;
}

.pricing__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
}

.pricing__label {
  font-size: var(--fs-micro);
  font-weight: 400;
}

.pricing__index {
  color: var(--text-mute);
}

.pricing__intro {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 28px 48px;
  margin-top: clamp(28px, 4.5vh, 48px);
}

.pricing__lede {
  max-width: 17ch;
  font-size: clamp(2rem, 3.7vw, 4.5rem);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -0.038em;
}

/* Each word in its own mask (they rise in). The padding keeps descenders. */
.pricing__w,
.ppanel__w {
  display: inline-block;
  overflow: clip;
  padding-bottom: 0.1em;
  margin-bottom: -0.1em;
  vertical-align: top;
}

.pricing__w > span,
.ppanel__w > span {
  display: inline-block;
}

/* ------------------------------------------------------------------ the strip */

/* Above the strip, so it reads as something to press: "Choose a service"
   with a dot that pulses a few times, and "Swipe for all 7" while the strip
   is wider than the screen (pricing.js: is-scrollable), until it's used. */
.pricing__pick {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: clamp(40px, 7vh, 88px);
}

.pricing__pick-say {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.pricing__pick-dot {
  position: relative;
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink);
}

.pricing__pick-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--ink);
  opacity: 0;
  animation: pick-pulse 2200ms var(--ease-out) 1600ms 4;
}

@keyframes pick-pulse {
  0% {
    scale: 1;
    opacity: 0.5;
  }
  70%,
  100% {
    scale: 3.2;
    opacity: 0;
  }
}

.pricing__pick-swipe {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--text-mute);
  opacity: 0;
  transition: opacity 600ms ease;
}

.pricing__pick-swipe svg {
  width: 13px;
  height: 13px;
  animation: pick-nudge 1800ms var(--ease-out) infinite;
}

@keyframes pick-nudge {
  0%,
  100% {
    translate: 0 0;
  }
  40% {
    translate: 4px 0;
  }
}

.pricing.is-scrollable:not(.is-used) .pricing__pick-swipe {
  opacity: 1;
}

@media (max-width: 599px) {
  .pricing__pick-more {
    display: none;
  }

  /* Phones: the swipe line in ink, so it can't be missed. */
  .pricing__pick-swipe {
    color: var(--ink);
  }
}

/* Swipes sideways when they don't all fit (the scrollbar hidden). Then it
   fades out at its right edge, where more waits, until its end is in view
   (pricing.js: is-scrollable, is-end); the fade's length is a registered
   property, so it eases away instead of snapping. */
@property --strip-fade {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

.pricing__strip {
  margin: 14px calc(var(--gutter) * -1) 0;
  padding: 0 var(--gutter);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  transition: --strip-fade 500ms var(--ease-out);
}

.pricing.is-scrollable .pricing__strip {
  --strip-fade: 72px;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--strip-fade)), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - var(--strip-fade)), transparent);
}

.pricing.is-scrollable.is-end .pricing__strip {
  --strip-fade: 0px;
}

.pricing__strip::-webkit-scrollbar {
  display: none;
}

.pricing__tabs,
.pricing__ink {
  display: grid;
  grid-template-columns: repeat(var(--tabs, 8), minmax(148px, 1fr)); /* --tabs: the build's count */
}

.pricing__tabs {
  position: relative;
  width: max-content;
  min-width: 100%;
  border-block: 1px solid var(--line);
}

.ptab {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr auto;
  row-gap: 14px;
  min-height: clamp(128px, 16vh, 168px);
  padding: 18px clamp(16px, 1.3vw, 24px) 20px;
  text-align: left;
  color: var(--ink);
  border-left: 1px solid var(--line);
  transition: background-color 300ms ease;
  -webkit-tap-highlight-color: transparent;
}

.ptab:first-child {
  border-left: 0;
}

.ptab__i {
  color: var(--text-mute);
}

.ptab__name {
  font-size: clamp(1rem, 0.9rem + 0.3vw, 1.25rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.ptab__from {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
}

.ptab__pre {
  flex-basis: 100%;
  margin-bottom: 6px;
  color: var(--text-mute);
}

.ptab__num {
  font-size: clamp(1.625rem, 1.1rem + 1.1vw, 2.5rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
}

.ptab__unit {
  margin-left: 2px;
  font-size: 1rem;
  color: var(--text-mute);
}

/* Hover: an ink line draws along the foot from the side the pointer came in. */
.ptab::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: var(--line-from, 0%) 50%;
  transition: transform 600ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .ptab:hover {
    background: rgb(255 255 255 / 0.5);
  }

  .ptab:hover::after {
    transform: scaleX(1);
  }
}

.ptab:focus-visible {
  outline-offset: -6px;
}

/* The corner: a + in a ring on the strip (it fills and turns on hover);
   in the ink block's copy an arrow down, as the chosen one's plans are
   below. The ink's clip passes over it, so the + becomes the arrow. */
.ptab__go {
  position: absolute;
  top: 11px;
  right: clamp(12px, 1.1vw, 20px);
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  color: var(--ink);
  box-shadow: inset 0 0 0 1px rgb(17 17 17 / 0.2);
  transition:
    background-color 300ms ease,
    color 300ms ease,
    box-shadow 300ms ease,
    opacity 500ms ease calc(1000ms + var(--i, 0) * 70ms),
    scale 750ms var(--ease-out) calc(1000ms + var(--i, 0) * 70ms);
}

.ptab__go svg {
  grid-area: 1 / 1;
  width: 12px;
  height: 12px;
  transition: rotate 450ms var(--ease-out);
}

.ptab__down {
  display: none;
}

@media (hover: hover) and (pointer: fine) {
  .ptab:hover .ptab__go {
    color: var(--white);
    background: var(--ink);
    box-shadow: none;
  }

  .ptab:hover .ptab__plus {
    rotate: 90deg;
  }
}

/* The ink block: the same strip, white on ink, cut to the chosen tab. */
.pricing__ink {
  position: absolute;
  inset: -1px 0;
  color: var(--white);
  background: var(--ink);
  clip-path: inset(0 100% 0 0);
  pointer-events: none;
}

.pricing__ink .ptab {
  color: var(--white);
  border-left-color: rgb(255 255 255 / 0.14);
  transition: none;
}

.pricing__ink .ptab__i,
.pricing__ink .ptab__pre,
.pricing__ink .ptab__unit {
  color: var(--on-ink-mute);
}

.pricing__ink .ptab::after {
  display: none;
}

.pricing__ink .ptab__go {
  color: var(--ink);
  background: var(--white);
  box-shadow: none;
}

.pricing__ink .ptab__plus {
  display: none;
}

.pricing__ink .ptab__down {
  display: block;
}

/* ------------------------------------------------------------------ panels */

.pricing__panels {
  margin-top: clamp(40px, 6.5vh, 80px);
}

.ppanel + .ppanel {
  margin-top: clamp(72px, 10vh, 120px); /* without the script: one after another */
}

/* With the script: every panel in one cell (as tall as the tallest), one showing. */
.pricing.is-tabbed .pricing__panels {
  display: grid;
}

.pricing.is-tabbed .ppanel {
  grid-area: 1 / 1;
  margin: 0;
}

.pricing.is-tabbed .ppanel:not(.is-active):not(.is-leaving) {
  visibility: hidden;
}

.ppanel {
  display: grid;
  align-items: start;
  align-content: start; /* the cell is as tall as the tallest panel: the rest stays at the foot */
  gap: clamp(28px, 4vh, 40px) clamp(32px, 3.2vw, 64px);
}

.ppanel__title {
  font-size: clamp(1.75rem, 2.6vw, 3.25rem);
  font-stretch: 112.5%;
  font-weight: 500;
  line-height: 0.98;
  letter-spacing: -0.012em;
  text-transform: uppercase;
  text-wrap: balance;
}

.ppanel__lede {
  max-width: 30ch;
  margin-top: 20px;
  font-size: clamp(1.0625rem, 0.95rem + 0.35vw, 1.3125rem);
  line-height: 1.4;
  letter-spacing: -0.012em;
  text-wrap: pretty;
}

.ppanel__note {
  max-width: 34ch;
  margin-top: 24px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--text-mute);
  text-wrap: pretty;
}

/* The service's own page, under the note (tools/pricing/build.py 'page'). */
.ppanel__more {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  padding: 6px 0;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.ppanel__more svg {
  width: 14px;
  height: 14px;
  transition: translate 420ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .ppanel__more:hover svg {
    translate: 3px 0;
  }
}

/* Wide screens: the service beside its plans, held while you read down them. */
@media (min-width: 1360px) {
  .ppanel {
    grid-template-columns: minmax(0, 26fr) minmax(0, 74fr);
  }

  .ppanel__aside {
    position: sticky;
    top: calc(var(--header-compact) + 32px);
  }
}

/* ------------------------------------------------------------------ cards */

.ppanel__cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(10px, 0.9vw, 16px);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The li is what pricing.js moves (GSAP owns its transform); the box inside
   takes the hover lift, on `translate`. */
.pcard {
  display: flex;
  min-width: 0;
}

.pcard__box {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: clamp(24px, 1.9vw, 34px);
  border-radius: 18px;
  background: var(--white);
  box-shadow:
    inset 0 0 0 1px rgb(17 17 17 / 0.06),
    var(--shadow-lift);
  transition:
    translate 550ms var(--ease-out),
    box-shadow 550ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .pcard:not(.pcard--ask) .pcard__box:hover {
    translate: 0 -6px;
    box-shadow:
      inset 0 0 0 1px rgb(17 17 17 / 0.06),
      var(--shadow-lift-up);
  }

  .pcard--featured:not(.pcard--ask) .pcard__box:hover {
    box-shadow:
      inset 0 0 0 1px rgb(17 17 17 / 0.06),
      var(--shadow-deep-up);
  }
}

.pcard__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 28px;
}

.pcard__name {
  margin: 0; /* an h4: base.css only resets h1 to h3 */
  font-size: clamp(1.125rem, 0.95rem + 0.4vw, 1.375rem);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.015em;
}

.pcard__tag,
.pcard__badge {
  flex: none;
  padding: 5px 9px;
  border-radius: 999px;
  white-space: nowrap;
}

.pcard__tag {
  box-shadow: inset 0 0 0 1px currentColor;
}

.pcard__badge {
  color: var(--ink);
  background: var(--bone);
}

/* The price: 'from' before it and '/mo' after. */
.pcard__price {
  display: grid;
  grid-template-rows: auto auto;
  align-items: end;
  margin-top: clamp(26px, 4vh, 44px);
}

.pcard__now {
  grid-row: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 6px;
  margin-top: 6px;
  line-height: 1;
}

.pcard__num {
  font-size: clamp(2.5rem, 1.6rem + 1.9vw, 4rem);
  font-weight: 500;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
}

.pcard__pre,
.pcard__unit {
  font-size: 1.0625rem;
  color: var(--text-mute);
  letter-spacing: -0.01em;
}

.pcard__deal {
  margin-top: 12px;
  color: var(--text-mute);
}

.pcard__time {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 8px;
  margin-top: 16px;
  padding: 7px 11px;
  border-radius: 999px;
  background: var(--bone);
}

.pcard__time i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

.pcard__sum {
  margin-top: 18px;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: rgb(17 17 17 / 0.72);
  text-wrap: pretty;
}

.pcard__list {
  display: grid;
  gap: 11px;
  margin: 22px 0 30px;
  padding: 22px 0 0;
  border-top: 1px solid var(--line);
  list-style: none;
  font-size: 0.9375rem;
  line-height: 1.35;
}

.pcard__list li {
  position: relative;
  padding-left: 27px;
}

/* A tick in a filled circle. */
.pcard__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.05em;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.6 8.3 7 10.6l4.4-5' fill='none' stroke='%23fff' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 100% no-repeat,
    var(--ink);
}

.pcard__cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 52px;
  margin-top: auto;
  padding: 0 22px;
  border-radius: 999px;
  color: var(--white);
  background: var(--ink);
  font-size: 0.9375rem;
  font-weight: 500;
  transition:
    background-color 300ms ease,
    color 300ms ease,
    box-shadow 300ms ease,
    scale 240ms var(--ease-out);
}

.pcard__cta svg {
  flex: none;
  width: 15px;
  height: 15px;
  transition: rotate 420ms var(--ease-out);
}

.pcard__cta:active {
  scale: 0.97;
}

.pcard__cta:focus-visible {
  border-radius: 999px;
}

@media (hover: hover) and (pointer: fine) {
  .pcard__cta:hover {
    background: #262626;
  }

  /* Like "Work with us": it opens the form where you are. */
  .pcard__cta:hover svg {
    rotate: 45deg;
  }
}

/* The featured plan: ink, lit from its top corner. */
.pcard--featured .pcard__box {
  color: var(--bone);
  background: radial-gradient(120% 70% at 0% 0%, #2b2b2b 0%, var(--ink) 58%);
  /* Same layer shape as the hover, so the lift eases instead of snapping. */
  box-shadow:
    inset 0 0 0 1px rgb(17 17 17 / 0.06),
    var(--shadow-deep);
}

.pcard--featured .pcard__pre,
.pcard--featured .pcard__unit,
.pcard--featured .pcard__deal {
  color: var(--on-ink-mute);
}

.pcard--featured .pcard__time {
  background: rgb(255 255 255 / 0.1);
}

.pcard--featured .pcard__sum {
  color: rgb(247 245 242 / 0.72);
}

.pcard--featured .pcard__list {
  border-top-color: rgb(255 255 255 / 0.14);
}

.pcard--featured .pcard__list li::before {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.6 8.3 7 10.6l4.4-5' fill='none' stroke='%23111' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 100% no-repeat,
    var(--bone);
}

.pcard--featured .pcard__cta {
  color: var(--ink);
  background: var(--bone);
}

.pcard--featured .pcard__cta:focus-visible {
  outline-color: var(--bone);
}

@media (hover: hover) and (pointer: fine) {
  .pcard--featured .pcard__cta:hover {
    background: var(--white);
  }
}

/* Two plans: a third tile for anyone not sure which. */
.pcard--ask .pcard__box {
  background: none;
  box-shadow: none;
  border: 1.5px dashed rgb(17 17 17 / 0.22);
}

.pcard__ask {
  max-width: 10ch;
  font-size: clamp(1.625rem, 1.1rem + 1.1vw, 2.5rem);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -0.035em;
}

.pcard--ask .pcard__sum {
  max-width: 30ch;
  margin-bottom: 30px;
}

.pcard--ask .pcard__cta {
  color: var(--ink);
  background: none;
  box-shadow: inset 0 0 0 1.5px var(--ink);
}

@media (hover: hover) and (pointer: fine) {
  .pcard--ask .pcard__cta:hover {
    color: var(--white);
    background: var(--ink);
  }
}

/* Below 1024px: the plans swipe sideways, each card snapping to the edge,
   the next one peeking in. */
@media (max-width: 1023px) {
  .ppanel__cards {
    display: flex;
    gap: 12px;
    /* Room under the cards for their shadows (a scroller clips them, which
       left a hard line), given back by the margin so the spacing is kept. */
    margin: 0 calc(var(--gutter) * -1) -36px;
    padding: 4px var(--gutter) 64px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gutter);
    scrollbar-width: none;
  }

  .ppanel__cards::-webkit-scrollbar {
    display: none;
  }

  .pcard {
    flex: 0 0 min(84vw, 380px);
    scroll-snap-align: start;
  }
}

/* ------------------------------------------------------------------ reveal */

/* The load-in (html.is-entered, from the inline script after the section,
   as soon as the title's type has loaded; it doesn't wait for the scripts).
   In order: the header drops in, the top line, the title letter by letter,
   the line word by word, "Choose a service", the strip
   unrolling tab by tab with its prices counting up (the inline script),
   each tab's + popping in, then the ink (pricing.js). Hidden only while JS
   is on and the page hasn't entered, so nothing shows, vanishes and shows
   again; the head's safety net enters it after 5s regardless. */
html.js:not(.is-entered) .site-header > * {
  opacity: 0;
  transform: translateY(-16px);
}

html.js:not(.is-entered) .pricing [data-enter] {
  opacity: 0;
  translate: 0 14px;
}

html.js:not(.is-entered) .pricing__title .pricing__l,
html.js:not(.is-entered) .pricing__lede .pricing__w > span {
  transform: translateY(108%);
}

html.js:not(.is-entered) .ptab {
  clip-path: inset(-2px 100% -2px 0);
}

html.js:not(.is-entered) .ptab__go {
  opacity: 0;
  scale: 0.4;
}

/* The header's own move (compacting) stays on translate, untouched. */
.site-header > * {
  transition:
    translate 600ms var(--ease-out),
    opacity 800ms ease,
    transform 1100ms var(--ease-out);
}

.site-header__actions {
  transition-delay: 0ms, 90ms, 90ms;
}

.pricing [data-enter] {
  transition:
    opacity 800ms ease calc(160ms + var(--e, 0) * 90ms),
    translate 1000ms var(--ease-out) calc(160ms + var(--e, 0) * 90ms);
}

.pricing__title .pricing__l {
  transition: transform 1300ms var(--ease-out) calc(120ms + var(--l, 0) * 45ms);
}

.pricing__lede .pricing__w > span {
  transition: transform 1150ms var(--ease-out) calc(340ms + var(--w, 0) * 40ms);
}

.ptab {
  clip-path: inset(-2px -1px -2px 0);
  transition:
    background-color 300ms ease,
    clip-path 1100ms var(--ease-out) calc(480ms + var(--i, 0) * 70ms);
}

/* The cards stay hidden until pricing.js plays them in, as they come into
   view (or the safety net gives up on it). */
html.js:not(.pricing-static) .pricing:not(.is-shown) .ppanel .pcard,
html.js:not(.pricing-static) .pricing:not(.is-shown) .ppanel__w > span,
html.js:not(.pricing-static) .pricing:not(.is-shown) .ppanel__lede,
html.js:not(.pricing-static) .pricing:not(.is-shown) .ppanel__note {
  opacity: 0;
}

/* ------------------------------------------------------------------ the close */

/* After the plans: a call, not a pitch, the way to start and what happens next. */
.pricing-end {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: start;
  gap: clamp(18px, 3vh, 28px);
  padding: clamp(96px, 16vh, 180px) var(--gutter) clamp(110px, 18vh, 200px);
  background: var(--bone);
  border-top: 1px solid var(--line);
}

.pricing-end::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("../assets/textures/grain.webp") repeat;
  background-size: 160px 160px;
  opacity: 0.55;
  pointer-events: none;
}

.pricing-end > * {
  position: relative;
}

.pricing-end__label {
  color: var(--text-mute);
}

.pricing-end__title {
  font-size: clamp(2.75rem, 7.2vw, 8.5rem);
  font-stretch: var(--wdth-display);
  font-weight: 500;
  line-height: 0.92;
  letter-spacing: -0.012em;
  text-transform: uppercase;
  font-synthesis: none;
  text-wrap: balance;
}

/* Under the title: the words and the buttons, and beside them (stacked
   below on narrow screens) what happens after you ask. */
.pricing-end__body {
  justify-self: stretch;
  display: grid;
  align-items: start;
  gap: clamp(48px, 7vh, 72px) clamp(40px, 5vw, 104px);
  margin-top: clamp(4px, 1vh, 12px);
}

@media (min-width: 1024px) {
  .pricing-end__body {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  }
}

.pricing-end__lead {
  display: grid;
  justify-items: start;
  gap: clamp(18px, 3vh, 28px);
}

.pricing-end__text {
  max-width: 34ch;
  font-size: clamp(1.125rem, 1rem + 0.45vw, 1.5rem);
  line-height: 1.38;
  letter-spacing: -0.015em;
  text-wrap: pretty;
}

.pricing-end__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 28px;
  margin-top: 8px;
}

.pricing-end__next-label {
  margin-bottom: 18px;
  color: var(--text-mute);
}

.pricing-end__steps {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(24px, 2.4vw, 44px);
  margin: 0;
  padding: 0;
  list-style: none;
}

.pricing-end__step {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-content: start;
  column-gap: 18px;
  padding: 20px 0 30px;
  border-top: 1px solid var(--line);
}

.pricing-end__n {
  grid-row: span 2;
  padding-top: 0.35em;
  color: var(--text-mute);
}

.pricing-end__step-title {
  font-size: clamp(1.0625rem, 0.95rem + 0.35vw, 1.3125rem);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.015em;
}

.pricing-end__step-text {
  max-width: 36ch;
  margin-top: 6px;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: rgb(17 17 17 / 0.68);
  text-wrap: pretty;
}

@media (max-width: 599px) {
  .pricing-end__steps {
    grid-template-columns: minmax(0, 1fr);
  }

  .pricing-end__step {
    padding-bottom: 22px;
  }
}

.pricing-end__link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 1rem;
  font-weight: 500;
}

.pricing-end__link svg {
  width: 15px;
  height: 15px;
  transition: translate 420ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .pricing-end__link:hover svg {
    translate: 3px 0;
  }
}

.pricing-end.is-armed .pricing__w > span {
  transform: translateY(108%);
  transition: transform 1150ms var(--ease-out) calc(var(--w, 0) * 70ms);
}

.pricing-end.is-armed .pricing-end__label,
.pricing-end.is-armed .pricing-end__text,
.pricing-end.is-armed .pricing-end__actions {
  opacity: 0;
  translate: 0 16px;
  transition:
    opacity 800ms ease 300ms,
    translate 1000ms var(--ease-out) 300ms;
}

/* The steps follow the words in, one after another. */
.pricing-end.is-armed .pricing-end__next-label,
.pricing-end.is-armed .pricing-end__step {
  opacity: 0;
  translate: 0 16px;
  transition:
    opacity 800ms ease calc(450ms + var(--s, 0) * 90ms),
    translate 1000ms var(--ease-out) calc(450ms + var(--s, 0) * 90ms);
}

.pricing-end.is-in .pricing__w > span {
  transform: none;
}

.pricing-end.is-in .pricing-end__label,
.pricing-end.is-in .pricing-end__text,
.pricing-end.is-in .pricing-end__actions,
.pricing-end.is-in .pricing-end__next-label,
.pricing-end.is-in .pricing-end__step {
  opacity: 1;
  translate: none;
}

/* ------------------------------------------------------------------ responsive */

@media (max-width: 719px) {
  .pricing__intro {
    align-items: flex-start;
  }

  .pricing__tabs,
  .pricing__ink {
    grid-template-columns: repeat(var(--tabs, 8), minmax(142px, 1fr));
  }

  .ptab {
    min-height: 118px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-header > *,
  .pricing-end *,
  .pricing *,
  .pricing *::before,
  .pricing *::after {
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }

  .pricing__pick-dot::after,
  .pricing__pick-swipe svg {
    animation: none;
  }
}

/* Phones: the site's section rhythm (--sec-top / --sec-bot / --sec-end, tokens.css),
   so every gap between two sections reads the same. */
@media (max-width: 719px) {
  /* The plans' scroller already leaves 28px under the cards (for their shadows). */
  .pricing {
    padding-bottom: calc(var(--sec-bot) - 28px);
  }

  .pricing-end {
    padding-top: var(--sec-top);
    padding-bottom: var(--sec-end);
  }
}
