/* x2network marketing site — component layer.
   Sits on top of styles.css (the design system's token + pattern layer) and
   holds every rule the site's own blocks need. One section per block, in the
   order the blocks are declared in Blocks.jsx.

   Fluid first. Sizes are clamp() against the viewport, so there is exactly one
   layout breakpoint (64em) where columns collapse, and nothing else.

   Units: rem for anything dimensional and em where a value should track its
   local type size, both so the whole site scales with the reader's browser base
   size. px appears only for hairlines, shadow spreads and blur radii, which are
   optical details that must NOT scale. */

/* ---------- Kit tokens ---------- */
:root {
  /* Fluid rhythm. Replaces the fixed --space-10/--space-16 jumps that used to
     be written inline, so gutters shrink continuously instead of at a stop. */
  --x2-gap-sm: clamp(0.75rem, 1.5vw, 1rem);
  --x2-gap-md: clamp(1.5rem, 3vw, 2.5rem);
  --x2-gap-lg: clamp(2rem, 5vw, 4rem);
  --x2-row-py: clamp(2.5rem, 5vw, 4rem);

  /* Column floor for the auto-fit grids. Set per grid, never per breakpoint. */
  --x2-col-min: 16rem;

  --x2-measure: 46rem;
  --x2-icon-nudge: 0.125em;
}

/* ---------- App shell ---------- */
#root { min-height: 100vh; display: flex; flex-direction: column; }
#root > main { flex: 1 1 auto; }

@keyframes x2-swapfade { from { opacity: 0; transform: translateY(0.5rem); } }
.swap-fade { animation: x2-swapfade 0.35s cubic-bezier(0.4, 0, 0.2, 1); }
@keyframes x2-railfill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* The wordmark artwork is dark navy, so it needs lifting on dark surfaces. */
.dark .brand img,
.dark .footer__brand img { filter: invert(1) brightness(1.9) saturate(0); }
/* Footer logo matches the header logo height. */
.footer__brand img { height: var(--ds-logo-h-header); }

select.input { background-image: none; appearance: none; }

/* ---------- Layout primitives ----------
   The four shapes every page in this kit needs. Pages compose these rather
   than declaring grid-template-columns inline, which is what made the old
   markup break below 64em. */

/* Two-column split. One column until 64em, always. */
.x2-split { display: grid; gap: var(--x2-gap-lg); align-items: start; }
.x2-split--center { align-items: center; }
.x2-split--end { align-items: end; }
@media (min-width: 64em) {
  .x2-split { grid-template-columns: 1fr 1fr; }
  .x2-split--7-5 { grid-template-columns: 7fr 5fr; }
  .x2-split--5-7 { grid-template-columns: 5fr 7fr; }
  .x2-split--4-8 { grid-template-columns: 4fr 8fr; }
}

/* Card grid. Reflows on available width via auto-fit, so it needs no
   breakpoint and no item count passed in from JS. */
.x2-cols {
  display: grid;
  gap: var(--ds-grid-gap);
  grid-template-columns: repeat(auto-fit, minmax(var(--x2-col-min), 1fr));
}
.x2-cols--tight { --x2-col-min: 10rem; }
.x2-cols--wide { --x2-col-min: 20rem; }
.x2-cols--gap-lg { gap: var(--x2-gap-md); }

.x2-stack { display: flex; flex-direction: column; gap: var(--x2-stack-gap, var(--space-4)); }
.x2-stack--xs { --x2-stack-gap: var(--space-2); }
.x2-stack--sm { --x2-stack-gap: var(--space-3); }
.x2-stack--lg { --x2-stack-gap: var(--space-6); }
.x2-stack--xl { --x2-stack-gap: var(--x2-gap-lg); }
.x2-stack--start { align-items: flex-start; }

.x2-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-6); }
.x2-row--sm { gap: var(--space-3); }
.x2-row--md { gap: var(--space-4); }
/* Heading beside an action. Stacks below 64em rather than squeezing. */
.x2-row--split { align-items: flex-start; justify-content: space-between; }
@media (min-width: 64em) { .x2-row--split { align-items: flex-end; flex-wrap: nowrap; } }

.x2-measure { max-width: var(--x2-measure); }
.x2-measure--sm { max-width: 38rem; }
.x2-measure--lg { max-width: 52rem; }

/* Token-driven top margins. The one utility set in the kit: rhythm was by far
   the most common inline style, and every value here is a spacing token. */
