/* Layout of /plans/: only grids, widths and vertical rhythm, for the same reason as in
   home/css/pages/index.css — the design system ships no page layout. */

/* ---------- Hero ---------- */
/* 72px less than the hero, not a fixed height: the hero measures differently with and without the
   diagram, and when the layer reaches the edge .qf-mesh's overflow cuts it dead before the blur fades it. */
.plans-hero { --mesh-height: calc(100% - 72px); }

.plans-hero__nav { padding-top: var(--space-lg); }

/* The bottom padding is ALL the space up to the next section: .plans-section adds no top padding.
   align-items:start starts the title and the diagram's first bar at the same height. */
.plans-hero__body {
  display: grid;
  grid-template-columns: minmax(0, 400px) minmax(0, 1fr);
  gap: var(--space-xl);
  align-items: start;
  padding-top: 72px;
  padding-bottom: 72px;
}

@media (max-width: 900px) {
  .plans-hero__body { grid-template-columns: minmax(0, 1fr); }
}

/* In two columns the 400px track caps it; this only matters once the diagram moves below. */
.plans-hero__copy { max-width: 560px; }

/* The 18px above separated it from the "Pricing" pill, which is gone: the title opens the hero. */
.plans-hero__title {
  margin: 0 0 14px;
  text-wrap: pretty;
}

.plans-hero__lead { color: var(--text-secondary); }

/* ---------- Billing diagram ---------- */
/* The figure sits over the mesh, so .qf-cpubill's own background (--surface-page) would cover the
   gradient. */
.plans-hero__figure {
  margin: 0;
  justify-self: end;
}

.plans-hero__figure .qf-cpubill { background: transparent; }

/* The fill's width and the job's position are data, not style: the markup declares them and
   billing_diagram.js moves them during the animation. */
.plans-hero__figure .qf-cpubill__fill { width: var(--cpubill-fill, 0px); }

.plans-hero__figure .qf-cpubill__job { left: var(--cpubill-job-left, 40px); }

/* The canvas is 740px and is shrunk whole with a transform: below 600px it drops under 80% and the
   diagram's pills become unreadable. The hero's copy already says the same in words. */
@media (max-width: 600px) {
  .plans-hero__figure { display: none; }
}

/* ---------- Section rhythm ---------- */
/* .qf-section carries 96px above and below. The design chains the sections without the top padding:
   the hero already separated enough and between sections the bottom padding is enough. */
.plans-section { padding-top: 0; }

.plans-section__title { margin-bottom: var(--space-xl); }

/* The page's last section: the design closes it with 96px. */
.plans-section--faq { padding-bottom: 96px; }

.plans-alert { margin-bottom: var(--space-xl); }

/* ---------- Billing period variants ---------- */
/* wireBillingToggle() hides through the "hidden" attribute, which the design system's reset already
   handles with [hidden]{display:none!important}. */

/* .qf-tag is inline-flex, so without this "Save 20%" breaks into two lines as soon as the container
   tightens. */
.plans-tier__save,
.plans-compare__save,
.plans-billing__save { white-space: nowrap; }

/* ---------- Billing period toggle ---------- */
/* The design separates it from the cards with 32px, but there none of them sticks out upwards: the
   featured one grows 8% from its centre and with cards this tall it rode over the toggle. */
.plans-billing {
  display: flex;
  justify-content: center;
  margin: 0 0 var(--space-huge);
  padding: 0;
  border: 0;
}

/* The <legend> names the radio group for screen readers; the design does not show it. */
.plans-billing__legend {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.plans-billing__switch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
}

/* The radio is still the state (and the focus target); what you see is its <label>. */
.plans-billing__radio {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.plans-billing__opt {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  height: 36px;
  padding: 0 18px;
  border-radius: var(--radius-pill);
  font-size: var(--size-button-md);
  line-height: var(--lh-button-md);
  letter-spacing: var(--track-button-md);
  color: var(--text-muted);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}

.plans-billing__opt:hover { color: var(--text-body); }

/* The same pair .qf-theme-switch__opt--on uses for a segmented control's active option. */
.plans-billing__radio:checked + .plans-billing__opt {
  background: var(--action-tag-bg);
  color: var(--action-tag-text);
}

/* Keyboard focus lands on the radio, which is invisible: it is drawn on the label instead. */
.plans-billing__radio:focus-visible + .plans-billing__opt {
  outline: 2px solid var(--border-input-focus);
  outline-offset: 2px;
}

/* The annual option carries the pill inside and needs less air on that side. */
.plans-billing__opt:has(.plans-billing__save) { padding-right: 14px; }

/* ---------- Plan row ---------- */
/* The design fixes 4 columns and centres them. Flex and not grid: with fewer plans than columns, an
   auto-fit grid's tracks split the whole width and a single card measured 1152px. */
.plans-tiers {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-xl);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* 280px is what the card measures with all 4 columns filled: the cap wins over how many plans are
   visible. display:grid + stretch keeps them the same height even when the content varies. */
.plans-tiers__item {
  display: grid;
  flex: 1 1 260px;
  max-width: 280px;
}

/* The featured one grows 8% and lifts with elevation 2, as in the design. The z-index keeps it above
   its neighbours, which the extra width overlaps. */
.plans-tiers__item--featured {
  position: relative;
  z-index: 2;
  transform: scale(1.08);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-panel);
}

