/* ============================================================================
   PAGE COMPOSITION.
   ============================================================================

   site.css holds the components; this holds the arrangements they sit in. The
   split is worth keeping: a .btn belongs to the system and changing it changes
   every page, whereas .hero belongs to one page and cannot.

   Everything here reads tokens.css. There is no raw hex below this line.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   Section rhythm.

   The redesign alternates plain ground and a sunken band down the page. The
   band is the only structural device carrying emphasis, so it is worth having
   exactly one name for it rather than a border-top here and a background there.
   --------------------------------------------------------------------------- */
.section { padding-block: 72px; }
.section-tight { padding-block: 56px; }
.section-lead { padding-block: 88px 72px; }
.section-band {
  background: var(--bg-sunken);
  border-block: 1px solid var(--line-faint);
}
.section-ruled { border-top: 1px solid var(--line-faint); }

/* A heading block: eyebrow, h2, lede. Measure is set in ch so it tracks the
   type scale rather than fighting it at small widths. */
.section-head { max-width: 60ch; margin-bottom: 36px; }
.section-head p { margin: 0; font-size: var(--step-1); color: var(--ink-2); }
.section-head h2 { margin: 0 0 12px; }

/* ---------------------------------------------------------------------------
   Hero.
   --------------------------------------------------------------------------- */
.hero {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--line-faint);
}
/* The glow is one radial ellipse bled off the top edge. It is pointer-events:
   none so it can never eat a click on the nav above it. */
.hero::before {
  content: '';
  position: absolute;
  top: -180px; left: 50%;
  width: 900px; height: 420px;
  transform: translateX(-58%);
  background: radial-gradient(ellipse at center,
    color-mix(in srgb, var(--accent) 17%, transparent), transparent 68%);
  pointer-events: none;
}
.hero-inner { position: relative; max-width: var(--wrap); margin: 0 auto; padding: 88px var(--gutter) 72px; }
.hero-copy { max-width: 74ch; }
.hero h1 { font-size: var(--step-6); margin: 0 0 20px; }
.hero-lede {
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 50ch;
  margin: 0 0 28px;
}
.hero-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 22px; }
.hero-note { font-size: 12.5px; color: var(--ink-3); margin: 0; }

/* The animated marker beside the hero eyebrow. Decorative: it stops dead under
   prefers-reduced-motion and the line still reads. */
.hero-kicker { display: inline-flex; align-items: center; gap: 8px; }
.hero-kicker::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  animation: gmd-pulse 2.4s ease-in-out infinite;
}

/* The diagram panel under the hero copy. */
.hero-figure {
  margin-top: 52px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--line), 0 18px 44px rgba(0, 0, 0, .5);
  padding: 26px 30px 24px;
}
.hero-figure-head { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; margin-bottom: 18px; }
.hero-figure-head .eyebrow-sm { margin: 0 auto 0 0; }
/* The legend is the diagram's key: a short colour swatch and its label. It is
   what makes "indigo is Fetch, orange is dbt" legible without a caption. */
.legend { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; color: var(--ink-3); }
.legend::before { content: ''; width: 7px; height: 2px; background: currentColor; }
.legend-fetch { color: var(--accent); }
.legend-dbt { color: var(--dbt); }

.hero-stats {
  margin-top: 16px; padding-top: 16px;
  border-top: 1px solid var(--line-faint);
  display: flex; flex-wrap: wrap; gap: 18px;
}
.hero-stat-value { font-size: 19px; font-weight: 500; }
.hero-stat-label { font-size: 10.5px; color: var(--ink-3); }

/* ---------------------------------------------------------------------------
   Grids.

   One set of column rules, used by the pillars, the security cards, the
   use-case cards and the integration directory, rather than one per page.
   --------------------------------------------------------------------------- */
.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-tight { gap: 12px; }

/* ---------------------------------------------------------------------------
   Pillars — Fetch, dbt, Pipelines.
   --------------------------------------------------------------------------- */
.pillar {
  display: flex; flex-direction: column; gap: 10px;
  padding: 22px 20px 24px;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  box-shadow: 0 0 0 1px var(--line);
}
.pillar-title { font-size: var(--step-2); font-weight: 500; letter-spacing: -.015em; }
.pillar p { font-size: 13.5px; line-height: 1.6; color: var(--ink-2); margin: 0 0 4px; }
.pillar-points { display: flex; flex-direction: column; gap: 7px; margin-top: auto; padding-top: 6px; }
.pillar-point {
  display: flex; gap: 8px;
  font-size: 12.5px; line-height: 1.5; color: var(--ink-2);
}
.pillar-point::before { content: '—'; color: var(--accent); flex: none; }

