/* Rexton Studio, shared page-level layout patterns (hero, grids, forms) */

/* ---- Hero ---- */
.hero {
  position: relative;
  padding: calc(var(--nav-h) + var(--sp-16)) 0 var(--sp-16);
  overflow: hidden;
}

/* Spark of light, a soft glow near the top-center of the header, the one
   spot of brightness against the black. */
.hero::before {
  content: "";
  position: absolute;
  top: -220px;
  left: 50%;
  transform: translateX(-50%);
  width: 900px;
  height: 520px;
  background: radial-gradient(ellipse closest-side, rgba(14, 122, 213, 0.38), rgba(14, 122, 213, 0.08) 55%, transparent 78%);
  pointer-events: none;
  z-index: 0;
}

@media (max-width: 720px) {
  /* Stronger on mobile, not just resized, the same glow calibrated for a
     desktop viewing distance reads as barely-there on a small, close-up
     phone screen. */
  .hero::before {
    width: 560px;
    height: 380px;
    top: -140px;
    background: radial-gradient(ellipse closest-side, rgba(14, 122, 213, 0.5), rgba(14, 122, 213, 0.12) 55%, transparent 78%);
  }
}

/* ---- Section glow: same restrained treatment as the hero spark, reused at
   a couple of other moments that earn it, one per page, not a wash across
   the whole scroll. Breaks up the run of flat-black sections with a pocket
   of color instead of leaving that as one long monochrome stretch. ---- */
.section-glow { overflow: hidden; }
.section-glow::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 900px;
  height: 620px;
  background: radial-gradient(ellipse closest-side, rgba(14, 122, 213, 0.22), rgba(14, 122, 213, 0.05) 55%, transparent 78%);
  pointer-events: none;
  z-index: 0;
}
.section-glow .container { position: relative; z-index: 1; }

@media (max-width: 720px) {
  .section-glow::after {
    width: 560px;
    height: 480px;
    background: radial-gradient(ellipse closest-side, rgba(14, 122, 213, 0.34), rgba(14, 122, 213, 0.08) 55%, transparent 78%);
  }
}

/* 1000, raised from 880 on 2026-09-12. Measured, not guessed: at 880 the H1 was
   left with 832px of measure at EVERY desktop width from 1280 to 1920, while
   "Websites built for" needs 846px and "service businesses" needs 893px at the
   83px the clamp settles on. Neither half fitted, so the headline shattered into
   four lines with "FOR" stranded alone on one of them. At 1000 the measure is
   952 and it sets as two near-equal lines, 846 and 893, which is what makes it
   read as composed rather than shattered.
   The lede keeps its own 640px cap, and the trust and CTA rows are centred flex
   that size to content, so nothing else widens with this. */
.hero-inner {
  position: relative;
  z-index: 1;
  max-width: 1000px;
  margin: 0 auto;
  text-align: center;
}

.hero h1 {
  font-size: clamp(2.6rem, 6.2vw, 5.2rem);
  margin-top: var(--sp-4);
  /* Belt and braces for widths the measurement above did not cover, and for
     whenever this copy changes. Ignored by browsers that do not support it. */
  text-wrap: balance;
}

.hero .lede {
  margin: var(--sp-6) auto 0;
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  color: var(--steel-silver);
  max-width: 640px;
  line-height: 1.65;
}

.hero .cta-row {
  margin-top: var(--sp-8);
  display: flex;
  justify-content: center;
  gap: var(--sp-4);
  flex-wrap: wrap;
}

@media (max-width: 640px) {
  .hero { padding: calc(var(--nav-h) + var(--sp-2)) 0 var(--sp-6); }
  .hero .eyebrow { font-size: 0.7rem; }
  .hero h1 { font-size: clamp(1.65rem, 7.2vw, 5.2rem); margin-top: 0; }
  .hero .cta-row { margin-top: var(--sp-6); }
}

.hero .accent { color: var(--forge-blue-text); }

.trust-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--sp-3) var(--sp-8);
  margin: var(--sp-6) 0;
}
.trust-item {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--steel-silver);
  white-space: nowrap;
}
.trust-item svg { width: 16px; height: 16px; color: var(--forge-blue); flex-shrink: 0; }
/* The homepage grid glow brightens the grid lines behind the hero, and one
   crossing under these small labels measured 1.7:1. A black halo, invisible on
   the black page, keeps the lit lines out from under the letters. */
.trust-item { text-shadow: 0 0 1px #000, 0 0 2px #000, 0 0 3px #000, 0 0 6px #000; }
@media (max-width: 720px) {
  .trust-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    justify-items: center;
    gap: var(--sp-3) var(--sp-4);
  }
  .trust-item { font-size: 0.62rem; }
  .trust-item svg { width: 14px; height: 14px; }
}