.x2-mt-2 { margin-top: var(--space-2); }
.x2-mt-3 { margin-top: var(--space-3); }
.x2-mt-4 { margin-top: var(--space-4); }
.x2-mt-5 { margin-top: var(--space-5); }
.x2-mt-6 { margin-top: var(--space-6); }
.x2-mt-8 { margin-top: var(--space-8); }
.x2-mt-lg { margin-top: var(--x2-gap-md); }
.x2-mt-xl { margin-top: var(--x2-gap-lg); }

/* ---------- Shared inline pieces ---------- */
.x2-tick { color: hsl(var(--accent)); flex: none; margin-top: var(--x2-icon-nudge); display: inline-flex; }
.x2-tick-text { font-size: var(--text-sm); line-height: 1.6; }
.x2-strong-sm { font-size: var(--text-sm); font-weight: var(--font-weight-semibold); }
.x2-med-sm { font-size: var(--text-sm); font-weight: var(--font-weight-medium); }

/* ---------- StatBand ---------- */
.x2-stats {
  display: grid;
  gap: var(--x2-gap-md);
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}
.x2-stat__value {
  font-size: var(--type-h2);
  line-height: 1.1;
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--tracking-tight);
}
.x2-stat__value--sm { font-size: var(--text-2xl); }

/* ---------- Checklist ---------- */
.x2-checklist {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(var(--x2-col-min), 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}
.x2-checklist__item { display: flex; gap: var(--space-3); align-items: flex-start; }

/* ---------- ProblemCard ---------- */
.x2-problem__icon { margin-bottom: var(--space-4); }

/* ---------- ScreenSlider ----------
   --count (frame total) and --i (active frame) come in as custom properties on
   the track, because they are live values that cannot exist in a stylesheet.
   The arithmetic stays here. */
.x2-slider { margin: 0; }
.x2-slider__frame {
  border-radius: var(--ds-radius-sm);
  border: 1px solid hsl(var(--border));
  background: hsl(var(--surface));
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}
.x2-slider__chrome {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-4);
  min-height: 2.5rem;
  border-bottom: 1px solid hsl(var(--border));
  background: hsl(var(--surface-2));
}
.x2-slider__lights { display: flex; align-items: center; gap: 0.375rem; flex: none; }
.x2-slider__light { width: 0.5rem; height: 0.5rem; border-radius: var(--ds-radius-pill); background: hsl(var(--border)); display: block; }
.x2-slider__controls { display: flex; align-items: center; gap: var(--space-3); }
/* pickled-bluewood, not soft: this is a functional readout, and soft only
   reaches 2.45:1 on the chrome bar. */