/* ---------------------------------------------------------------------------
   Connector inventory — three counted columns in one ruled box.
   --------------------------------------------------------------------------- */
.inventory {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: 0 0 0 1px var(--line);
}
.inventory-col { padding: 22px 20px; background: var(--surface); }
.inventory-col + .inventory-col { border-left: 1px solid var(--line-faint); }
.inventory-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 14px; }
.inventory-count { font-size: var(--step-4); font-weight: 500; color: var(--accent-bright); letter-spacing: -.03em; }
.inventory-label { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.inventory-items { display: flex; flex-wrap: wrap; gap: 6px; }

/* ---------------------------------------------------------------------------
   Feature rows — copy one side, product mockup the other, alternating.
   --------------------------------------------------------------------------- */
.feature-rows { display: flex; flex-direction: column; gap: 64px; }
.feature-row { display: grid; grid-template-columns: 1fr 1fr; gap: 44px; align-items: center; }
/* Every second row swaps sides. Using order rather than a second markup shape
   keeps the DOM in reading order, so the copy still precedes its illustration
   for a screen reader and on a narrow screen. */
.feature-row:nth-child(even) .feature-copy { order: 2; }
.feature-row:nth-child(even) .feature-figure { order: 1; }
.feature-copy h3 { font-size: var(--step-3); margin: 0 0 12px; }
.feature-copy > p { font-size: 14.5px; line-height: 1.65; color: var(--ink-2); margin: 0 0 16px; max-width: 52ch; }
.feature-points { display: flex; flex-direction: column; gap: 8px; }
.feature-point {
  display: flex; gap: 9px;
  font-size: 13.5px; line-height: 1.55; color: var(--ink-2);
}
.feature-point::before {
  content: '';
  flex: none;
  width: 13px; height: 13px;
  margin-top: 4px;
  background: var(--accent);
  /* A tick drawn in CSS rather than 4 inline SVGs per row. */
  clip-path: polygon(13% 47%, 4% 58%, 38% 92%, 96% 26%, 86% 17%, 38% 70%);
}
.feature-caption { font-size: 10.5px; color: var(--ink-3); margin-top: 8px; line-height: 1.5; }

/* ---------------------------------------------------------------------------
   Alert events and roadmap.
   --------------------------------------------------------------------------- */
.chip-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.chip-row-label { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin-right: 6px; }

.roadmap { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; max-width: 900px; }
.roadmap-item {
  display: flex; gap: 10px;
  padding: 13px 15px;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  box-shadow: 0 0 0 1px var(--line-2);
  font-size: 13px; line-height: 1.55; color: var(--ink-2);
}
/* An open circle, not a tick. These are the things that are NOT built, and the
   marker should never be mistakable for a feature bullet two sections up. */
.roadmap-item::before { content: '○'; color: var(--ink-4); font-size: 12px; flex: none; }
.roadmap-item strong { color: var(--ink); font-weight: 500; }

/* ---------------------------------------------------------------------------
   Integration directory.
   --------------------------------------------------------------------------- */
.intg-filters { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 26px; }
.intg-filter {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px;
  border-radius: 20px;
  cursor: pointer;
  font-family: inherit;
  font-size: 12.5px;
  color: var(--ink-2);
  background: var(--surface-2);
  border: 1px solid var(--color-divider);
  transition: background-color .16s, border-color .16s, color .16s;
}
.intg-filter:hover { border-color: var(--accent); color: var(--ink); }
.intg-filter.is-on { background: var(--accent); border-color: var(--accent); color: var(--bg); }
.intg-filter-count { font-size: 10.5px; opacity: .6; }

.intg-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.intg-card {
  display: flex; flex-direction: column;
  text-align: left;
  padding: 18px 17px 19px;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  border: 1px solid var(--line-faint);
  transition: border-color .16s;
}
.intg-card:hover { border-color: var(--accent); text-decoration: none; }
.intg-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.intg-card-name { font-size: var(--step-1); font-weight: 500; color: var(--ink); letter-spacing: -.01em; }
.intg-card-kind { font-size: 9.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-4); white-space: nowrap; }
.intg-card-blurb { font-size: 12.5px; line-height: 1.55; color: var(--ink-2); margin: 8px 0 12px; }
.intg-card-tiers { display: flex; flex-wrap: wrap; gap: 5px; margin-top: auto; }
.intg-empty { padding: 40px 0; color: var(--ink-3); }