/* ---- Two-column service/detail layout (heading + copy beside a card) ----
   Was only ever defined locally in services.html's own <style> block, so
   any other page reusing this class (pricing.html) got no grid at all
   both columns just stacked full-width, which is why the button and copy
   read as broken there. Shared here so every page gets the real layout. */
.service-detail { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-12); align-items: start; }
@media (max-width: 860px) { .service-detail { grid-template-columns: 1fr; gap: var(--sp-8); } }
.service-detail h2 { font-size: clamp(1.8rem, 3.2vw, 2.6rem); }
.service-detail .lede { margin-top: var(--sp-5); color: var(--steel-silver); font-size: 1.02rem; line-height: 1.7; max-width: 460px; }

/* ---- Section headers ---- */
.section-head {
  max-width: 640px;
  margin: 0 auto var(--sp-12);
  text-align: center;
}

.section-head h1,
.section-head h2 {
  margin-top: var(--sp-4);
  font-size: clamp(1.9rem, 3.6vw, 3rem);
}

.section-head .lede {
  margin-top: var(--sp-4);
  color: var(--steel-silver);
  font-size: 1.05rem;
  line-height: 1.65;
}

/* ---- Card grid (2-4 col responsive) ---- */
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-6); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-6); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-6); }

@media (max-width: 960px) {
  .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
}

/* ---- Work card (niche demo link) ---- */
.work-card {
  padding: 0;
  display: flex;
  flex-direction: column;
  transition: transform var(--dur-med) var(--ease-forge);
}

.work-card:hover { transform: translateY(-4px); }

/* Browser-chrome frame around the homepage screenshot */
.work-preview { position: relative; background: var(--steel-black); }
.preview-chrome {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 9px 12px;
  background: var(--steel-black);
  border-bottom: 1px solid var(--line);
}
.preview-chrome .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--line-strong); flex-shrink: 0; }
.preview-chrome .preview-url {
  margin-left: var(--sp-2);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--steel-silver);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.work-preview .shot-wrap { aspect-ratio: 16 / 10; overflow: hidden; }
.work-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  display: block;
  transition: transform var(--dur-slow) var(--ease-forge);
}
.work-card:hover .work-preview img { transform: scale(1.045); }

.work-body {
  padding: var(--sp-4) var(--sp-6);
  display: flex;
  flex-direction: column;
}

.work-card .view {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  color: var(--forge-blue-text);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

.work-card .view svg { transition: transform var(--dur-fast) var(--ease-forge); width: 14px; height: 14px; }
.work-card:hover .view svg { transform: translateX(4px); }

/* ---- 3D portfolio carousel, full-bleed, lives inside the hero ---- */
.hero-carousel {
  position: relative;
  z-index: 1;
  width: 100%;
  margin-top: var(--sp-16);
}

@media (max-width: 640px) {
  .hero-carousel { margin-top: var(--sp-6); }
}

.carousel-3d {
  position: relative;
}

.hero-carousel .car-prev { left: clamp(12px, 4vw, 56px); }
.hero-carousel .car-next { right: clamp(12px, 4vw, 56px); }
.hero-carousel .car-dots { padding: 0 var(--sp-6); }

.car-stage {
  position: relative;
  height: 700px;
  perspective: 2000px;
  overflow: hidden;
  /* Tells the browser this element handles horizontal gestures itself
     without it, mobile browsers impose a gesture-disambiguation delay
     before committing to our drag, which reads as laggy/unresponsive.
     pan-y keeps vertical page scroll working when a touch isn't ours. */
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  /* A soft radial glow behind the stack, like the cards are lit from
     behind, reads as staged/premium rather than pasted on flat black. */
  background: radial-gradient(ellipse 60% 55% at 50% 50%, rgba(14, 122, 213, 0.14), transparent 70%);
}

.car-card {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(560px, 78vw);
  transform-origin: center center;
  will-change: transform, opacity;
  transition: transform var(--dur-slow) var(--ease-forge), opacity var(--dur-slow) var(--ease-forge), box-shadow var(--dur-med) var(--ease-forge);
  cursor: pointer;
  box-shadow: 0 40px 70px -30px rgba(0, 0, 0, 0.7);
}

.car-stage.is-dragging .car-card { transition: box-shadow var(--dur-med) var(--ease-forge); cursor: grabbing; }

.car-card.is-active {
  cursor: default;
  box-shadow: 0 50px 90px -28px rgba(0, 0, 0, 0.75), 0 0 0 1px rgba(14, 122, 213, 0.25), 0 0 60px -10px rgba(14, 122, 213, 0.35);
}

/* Neighbor cards shouldn't show their own cursor-glint or hover-lift,
   the 3D transform already does the "depth" storytelling. */
.car-card:not(.is-active):hover { box-shadow: 0 44px 78px -28px rgba(0, 0, 0, 0.72); }

.car-nav {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(18, 26, 38, 0.7);
  backdrop-filter: blur(6px);
  border: 1px solid var(--line-strong);
  color: var(--paper);
  z-index: 20;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-forge), border-color var(--dur-fast), background var(--dur-fast);
}
.car-nav:hover { border-color: var(--forge-blue); background: rgba(14, 122, 213, 0.16); transform: translateY(-50%) scale(1.06); }
.car-nav:active { transform: translateY(-50%) scale(0.94); }
.car-nav svg { width: 20px; height: 20px; }
.car-prev { left: -6px; }
.car-next { right: -6px; }