.x2-slider__counter { font-size: var(--text-xs); font-variant-numeric: tabular-nums; color: hsl(var(--ds-color-pickled-bluewood)); }
.x2-slider__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  flex: none;
  border-radius: var(--ds-radius-default);
  border: 1px solid hsl(var(--border));
  background: hsl(var(--surface));
  color: hsl(var(--foreground));
  cursor: pointer;
  transition: var(--ds-transition);
}
.x2-slider__btn:hover { background: hsl(var(--surface-2)); }
.x2-slider__viewport { overflow: hidden; }
.x2-slider__track {
  display: flex;
  width: calc(var(--count, 1) * 100%);
  transform: translateX(calc(var(--i, 0) * -100% / var(--count, 1)));
  /* 200ms rather than the system's 150ms: at 150ms a full slide reads as a
     flicker. Same easing curve. */
  transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
.x2-slider__img { width: calc(100% / var(--count, 1)); display: block; flex: none; height: auto; }
.x2-slider__rail { display: flex; gap: 0.25rem; margin-top: var(--space-1); }
/* The visible rail stays a 3px hairline; the button around it carries
   transparent vertical padding so the hit target is a usable 1.5rem. */
.x2-slider__seg { flex: 1; display: block; padding: 0.625rem 0; border: none; background: none; cursor: pointer; }
.x2-slider__seg-bar {
  display: block;
  height: 3px;
  border-radius: var(--ds-radius-pill);
  background: hsl(var(--border));
  transition: var(--ds-transition);
}
.x2-slider__seg[aria-current="true"] .x2-slider__seg-bar { background: hsl(var(--accent)); }

/* ---------- ServiceRow ----------
   Media is always first in the DOM, so the mobile order is consistent. The
   alternation is a desktop-only reorder. */
.x2-service-row {
  display: grid;
  gap: var(--x2-gap-lg);
  align-items: center;
  padding-block: var(--x2-row-py);
  border-top: 1px solid hsl(var(--border));
}
.x2-service-row:first-child { border-top: none; padding-top: 0; }
@media (min-width: 64em) {
  .x2-service-row { grid-template-columns: 1fr 1fr; }
  .x2-service-row--flip .x2-service-row__media { order: 2; }
}
.x2-service-row__head { display: flex; align-items: center; gap: var(--space-4); }
.x2-service-row__title { margin-top: var(--space-4); font-size: var(--type-h3); }

/* ---------- ServiceCard ---------- */
.x2-service-card { overflow: visible; }
.x2-service-card__title { font-size: 1.0625rem; }
.x2-service-card__body { margin-top: var(--space-2); flex: 1 1 auto; }

/* ---------- ComparisonTable ----------
   Columns cannot usefully collapse, so below its natural width the table
   scrolls horizontally inside its card rather than crushing the cells. */
.x2-table { overflow: hidden; }
.x2-table__scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.x2-table__inner { min-width: 34rem; }
.x2-table__row {
  display: grid;
  grid-template-columns: 1.1fr repeat(var(--cols, 2), 1fr);
  border-bottom: 1px solid hsl(var(--border));
}
.x2-table__row:last-child { border-bottom: none; }
.x2-table__row--head { background: hsl(var(--surface-2)); }
.x2-table__cell { padding: var(--space-4) var(--space-6); font-size: var(--text-sm); line-height: 1.6; color: hsl(var(--muted)); }
.x2-table__cell--head { font-weight: var(--font-weight-semibold); color: hsl(var(--foreground)); }
.x2-table__cell--label { font-weight: var(--font-weight-medium); color: hsl(var(--foreground)); }

/* ---------- ProcessSteps ---------- */
.x2-steps { display: grid; gap: var(--ds-grid-gap); }
.x2-steps--compact { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.x2-step__head { display: flex; align-items: center; gap: var(--space-3); }
.x2-step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  flex: none;
  border-radius: var(--ds-radius-pill);
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
}
.x2-step__detail { margin-top: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.x2-step__detail-row { display: flex; gap: var(--space-2); font-size: var(--text-xs); line-height: 1.5; }
.x2-step__detail-row dt { min-width: 6.5rem; flex: none; color: hsl(var(--soft)); }
.x2-step__detail-row dd { margin: 0; }

/* ---------- PricingBand ---------- */
.x2-price--featured { border-color: hsl(var(--accent)); }
.x2-price__range { margin-top: var(--space-2); font-size: var(--text-2xl); font-weight: var(--font-weight-semibold); letter-spacing: var(--tracking-tight); }
.x2-price__list { margin-top: var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); list-style: none; padding: 0; }
.x2-price__item { display: flex; gap: var(--space-2); font-size: var(--text-sm); line-height: 1.6; }
/* Label and figure on one line, wrapping to two when there is no room. */
.x2-price__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3) var(--space-6); }

/* ---------- Quote ---------- */
.x2-quote { margin: 0; }
.x2-quote__mark { color: hsl(var(--soft)); display: inline-flex; }
.x2-quote__text { margin: var(--space-4) 0 0; font-size: var(--type-h3); line-height: 1.45; letter-spacing: var(--tracking-tight); }
.x2-quote__name { color: hsl(var(--foreground)); font-weight: var(--font-weight-medium); }

/* ---------- CaseStudyCard ---------- */
.x2-case__title { margin-top: var(--space-2); font-size: 1.0625rem; }
/* Fluid height: 22rem of photo is right on a desktop and far too much on a
   phone, so it tracks the viewport between 12rem and 22rem. */
.x2-case__figure { width: 100%; height: clamp(12rem, 28vw, 22rem); object-fit: cover; border-radius: var(--ds-radius-sm); }

/* ---------- Image block ---------- */
/* The UA stylesheet gives figure a 40px inline margin, which would indent the
   image inside a column that is already narrow. Same reset as .x2-quote. */
.x2-block-figure { margin: 0; }

/* ---------- Cta ---------- */
.x2-cta__body { margin-top: var(--space-4); font-size: var(--type-body); line-height: var(--leading-body); }

/* ---------- Tbc marker ---------- */
.x2-tbc {
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
  padding-inline: 0.375em;
  border-radius: var(--ds-radius-sm);
  background: var(--badge-warning-background);
  border: 1px dashed var(--badge-warning-border);
  font-variant-numeric: tabular-nums;
}

/* ---------- BuildViz (three.js hero) ---------- */
.x2-viz { position: relative; }
/* Fluid stage height. The scene reframes itself to its container, so this is
   the only thing that needs to change between a phone and a desktop. */