/* The tier badge is the answer to "does my plan include this", so an ungranted
   tier still shows — greyed — rather than being omitted. A missing badge reads
   as an oversight; a dim one reads as a no. */
.tier-badge {
  font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
  padding: 3px 7px; border-radius: var(--radius-sm);
  background: var(--accent-soft); color: var(--color-accent-300);
}
.tier-badge-off { background: var(--surface-3); color: var(--ink-4); }

/* ---------------------------------------------------------------------------
   Use cases.
   --------------------------------------------------------------------------- */
.uc-card {
  display: flex; flex-direction: column;
  text-align: left;
  padding: 22px 20px 24px;
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  border: 1px solid var(--line-faint);
  transition: border-color .16s;
}
.uc-card:hover { border-color: var(--accent); text-decoration: none; }
.uc-card-title { font-size: var(--step-2); font-weight: 500; letter-spacing: -.015em; color: var(--ink); margin-bottom: 10px; }
.uc-card-blurb { font-size: 13px; line-height: 1.6; color: var(--ink-2); margin-bottom: 16px; }
.uc-card-more { font-size: 12.5px; color: var(--accent); margin-top: auto; }

.uc-split { display: grid; grid-template-columns: 1fr 1fr; gap: 44px; align-items: start; }
.uc-split h2 { max-width: 22ch; margin: 0 0 16px; }
.uc-split p { font-size: 14.5px; line-height: 1.7; color: var(--ink-2); margin: 0 0 14px; max-width: 54ch; }
.uc-checklist { display: flex; flex-direction: column; gap: 9px; }
.uc-check { display: flex; gap: 9px; font-size: 14px; line-height: 1.6; color: var(--ink-2); }
.uc-check::before {
  content: '';
  flex: none; width: 13px; height: 13px; margin-top: 5px;
  background: var(--accent);
  clip-path: polygon(13% 47%, 4% 58%, 38% 92%, 96% 26%, 86% 17%, 38% 70%);
}

/* ---------------------------------------------------------------------------
   Docs — sticky rail beside eleven numbered steps.
   --------------------------------------------------------------------------- */
.docs-layout { display: grid; grid-template-columns: 190px 1fr; gap: 44px; align-items: start; }
.docs-rail {
  position: sticky;
  top: calc(var(--header-h) + 27px);
  display: flex; flex-direction: column; gap: 1px;
}
.docs-rail a { font-size: 12px; line-height: 1.45; padding: 5px 0; color: var(--ink-3); }
.docs-rail a:hover { color: var(--accent-bright); text-decoration: none; }
.docs-steps { max-width: 70ch; display: flex; flex-direction: column; gap: 40px; }
.docs-step {
  display: grid; grid-template-columns: 38px 1fr; gap: 18px;
  /* Without this the sticky header covers the heading you just jumped to. */
  scroll-margin-top: calc(var(--header-h) + 27px);
}
.docs-step-n {
  width: 32px; height: 32px;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: 13px;
  color: var(--accent-bright);
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}
.docs-step h3 { font-size: var(--step-2); margin: 0 0 12px; }
.docs-step p { font-size: 14.5px; line-height: 1.7; color: var(--ink-2); margin: 0 0 12px; }

/* ---------------------------------------------------------------------------
   Blog.
   --------------------------------------------------------------------------- */
.post-list { display: flex; flex-direction: column; }
.post-item { padding: 24px 0; border-top: 1px solid var(--line-faint); }
.post-date { font-size: var(--step--1); letter-spacing: .04em; color: var(--ink-3); margin-bottom: 8px; }
.post-item h2 { font-size: var(--step-3); margin: 0 0 9px; }
.post-item h2 a { color: var(--ink); }
.post-item h2 a:hover { color: var(--accent); }
.post-excerpt { font-size: 14.5px; line-height: 1.65; color: var(--ink-2); margin: 0; }

/* ---------------------------------------------------------------------------
   Contact.
   --------------------------------------------------------------------------- */