.plans-tier {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.plans-tier__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
}

.plans-tier__name { margin: 0; }

/* .qf-price already carries margin-top; here only the savings pill is aligned with the price. */
.plans-tier__save { margin-left: var(--space-sm); }

/* The period takes a whole line: sharing it with the price and the pill, "/ month, billed annually"
   had under 100px and broke into three lines. */
.plans-tier .qf-price[data-billing="annually"] {
  flex-wrap: wrap;
  row-gap: var(--space-xs);
}

.plans-tier .qf-price[data-billing="annually"] .qf-price__period {
  order: 1;
  flex-basis: 100%;
}

.plans-tier__desc { margin-bottom: 0; }

.plans-tier__features { margin-bottom: var(--space-xl); }

/* It pushes the CTA to the bottom of the card: every card in the row aligns it at the same height. */
.plans-tier__actions { margin-top: auto; }

/* ---------- Comparison table ---------- */
/* The horizontal scroll lives here, not on the <body>: on narrow screens the table scrolls on its own. */
.plans-compare { overflow-x: auto; }

.plans-compare .qf-table { min-width: 640px; }

/* The recommended plan's column is tinted, like "Studio"'s in the design. The selector repeats
   .qf-table to beat th/td's default colour on specificity. */
.qf-table th.plans-compare__feature,
.qf-table td.plans-compare__feature,
.qf-table tr:hover td.plans-compare__feature {
  background: var(--surface-feature);
  color: var(--feature-ink);
}

.qf-table th.plans-compare__feature--first { border-radius: var(--radius-md) var(--radius-md) 0 0; }

.qf-table td.plans-compare__feature--last { border-radius: 0 0 var(--radius-md) var(--radius-md); }

.plans-compare__save { margin-left: var(--space-sm); }

/* ---------- FAQ ---------- */
/* Two fixed columns, as in the design: with auto-fit three fitted at 1200px and the fourth question
   was left alone on a row. */
.plans-faq {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-xl) var(--space-huge);
  align-items: start;
}

.plans-faq__q { margin-bottom: var(--space-xs); }

.plans-faq__a { color: var(--text-secondary); }

/* ---------- Plan change modal ---------- */
/* The design has no modal; it is built from the design system's surfaces. */
.plans-modal {
  width: min(440px, calc(100vw - var(--space-huge)));
  padding: var(--space-xxl);
  border: 1px solid var(--border-hairline);
  border-radius: var(--radius-card);
  background: var(--surface-card);
  color: var(--text-body);
  box-shadow: var(--shadow-panel);
}

/* The scrim: the brand's ink with alpha, never pure black. */
.plans-modal::backdrop { background: rgba(13, 53, 61, .4); }

.plans-modal__loading,
.plans-modal__summary {
  margin-top: var(--space-lg);
  color: var(--text-secondary);
}

.plans-modal__summary p + p { margin-top: var(--space-sm); }

/* The JS toggles this alert (and __loading/__summary) through the "hidden" attribute; the design
   system's reset is what makes that win over .qf-alert's display:flex, see the .plan-variant comment above. */
.plans-modal__error { margin-top: var(--space-lg); }

.plans-modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-md);
  margin-top: var(--space-xl);
}

/* ---------- Narrow ---------- */
/* The featured one's 8% only makes sense while the cards are in a row: stacked, that extra width
   spills out of the container. The shadow and the order are kept. */
@media (max-width: 900px) {
  .plans-tiers__item--featured { transform: none; }

  /* Two FAQ columns at this width leave lines of 4 words. */
  .plans-faq { grid-template-columns: 1fr; }
}