@media (max-width: 640px) {
  .car-nav { display: none; }
}

.car-dots {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: var(--sp-8);
}

@media (max-width: 640px) {
  .car-dots { margin-top: var(--sp-4); }
}
.car-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(159, 176, 196, 0.62); /* 4.0:1 on black; --line-strong was 1.6:1 */
  border: none;
  cursor: pointer;
  padding: 0;
  transition: background var(--dur-fast), transform var(--dur-fast) var(--ease-forge), width var(--dur-med) var(--ease-forge);
}
.car-dot:hover { background: var(--steel-silver); }
.car-dot.is-active { background: var(--forge-blue); width: 24px; border-radius: 4px; }
.car-dot:focus-visible { outline: 2px solid var(--forge-blue); outline-offset: 3px; }

/* Pause / play for the autoplaying carousel (WCAG 2.2.2). Sits at the start
   of the dot row so it reads as part of the same control strip. */
.car-dots { align-items: center; }
.car-pause {
  width: 30px; height: 30px;
  margin-right: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: rgba(18, 26, 38, 0.7);
  color: var(--paper);
  cursor: pointer;
  flex-shrink: 0;
  transition: border-color var(--dur-fast), background var(--dur-fast);
}
.car-pause:hover { border-color: var(--forge-blue); background: rgba(14, 122, 213, 0.16); }
.car-pause svg { width: 12px; height: 12px; }
.car-pause .i-play { display: none; }
.car-pause.is-paused .i-play { display: block; }
.car-pause.is-paused .i-pause { display: none; }

@media (max-width: 640px) {
  .car-stage { height: 340px; }
  .car-card {
    width: min(243px, 58vw);
    /* Snappier commit animation than desktop's 720ms, a flick should
       resolve quickly, a slow drag on a small screen is where "fluid"
       actually gets felt. */
    transition: transform 380ms var(--ease-forge), opacity 380ms var(--ease-forge), box-shadow var(--dur-med) var(--ease-forge);
  }
}

/* ---- Pricing teaser ----
   The price is the whole point of the panel, so it gets treated as a figure
   rather than buried mid-sentence at body size. Hairlines run out to the
   panel edges on either side of it, which also fills the dead horizontal
   space that made the old flat box feel empty. */
.price-teaser { padding: var(--sp-16) var(--sp-8); }
@media (max-width: 640px) { .price-teaser { padding: var(--sp-12) var(--sp-5); } }

.pt-head { display: block; }

.pt-lead {
  display: block;
  margin-top: var(--sp-5);
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: clamp(0.72rem, 1.4vw, 0.85rem);
  letter-spacing: 0.24em;
  line-height: 1;
  color: var(--steel-silver);
}

.pt-figure-row {
  display: flex;
  align-items: center;
  gap: clamp(var(--sp-4), 4vw, var(--sp-12));
  margin-top: var(--sp-5);
}
.pt-figure-row::before,
.pt-figure-row::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-strong));
}
.pt-figure-row::after { background: linear-gradient(90deg, var(--line-strong), transparent); }

.pt-figure {
  flex-shrink: 0;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(3.4rem, 9vw, 6.5rem);
  line-height: 0.9;
  letter-spacing: -0.04em;
}

.pt-sub {
  margin-top: var(--sp-6);
  color: var(--steel-silver);
  font-size: clamp(0.98rem, 1.6vw, 1.1rem);
}

.pt-sub-tight { margin-top: var(--sp-2); font-size: 0.92rem; }

.price-teaser .btn { margin-top: var(--sp-8); }

/* ---- Service card ----
   Composed like a spec sheet entry rather than a centered stack: an oversized
   ghosted part number anchors the top, the CTA is pinned to the bottom behind
   a hairline so all three line up no matter how long the copy runs, and a
   forge-blue rail machines its way down the cut edge on hover. The scale jump
   between the numeral and the mono CTA is what stops it reading as a template. */