.contact-layout { display: grid; grid-template-columns: 1fr 320px; gap: 28px; align-items: start; max-width: 940px; }
.contact-panel {
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--line);
  padding: 28px 26px 30px;
}
.contact-fields { display: flex; flex-direction: column; gap: 18px; }
.enquiry-options { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.enquiry-option {
  display: flex; align-items: center; gap: 9px;
  padding: 11px 12px;
  border-radius: var(--radius-md);
  cursor: pointer;
  font-size: 13px;
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--color-divider);
  transition: background-color .16s, border-color .16s;
}
.enquiry-option:has(input:checked) { background: color-mix(in srgb, var(--accent) 10%, transparent); border-color: var(--accent); }
.enquiry-option:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.enquiry-option input { position: absolute; opacity: 0; width: 0; height: 0; }
.enquiry-dot {
  flex: none; width: 11px; height: 11px; border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px var(--color-divider);
  transition: background-color .16s, box-shadow .16s;
}
.enquiry-option:has(input:checked) .enquiry-dot { background: var(--accent); box-shadow: inset 0 0 0 1.5px var(--accent); }

.aside-card {
  padding: 18px 18px 20px;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  box-shadow: 0 0 0 1px var(--line);
}
.aside-note {
  padding: 16px 18px;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  box-shadow: 0 0 0 1px var(--line-2);
  font-size: 12.5px; line-height: 1.65; color: var(--ink-3);
}
/* The reCAPTCHA slot. Reserving the box means the form does not jump when the
   widget arrives, and it still reads as deliberate if the keys are unset.

   overflow-x: auto is load-bearing, not defensive. Google's widget is a fixed
   304px iframe we do not control, and with the slot's padding that made the
   contact panel 364px wide inside a 360px phone — the whole page scrolled
   sideways because of one third-party element. It scrolls inside its own box
   instead; the padding also goes at the narrow breakpoint so it rarely has to. */
.captcha-slot {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 12px 14px;
  border-radius: var(--radius-md);
  background: var(--surface-2);
  box-shadow: 0 0 0 1px var(--line-2);
  overflow-x: auto;
}

/* ---------------------------------------------------------------------------
   Plan builder.
   --------------------------------------------------------------------------- */
.builder-layout { display: grid; grid-template-columns: 1fr 336px; gap: 28px; align-items: start; }
.builder-panel {
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--line);
  padding: 28px 26px 30px;
}
.builder-sliders { display: flex; flex-direction: column; gap: 24px; }
.builder-field { min-width: 0; }

/* The no-script submit. It is in the markup rather than created by a script,
   because a control that applies the form must exist when no script runs.
   builder.js puts .js-builder on <html> as its FIRST act, so a throw further
   down leaves this visible rather than stranding someone with a form and no
   way to submit it. */
.builder-submit { margin-top: 22px; }
.js-builder .builder-submit { display: none; }

.slider-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 4px; }
.slider-head label { font-size: 13.5px; color: var(--ink); }
.slider-value { font-size: 14px; font-weight: 500; color: var(--accent); font-variant-numeric: tabular-nums; }
.slider-ends { display: flex; justify-content: space-between; font-size: 10.5px; color: var(--ink-4); margin-top: -2px; }
.slider-hint { font-size: var(--step--1); color: var(--ink-3); margin-top: 5px; }

/* The range track is painted from --fill, which the server renders inline and
   builder.js updates as you drag. Native input, no widget library. */
.slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 22px;
  background: transparent;
  cursor: pointer;
}
.slider::-webkit-slider-runnable-track {
  height: 3px; border-radius: 2px;
  background: linear-gradient(to right,
    var(--accent) var(--fill, 50%), var(--color-neutral-800) var(--fill, 50%));
}
.slider::-moz-range-track {
  height: 3px; border-radius: 2px;
  background: linear-gradient(to right,
    var(--accent) var(--fill, 50%), var(--color-neutral-800) var(--fill, 50%));
}
.slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 15px; height: 15px; margin-top: -6px;
  border-radius: 50%;
  background: var(--bg);
  border: 2px solid var(--accent);
  cursor: grab;
}
.slider::-moz-range-thumb {
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--bg);
  border: 2px solid var(--accent);
  cursor: grab;
}
.slider:focus-visible { outline: none; }
.slider:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--accent); outline-offset: 2px; }
.slider:focus-visible::-moz-range-thumb { outline: 2px solid var(--accent); outline-offset: 2px; }

.builder-divider {
  height: 1px;
  margin: 28px 0 22px;
  background: linear-gradient(to right,
    transparent, var(--color-divider) var(--rule-fade),
    var(--color-divider) calc(100% - var(--rule-fade)), transparent);
}