.x2-viz__stage { height: clamp(16rem, 38vw, 26rem); width: 100%; }
.x2-viz__caption-wrap { margin-top: var(--space-4); }
.x2-viz__rail { display: flex; gap: var(--space-2); }
.x2-viz__seg {
  flex: 1;
  height: 3px;
  padding: 0;
  border: none;
  border-radius: var(--ds-radius-pill);
  background: hsl(var(--muted) / 0.3);
  cursor: pointer;
  overflow: hidden;
  appearance: none;
}
.x2-viz__seg-fill {
  display: block;
  height: 100%;
  width: 100%;
  border-radius: var(--ds-radius-pill);
  background: hsl(var(--accent));
  transform-origin: left center;
  transform: scaleX(0);
}
.x2-viz__seg--done .x2-viz__seg-fill { transform: scaleX(1); }
.x2-viz__seg--active .x2-viz__seg-fill { animation: x2-railfill 4600ms linear forwards; }
.x2-viz--held .x2-viz__seg--active .x2-viz__seg-fill { animation-play-state: paused; }
.x2-viz__caption { margin-top: var(--space-5); }
.x2-viz__eyebrow { text-transform: uppercase; }
.x2-viz__line { margin-top: var(--space-2); min-height: 3.2em; max-width: 28rem; }
.x2-viz__fallback { width: 100%; border-radius: var(--ds-radius-sm); display: block; height: auto; }

/* ---------- Theme toggle ---------- */
.x2-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  flex: none;
  border-radius: var(--ds-radius-md);
  border: 1px solid hsl(var(--border));
  background: transparent;
  color: hsl(var(--muted));
  cursor: pointer;
  padding: 0;
}
.x2-theme-toggle:hover { color: hsl(var(--foreground)); background: hsl(var(--surface-2)); }
@media (min-width: 64em) { .x2-theme-toggle { width: 2.25rem; height: 2.25rem; } }

/* ---------- Page-level patterns ---------- */
/* Type and rhythm helpers, all token valued. */
.x2-mt-1 { margin-top: var(--space-1); }
.x2-sm { font-size: var(--text-sm); }
.x2-text-lg { font-size: var(--type-kicker); }
.x2-lead { font-size: var(--type-body); line-height: var(--leading-body); }
.x2-figure-lg { font-size: var(--text-2xl); font-weight: var(--font-weight-semibold); letter-spacing: var(--tracking-tight); }
.x2-med { font-weight: var(--font-weight-medium); }
.x2-center { margin-inline: auto; }
.x2-w-full { width: 100%; }
.x2-inline-block { display: inline-block; }
.x2-nudge { margin-top: var(--x2-icon-nudge); }
.x2-icon-inline { flex: none; margin-top: var(--x2-icon-nudge); display: inline-flex; }
.x2-measure--tight { max-width: 20ch; }
.x2-measure--xl { max-width: 56rem; }

/* A section that pads like a full band but is not one, and a section that only
   needs its closing padding. Fluid, so they shrink on a phone. */
.x2-band-pad { padding-block: clamp(3rem, 6vw, 5rem); }
.x2-pb-section { padding-bottom: clamp(3rem, 6vw, 5rem); }

/* Definition rows: term in a fixed gutter, value beside it. */
.x2-defrow { display: flex; gap: var(--space-4); font-size: var(--text-sm); }
.x2-defrow__term { min-width: 6rem; flex: none; }
/* Icon or avatar beside a block of copy. */
.x2-media-row { display: flex; gap: var(--space-5); align-items: flex-start; }
.x2-checklist__item--md { gap: var(--space-4); }

/* An aside that borrows the amber "to be confirmed" treatment. */
.x2-note-card { background: var(--badge-warning-background); border-color: var(--badge-warning-border); }

/* Portrait slot awaiting a real photograph. */
.x2-photo-slot {
  width: 100%;
  height: clamp(9rem, 20vw, 12rem);
  border-radius: var(--ds-radius-sm);
  background: hsl(var(--surface-2));
  border: 1px dashed hsl(var(--border));
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: var(--space-2);
}
.x2-case__figure--tall { height: clamp(14rem, 32vw, 24rem); }
/* Proof bar. Shallower than a full section and closed with a hairline. */
.x2-proof-band { padding-block: var(--space-10); border-bottom: 1px solid hsl(var(--border)); }
/* Service rows carry their own padding-block, so the list itself has no gap. */
.x2-service-rows { display: flex; flex-direction: column; }
.ds-container--narrow { max-width: 46rem; }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .swap-fade,
  .x2-viz__seg-fill { animation: none; }
  .x2-slider__track { transition: none; }
}