.service-card {
  padding: var(--sp-8);
  display: flex;
  flex-direction: column;
  text-align: left;
  /* Rail drawn as a background layer: .seam already owns both ::before
     (glint) and ::after (weld sweep) on this element, so there is no spare
     pseudo-element left to animate. */
  background-color: var(--blued-navy);
  background-image: linear-gradient(var(--forge-blue), var(--forge-blue));
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 2px 0%;
  transition: background-size var(--dur-med) var(--ease-forge);
}
.service-card:hover,
.service-card:focus-within { background-size: 2px 100%; }

.service-card .idx {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 4.2vw, 3.4rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
  color: rgba(159, 176, 196, 0.2);
  transition: color var(--dur-med) var(--ease-forge),
              -webkit-text-stroke-color var(--dur-med) var(--ease-forge);
}
.service-card:hover .idx,
.service-card:focus-within .idx { color: rgba(14, 122, 213, 0.45); }

/* Outlined figure where the browser supports it. The solid low-opacity fill
   above stays as the fallback so the numeral never vanishes without it. */
@supports (-webkit-text-stroke: 1px currentColor) {
  .service-card .idx {
    color: transparent;
    -webkit-text-stroke: 1px rgba(159, 176, 196, 0.34);
  }
  .service-card:hover .idx,
  .service-card:focus-within .idx {
    color: transparent;
    -webkit-text-stroke-color: var(--forge-blue);
  }
}

.service-card h3 { margin-top: var(--sp-5); font-size: 1.3rem; line-height: 1.15; }
.service-card p { margin-top: var(--sp-3); color: var(--steel-silver); font-size: 0.95rem; line-height: 1.7; }
.service-card .link {
  margin-top: auto;
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--forge-blue-text);
  transition: color var(--dur-fast) var(--ease-forge), border-top-color var(--dur-med) var(--ease-forge);
}
.service-card:hover .link { border-top-color: var(--line-strong); }
.service-card .link:hover { color: var(--forge-blue-bright); }

@media (max-width: 640px) {
  .service-card { padding: var(--sp-6); }
}

/* ---- Process steps ---- */
.process-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-6);
}
@media (max-width: 900px) { .process-list { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .process-list { grid-template-columns: 1fr; } }

.process-step { padding: var(--sp-6) 0; border-top: 2px solid var(--line-strong); position: relative; }
.process-step .step-num {
  font-family: var(--font-display);
  font-size: 2.6rem;
  font-weight: 800;
  color: var(--blued-navy-2);
  -webkit-text-stroke: 1px var(--line-strong);
  line-height: 1;
}
.process-step h3 { margin-top: var(--sp-3); font-size: 1.15rem; }
.process-step p { margin-top: var(--sp-2); color: var(--steel-silver); font-size: 0.9rem; line-height: 1.6; }

/* ---- Differentiator grid ---- */
.diff-card { padding: var(--sp-6); }
.diff-card svg { width: 26px; height: 26px; color: var(--forge-blue); }
.diff-card h3 { margin-top: var(--sp-4); font-size: 1.1rem; text-transform: none; font-family: var(--font-body); font-weight: 600; letter-spacing: 0; }
.diff-card p { margin-top: var(--sp-2); color: var(--steel-silver); font-size: 0.88rem; line-height: 1.6; }

/* ---- Pricing teaser / cards ---- */
/* ---- Plan grid ----
   Three packages, so this is a plain three-up inside the container. It drops
   straight to a single column rather than passing through a two-column step,
   which with an odd number of cards would always strand one alone on its own
   row. (This replaced a five-tier grid that needed a 1400px breakout to fit;
   that rule is gone with the tiers.) */
.plan-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-6); }
@media (max-width: 900px) { .plan-grid { grid-template-columns: 1fr; gap: var(--sp-4); } }

.price-card { padding: var(--sp-8); display: flex; flex-direction: column; }
/* Slightly tighter in the five-across layout, where each card is narrower. */
@media (min-width: 1400px) { .price-card { padding: var(--sp-6) var(--sp-5); } }
.price-card .plan-name { display: block; min-height: 1.4em; font-family: var(--font-mono); font-size: 0.78rem; color: var(--steel-silver); letter-spacing: 0.08em; text-transform: uppercase; }
.price-card .plan-price { margin-top: var(--sp-3); font-family: var(--font-display); font-size: 3rem; font-weight: 800; line-height: 1.05; white-space: nowrap; }
.price-card .plan-price sup { font-family: var(--font-mono); font-size: 1rem; color: var(--steel-silver); font-weight: 400; margin-left: 4px; }
.price-card .plan-note { margin-top: var(--sp-2); color: var(--steel-silver); font-size: 0.85rem; }
.price-card ul { list-style: none; margin: var(--sp-6) 0 0; padding: 0; flex-grow: 1; }
.price-card li { display: flex; gap: var(--sp-3); padding: var(--sp-2) 0; font-size: 0.9rem; color: var(--paper); border-top: 1px solid var(--line); }
.price-card li:first-child { border-top: none; }
.price-card li svg { width: 16px; height: 16px; color: var(--forge-blue); flex-shrink: 0; margin-top: 2px; }