.toggle-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.toggle {
  display: flex; gap: 10px; align-items: flex-start;
  text-align: left;
  padding: 12px 13px;
  border-radius: var(--radius-md);
  cursor: pointer;
  background: var(--surface-2);
  border: 1px solid var(--color-divider);
  transition: background-color .16s, border-color .16s;
}
.toggle:has(input:checked) { background: color-mix(in srgb, var(--accent) 10%, transparent); border-color: var(--accent); }
.toggle:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
/* The box is the checkbox everywhere it appears -- the toggle grid, the terms
   row on the workspace step, and a togglable add-on. A native checkbox paints
   itself white on this background, which is why none of them use one, and why
   all three reuse THESE rules rather than growing a second box each. */
.toggle input,
.wiz-addon input[type=checkbox] { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle-box {
  flex: none; width: 16px; height: 16px; margin-top: 1px;
  border-radius: var(--radius-sm);
  display: grid; place-items: center;
  font-size: 10px; line-height: 1;
  color: var(--bg);
  border: 1.5px solid var(--color-divider);
  transition: background-color .16s, border-color .16s;
}
.toggle:has(input:checked) .toggle-box,
.field-checkbox:has(input:checked) .toggle-box,
.wiz-addon:has(input:checked) .toggle-box { background: var(--accent); border-color: var(--accent); }
.toggle-box::after { content: '✓'; opacity: 0; }
.toggle:has(input:checked) .toggle-box::after,
.field-checkbox:has(input:checked) .toggle-box::after,
.wiz-addon:has(input:checked) .toggle-box::after { opacity: 1; }
.field-checkbox:has(input:focus-visible) .toggle-box,
.wiz-addon:has(input:focus-visible) .toggle-box { outline: 2px solid var(--accent); outline-offset: 2px; }
.toggle-label { display: block; font-size: 13px; color: var(--ink); }
.toggle-note { display: block; font-size: 11px; color: var(--ink-3); margin-top: 1px; }

/* The recommendation rail. */
.builder-rail { position: sticky; top: calc(var(--header-h) + 27px); display: flex; flex-direction: column; gap: 14px; }
.rec-card { border-radius: var(--radius-lg); background: var(--surface); box-shadow: 0 0 0 1px var(--line); overflow: hidden; }
.rec-head { padding: 18px 20px 16px; background: linear-gradient(160deg, color-mix(in srgb, var(--accent) 14%, transparent), transparent 70%); }
.rec-title { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.rec-name { font-size: 27px; font-weight: 500; letter-spacing: -.02em; }
/* 'self-serve' or 'negotiated' — answers "can I just buy this?" before the
   price does, which is the first thing anyone wants to know about Enterprise. */
.rec-tag {
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 5px;
  background: var(--color-neutral-900); color: var(--ink-2);
}
.rec-tag-ent { background: var(--color-accent-800); color: var(--color-accent-300); }
.rec-reason { font-size: 12.5px; line-height: 1.55; color: var(--ink-2); margin-top: 8px; }
.rec-lines { padding: 16px 20px 18px; border-top: 1px solid var(--line-faint); display: flex; flex-direction: column; gap: 8px; }
.rec-line { display: flex; justify-content: space-between; gap: 12px; font-size: 12.5px; }
.rec-line > :first-child { color: var(--ink-3); }
/* nowrap so "3,000 of 10,000" cannot break in half when the label beside it
   needs two lines. The label is the half that should wrap. */
.rec-line > :last-child { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* A limit the described workload exceeds with nothing available to close it —
   the signal that this is the wrong rung of the ladder, which is the page's
   whole job. */
.rec-over { color: var(--err); }
/* A limit an add-on in the basket raises. The accent, not the error colour,
   because a gap something below is already paying for is not a problem. */
.rec-raised { color: var(--accent-bright); }
/* The plan's own figure, behind yours: "12 of 50". Muted and never recoloured
   by .rec-over/.rec-raised above — the number that changed is yours, and the
   allowance it is being measured against did not. */
.rec-of { color: var(--ink-4); }
/* Which add-on is buying the headroom the line above went past. Indented under
   it, so it reads as belonging to that limit rather than as another one. */
.rec-topup {
  margin: -2px 0 2px 0;
  padding-left: 10px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--accent-bright);
}
/* Divides the limits you set from the ones that just come with the plan. */
.rec-group {
  margin-top: 6px;
  padding-top: 10px;
  border-top: 1px solid var(--line-faint);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-4);
}
/* The plan and each add-on the recommendation needs, itemised above the sum.
   The rail used to print the plan's list price as the total, which understates
   what somebody who follows the advice actually pays. */
.rec-basket {
  padding: 14px 20px;
  border-top: 1px solid var(--line-faint);
  display: flex; flex-direction: column; gap: 8px;
}
.rec-total { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; padding: 14px 20px 18px; border-top: 1px solid var(--line-faint); }
.rec-total-label { font-size: 11px; color: var(--ink-3); }
.rec-total-note { font-size: 10.5px; color: var(--ink-4); margin-top: 2px; }
.rec-warn-head { margin-bottom: 7px; }
.rec-reason strong { color: var(--ink); font-weight: 500; }
.rec-total-amount { font-size: 26px; font-weight: 500; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.rec-warnings { padding: 13px 15px; border-radius: var(--radius-md); background: var(--accent-soft); box-shadow: 0 0 0 1px var(--accent-line); }
.rec-warning { font-size: 12px; line-height: 1.5; color: var(--ink-2); }

/* Tier comparison cards under the builder. */
.tier-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.tier-card {
  border-radius: var(--radius-lg);
  padding: 22px 20px;
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--line);
  display: flex; flex-direction: column;
  transition: box-shadow .2s;
}
.tier-card.is-recommended { box-shadow: 0 0 0 1.5px var(--accent); }
.tier-card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.tier-card-name { font-size: var(--step-2); font-weight: 500; letter-spacing: -.015em; }
.tier-card-price { display: flex; align-items: baseline; gap: 5px; margin-bottom: 8px; }
.tier-card-amount { font-size: 26px; font-weight: 500; letter-spacing: -.02em; }
.tier-card-period { font-size: 12px; color: var(--ink-3); }
.tier-card-blurb { font-size: 12.5px; line-height: 1.55; color: var(--ink-2); margin: 0 0 16px; min-height: 56px; }
.tier-card-features { display: flex; flex-direction: column; gap: 7px; margin-bottom: 18px; }
.tier-card .btn { margin-top: auto; width: 100%; }

/* ---------------------------------------------------------------------------
   Scroll reveal.

   Scoped to .js-reveal, which site.js puts on <html> BEFORE it hides anything.
   So the order is: nothing hidden -> script runs -> things hidden -> observer
   reveals them. A script that fails to load leaves the page fully visible,
   which is the only acceptable failure mode on a page that sells things.
   --------------------------------------------------------------------------- */
.js-reveal [data-reveal] { opacity: 0; transform: translateY(8px); transition: opacity .5s ease, transform .5s ease; }
.js-reveal [data-reveal].is-in { opacity: 1; transform: none; }

/* ============================ BREAKPOINTS ================================ */

@media (max-width: 1000px) {
  .builder-layout { grid-template-columns: 1fr; }
  /* Un-sticky before it gets taller than the viewport, or it pins awkwardly. */
  .builder-rail { position: static; }
  /* One breakpoint earlier than the other card grids. Four tier cards inside a
     1140px wrap are ~250px each, and below that the prices start wrapping. */
  .tier-cards { grid-template-columns: repeat(2, 1fr); }
  .contact-layout { grid-template-columns: 1fr; }
  .docs-layout { grid-template-columns: 1fr; }
  .docs-rail { position: static; flex-direction: row; flex-wrap: wrap; gap: 4px 14px; }
}

@media (max-width: 900px) {
  .grid-3, .intg-grid { grid-template-columns: repeat(2, 1fr); }
  .feature-row, .uc-split { grid-template-columns: 1fr; gap: 28px; }
  /* Reading order wins on one column: the copy always precedes its picture. */
  .feature-row:nth-child(even) .feature-copy,
  .feature-row:nth-child(even) .feature-figure { order: 0; }
  .inventory { grid-template-columns: 1fr; }
  .inventory-col + .inventory-col { border-left: 0; border-top: 1px solid var(--line-faint); }
  .hero-inner { padding-block: 56px 48px; }
  .section { padding-block: 56px; }
  .section-lead { padding-block: 56px 40px; }
}

@media (max-width: 620px) {
  .grid-2, .grid-3, .intg-grid, .tier-cards, .roadmap,
  .toggle-grid, .enquiry-options { grid-template-columns: 1fr; }
  .hero-figure { padding: 18px 16px; }
  .builder-panel, .contact-panel { padding: 20px 16px 24px; min-width: 0; }
  /* Give the 304px reCAPTCHA iframe the panel's full inner width. */
  .captcha-slot { padding: 0; background: none; box-shadow: none; }
  .docs-layout { gap: 24px; }
  .docs-step { grid-template-columns: 28px 1fr; gap: 12px; }
  .docs-step-n { width: 26px; height: 26px; font-size: 12px; }
}