.price-card.centered-card { text-align: center; }
.price-card.centered-card li { justify-content: center; }
.price-card.featured { border-color: var(--forge-blue); }
.price-card .btn { margin-top: var(--sp-6); width: 100%; }

.price-card .plan-price sup.from {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--steel-silver);
  font-weight: 400;
  margin: 0 0 var(--sp-2);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* ---- Add-ons: per-card checklist that feeds the total below it ---- */
.addon-block { margin-top: var(--sp-6); padding-top: var(--sp-5); border-top: 1px solid var(--line); flex-grow: 0; }
.addon-heading { display: block; font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--steel-silver); margin-bottom: var(--sp-3); }

.addon-row { display: flex; align-items: center; gap: var(--sp-3); padding: 0.45rem 0; cursor: pointer; }
.addon-row .addon-label { font-size: 0.86rem; flex-grow: 1; color: var(--paper); }
.addon-row .addon-price { font-family: var(--font-mono); font-size: 0.8rem; color: var(--steel-silver); transition: color var(--dur-fast); }
.addon-row:hover .addon-price { color: var(--forge-blue-text); }

.addon-check {
  appearance: none;
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-cut);
  background: var(--steel-black);
  position: relative;
  cursor: pointer;
  transition: background var(--dur-fast), border-color var(--dur-fast);
}
.addon-check:hover { border-color: var(--forge-blue); }
.addon-check:checked { background: var(--forge-blue); border-color: var(--forge-blue); }
.addon-check:checked::after {
  content: "";
  position: absolute; left: 5px; top: 2px;
  width: 4px; height: 8px;
  border: solid var(--paper);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.addon-check:focus-visible { outline: 2px solid var(--forge-blue); outline-offset: 2px; }

.total-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-top: var(--sp-6);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line-strong);
}
.total-row .total-label { font-family: var(--font-mono); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--steel-silver); }
.total-row .total-amt { font-family: var(--font-display); font-size: 1.9rem; font-weight: 800; color: var(--paper); }

/* ---- Featured add-on row: a bigger-ticket upsell with its own benefit line and, on
   qualifying cards, a struck-through "was" price next to the discounted total. ---- */
.addon-row.featured-addon { align-items: flex-start; padding: 0.65rem 0; }
.addon-row.featured-addon .addon-check { margin-top: 3px; }

.addon-copy { display: flex; flex-direction: column; gap: 3px; flex-grow: 1; min-width: 0; }
.addon-copy .addon-label { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.addon-desc { font-size: 0.74rem; line-height: 1.45; color: var(--steel-silver); }
.addon-hint { font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.02em; color: var(--ember); }

.addon-price-stack { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; flex-shrink: 0; }
.addon-price-stack .was { font-family: var(--font-mono); font-size: 0.72rem; color: var(--steel-silver); text-decoration: line-through; }
.addon-price-stack .now { font-family: var(--font-mono); font-size: 0.85rem; font-weight: 500; color: var(--paper); }

.addon-save {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ember);
  border: 1px solid var(--ember);
  padding: 1px 6px;
  border-radius: var(--radius-pill);
}

.addon-tag {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--forge-blue-text);
  border: 1px solid var(--forge-blue);
  padding: 1px 6px;
  border-radius: var(--radius-pill);
}

.recurring-note {
  display: none;
  margin-top: var(--sp-2);
  text-align: right;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--forge-blue-text);
}
.recurring-note.is-visible { display: block; }

/* ---- Form ---- */
.forge-form { padding: var(--sp-8); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-5); margin-bottom: var(--sp-5); }
.form-submit { margin-top: var(--sp-3); }
@media (max-width: 640px) { .form-row { grid-template-columns: 1fr; } }
.form-field { display: flex; flex-direction: column; gap: var(--sp-2); }
.form-field.full { grid-column: 1 / -1; }
.form-field label { font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--steel-silver); }
.form-field input, .form-field select, .form-field textarea {
  background: var(--steel-black);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-cut);
  padding: 0.85rem 1rem;
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 0.95rem;
  transition: border-color var(--dur-fast);
}
.form-field input:focus, .form-field select:focus, .form-field textarea:focus {
  border-color: var(--forge-blue);
}
.form-success { margin-top: var(--sp-5); font-family: var(--font-mono); font-size: 0.85rem; color: var(--forge-blue-text); display: none; }
.form-success.is-visible { display: block; }
.form-field input[type="date"] { color-scheme: dark; }
.form-field select:disabled { color: var(--steel-silver); cursor: not-allowed; }
.slot-hint { margin: calc(var(--sp-5) * -1) 0 var(--sp-5); font-family: var(--font-mono); font-size: 0.78rem; color: var(--ember); min-height: 1em; }
.call-hours-note { margin-bottom: var(--sp-5); font-size: 0.8rem; color: var(--steel-silver); }

/* ---- Weekend call picker (2026-09-26) ----
   Open weekend days as buttons with their open-slot counts, then the day's
   times as pills. 4 columns wide, 2 on a phone, so every row reads
   Saturday | Sunday (a .day-spacer holds Saturday's cell on a Sunday). */
.call-picker { display: flex; flex-direction: column; gap: var(--sp-3); margin-bottom: var(--sp-5); text-align: left; }
.call-picker .label-as-text { margin: var(--sp-2) 0 0; }
.call-picker .tz { text-transform: none; letter-spacing: 0; }
.day-picker, .time-picker { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-2); }
.day-picker > *, .time-picker > * { min-width: 0; }
.day-chip {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 12px 8px;
  background: var(--steel-black);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-cut);
  color: var(--paper);
  font: inherit;
  cursor: pointer;
  transition: border-color var(--dur-fast), background-color var(--dur-fast);
}
.dc-dow { font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--steel-silver); }
.dc-date { font-family: var(--font-display); font-weight: 700; font-size: 1.1rem; line-height: 1.15; white-space: nowrap; }
.dc-open { font-family: var(--font-mono); font-size: 0.68rem; color: var(--forge-blue-bright); white-space: nowrap; }
.day-chip:hover:not(:disabled) { border-color: var(--forge-blue); }
.day-chip.is-selected { border-color: var(--forge-blue); background: rgba(14, 122, 213, 0.16); }
.day-chip.is-selected .dc-dow { color: var(--paper); }
.day-chip:disabled { cursor: default; }
.day-chip.is-full { opacity: 0.45; }
.day-chip.is-full .dc-open { color: var(--steel-silver); }
.time-chip {
  padding: 10px 6px;
  background: var(--steel-black);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color var(--dur-fast), background-color var(--dur-fast);
}
.time-chip:hover:not(:disabled) { border-color: var(--forge-blue); }
.time-chip.is-selected { border-color: var(--forge-blue); background: rgba(14, 122, 213, 0.16); color: #fff; }
.time-chip.is-booked { opacity: 0.35; text-decoration: line-through; cursor: default; }
.day-chip:focus-visible, .time-chip:focus-visible, .picker-more:focus-visible { outline: 2px solid var(--forge-blue); outline-offset: 2px; }
.picker-note { grid-column: 1 / -1; font-family: var(--font-mono); font-size: 0.78rem; color: var(--steel-silver); }
.picker-more {
  align-self: flex-start;
  background: none; border: none; padding: 4px 0;
  color: var(--forge-blue-text);
  font-family: var(--font-mono); font-size: 0.78rem;
  text-decoration: underline; text-underline-offset: 3px;
  cursor: pointer;
}
.picker-more:hover { color: var(--forge-blue-bright); }
@media (max-width: 640px) {
  .day-picker { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .time-picker { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---- Utility ---- */
.mt-24 { margin-top: var(--sp-24); }
.text-center { text-align: center; }
.mx-auto { margin-left: auto; margin-right: auto; }

/* ==========================================================================
   Dot field
   Self-contained and removable: delete this block, the .dot-field element in
   the markup. The scroll progress hairline that used to live here was
   removed at the owner's request; do not reinstate it.

   The reference site renders its dithered backdrop with a WebGL shader. That
   is a lot of machinery (and a lot of GPU) for a decorative layer, so this is
   a CSS reading of the same idea instead: two offset dot lattices at
   different scales drifting slowly past each other, masked to fade out at the
   edges. No canvas, no JS, and it sits behind content without intercepting a
   single pointer event.
   ========================================================================== */
.dot-field {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
  /* Fades the lattice out toward the edges so it reads as an atmospheric
     field rather than a rectangle of dots stopping at a hard border. */
  -webkit-mask-image: radial-gradient(ellipse 78% 66% at 50% 42%, #000 0%, rgba(0,0,0,0.75) 46%, rgba(0,0,0,0.18) 76%, transparent 100%);
  mask-image: radial-gradient(ellipse 78% 66% at 50% 42%, #000 0%, rgba(0,0,0,0.75) 46%, rgba(0,0,0,0.18) 76%, transparent 100%);
}
.dot-field::before,
.dot-field::after {
  content: "";
  position: absolute;
  /* Oversized so the drift never exposes an edge. */
  inset: -60px;
  background-repeat: repeat;
}
.dot-field::before {
  background-image: radial-gradient(circle at center, rgba(14,122,213,0.55) 0 1.15px, transparent 1.6px);
  background-size: 22px 22px;
  opacity: 0.5;
}
.dot-field::after {
  background-image: radial-gradient(circle at center, rgba(243,128,11,0.4) 0 1px, transparent 1.5px);
  background-size: 53px 53px;
  opacity: 0.32;
}
/* Keep the lattice from competing with text on small screens. */
@media (max-width: 640px) {
  .dot-field::before { opacity: 0.34; }
  .dot-field::after  { opacity: 0.2; }
}



/* ---- Demo CTA note (pricing + services) ----
   The price is in the button, this says what the price buys and that it is
   credited back. Centred to match the CTAs it sits under. */
.demo-cta-note {
  max-width: 46ch;
  margin: var(--sp-3) auto 0;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--steel-silver);
  text-align: center;
}


/* ==========================================================================
   Two-stage inquiry form
   Stage 1 asks for the minimum. Stage 2 (booking a call) is revealed only
   after the server accepts stage 1, so a visitor who is not ready to commit
   to a time can still ask a question.
   ========================================================================== */

/* Required marker and the optional counterpart, so the difference is visible
   at a glance rather than only discoverable by submitting. */
.forge-form .req { color: var(--ember); margin-left: 2px; }
.forge-form .opt {
  font-family: var(--font-mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--steel-silver);
  margin-left: 6px;
  font-weight: 400;
}

/* Per-field validation message. role="alert" in the markup means a screen
   reader announces it the moment it is filled in. */
.field-err {
  margin: 6px 0 0;
  min-height: 0;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--ember);
}
.field-err:empty { display: none; }

.forge-form .is-invalid {
  border-color: var(--ember);
  box-shadow: 0 0 0 3px rgba(243, 128, 11, 0.14);
}

.forge-form textarea {
  width: 100%;
  resize: vertical;
  min-height: 84px;
  font-family: inherit;
}

/* Honeypot. Hidden from sight without display:none, because some bots skip
   display:none fields specifically to avoid this trap. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-foot-note {
  margin-top: var(--sp-3);
  font-size: 0.78rem;
  line-height: 1.55;
  color: var(--steel-silver);
  text-align: center;
}

.form-error {
  margin-top: var(--sp-3);
  font-size: 0.85rem;
  color: var(--ember);
  text-align: center;
}
.form-error:empty { display: none; }

/* Stage 2 header, shown once the inquiry is actually accepted. */
.stage-done { text-align: center; margin-bottom: var(--sp-6); }
.stage-done h3 {
  font-family: var(--font-display);
  font-size: 1.25rem;
  margin-bottom: var(--sp-2);
}
.stage-done p {
  font-size: 0.9rem;
  color: var(--steel-silver);
  max-width: 46ch;
  margin: 0 auto;
  line-height: 1.6;
}

.work-trade {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--forge-blue-text);
  margin-bottom: 4px;
}


/* ---- Package terms block (pricing) ----
   Only items verifiable against the agreement in checkout.html. The deposit vs
   full payment question and the hosting question are deliberately absent: both
   are genuinely contradictory in the source material and are flagged rather
   than guessed. */
.terms-block { margin-top: var(--sp-10); padding: var(--sp-8); }
.terms-h { font-family: var(--font-display); font-size: 1.2rem; margin-bottom: var(--sp-5); text-align: center; }
.terms-list { list-style: none; margin: 0; padding: 0; }
.terms-list li {
  padding: var(--sp-4) 0;
  border-top: 1px solid var(--line);
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--steel-silver);
}
.terms-list li:first-child { border-top: none; }
.terms-list strong { color: var(--paper); font-weight: 600; }
.terms-note {
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
  font-size: 0.84rem;
  color: var(--steel-silver);
  text-align: center;
}

/* ==========================================================================
   HERO INQUIRY FORM (2026-09-12)
   The form moved up out of the page body and into the hero, taking the slot
   the work carousel used to occupy. The carousel moved down to where the old
   contact section was, so the portfolio is still on the page, just below the
   thing that actually converts. Reason for the move: the form sat under a
   full-viewport carousel, so most visitors never reached it.
   ========================================================================== */
.hero-form-wrap {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 860px;
  /* --sp-8, not --sp-10. The scale is 1,2,3,4,5,6,8,12,16,24,32 with no 10 in
     it, and an undefined var invalidates the WHOLE margin shorthand, which
     silently took the `auto` with it and left the form jammed against the left
     edge overflowing its column. */
  margin: var(--sp-8) auto 0;
  padding: 0 var(--sp-6);
}
@media (max-width: 640px) {
  .hero-form-wrap { margin-top: var(--sp-6); padding: 0 var(--sp-4); }
}

/* Tighter than the old standalone version: smaller gaps and less padding, so
   the whole thing has a chance of sharing a screen with the headline. */
.hero-form { padding: var(--sp-6); }
.hero-form .form-row { gap: var(--sp-4); margin-bottom: var(--sp-4); }
@media (max-width: 640px) { .hero-form { padding: var(--sp-5); } }

/* Name, trade, email and phone share one row on desktop. Originally 3
   columns (name/trade/one merged "phone or email" field); grew to 4 on
   2026-09-19 when that field split into separate required email and phone
   inputs. Same shape either way: they were previously stacked as 1 + 2,
   which cost a whole row of height for no reason. */
.form-row-4 { grid-template-columns: repeat(4, 1fr); }
/* Grid children default to min-width:auto. The trade <select> carries options
   like "Painting / Moving / Carpet Cleaning", which set a 310px min-content
   width, so its track refused to shrink to 1fr and shoved later columns
   clean out of the panel. Same trap as the grid columns on hah-developments,
   resinclass and ap-proscapes. Measured before and after, not eyeballed. */
.form-row-4 > * { min-width: 0; }
.form-row-4 select,
.form-row-4 input { width: 100%; min-width: 0; }
@media (max-width: 960px) { .form-row-4 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .form-row-4 { grid-template-columns: 1fr; } }

/* Budget: radios drawn as pills. One tap rather than the two a native select
   costs on mobile, and the options stay visible instead of hiding in a menu,
   which is the whole point of asking. */
.label-as-text {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--steel-silver);
}
.budget-pills { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.bpill { position: relative; flex: 1 1 auto; min-width: 0; cursor: pointer; }
/* Off-screen rather than display:none, so it stays keyboard reachable and the
   focus ring below can respond to it. */
.bpill input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  margin: 0;
  pointer-events: none;
}
.bpill span {
  display: block;
  text-align: center;
  padding: 12px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--steel-black);
  color: var(--steel-silver);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
  transition: border-color .2s ease, color .2s ease, background-color .2s ease, transform .2s ease;
}
.bpill:hover span { border-color: var(--forge-blue); color: var(--paper-white, #fff); }
.bpill input:checked + span {
  border-color: var(--forge-blue);
  background: rgba(14, 122, 213, 0.16);
  color: #fff;
}
.bpill input:focus-visible + span { outline: 2px solid var(--forge-blue); outline-offset: 2px; }
@media (max-width: 520px) {
  .budget-pills { gap: var(--sp-2); }
  .bpill span { padding: 11px 8px; font-size: 0.72rem; }
}

/* The carousel keeps its own spacing rule from when it lived in the hero, and
   that top margin is wrong now it sits inside a normal section. */
.work-section .hero-carousel { margin-top: var(--sp-8); }

/* Hero eyebrows (and pricing's lead section, its hero) sit in the blue spark
   of light at the top of the page, where
   --forge-blue-text measured 3.3 to 4.2:1 (the glow is strongest on phones).
   A lighter blue for this one spot: 5.05:1 on the brightest glow, 9.5 on black. */
.hero .eyebrow, .sheet-lead .eyebrow { color: #74b4f0; }

/* "Every package includes": what all three packages share, said once instead
   of repeated on every card (2026-09-27). */
.includes-strip { margin-top: var(--sp-8); padding: var(--sp-6); border: 1px solid var(--line); border-radius: var(--radius-cut, 6px); text-align: center; }
.includes-h { margin: 0 0 var(--sp-4); font-family: var(--font-mono); font-size: 0.72rem; font-weight: 400; letter-spacing: 0.16em; text-transform: uppercase; color: var(--steel-silver); }
.includes-strip ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-3) var(--sp-8); }
.includes-strip li { display: inline-flex; align-items: center; gap: var(--sp-2); color: var(--paper); font-size: 0.95rem; }
.includes-strip li svg { width: 18px; height: 18px; color: var(--forge-blue-text); flex-shrink: 0; }
.includes-note { margin: var(--sp-4) 0 0; font-size: 0.85rem; color: var(--steel-silver); }
@media (max-width: 640px) {
  .includes-strip { text-align: left; }
  .includes-strip ul { flex-direction: column; align-items: flex-start; }
  .includes-strip li { align-items: flex-start; }
}
/* One Care plan, centred, with its two up-front options */
.care-single { max-width: 560px; margin: 0 auto; }
.care-excl { margin-top: var(--sp-4); font-size: 0.85rem; color: var(--steel-silver); }
.care-buy { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-3); margin-top: var(--sp-6); }
.care-buy .btn { flex: 1 1 200px; }
.care-foot { margin-top: var(--sp-6); font-size: 0.85rem; text-align: center; }
