/*
Theme Name: XPRT Computing
Theme URI: https://xprtcomputing.com/
Author: XPRT Computing
Description: One-page theme for XPRT Computing. Every section — hero, about, services, why-choose, testimonials, contact and footer — is editable from Appearance > Customize, and the three repeating lists (Services, Testimonials, Why Choose Us) are their own admin menus. Keeps the GSAP pinned services scroll and the tuned asset pipeline of the original static build.
Version: 1.3.0
Requires at least: 6.3
Tested up to: 6.8
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: xprt-computing
Tags: one-column, custom-logo, custom-menu, editor-style, featured-images, translation-ready

Requires at least 6.3 because scripts are enqueued with the `strategy` => 'defer'
argument added in that release.
*/

/* ==========================================================================
   XPRT Computing — single page website
   ==========================================================================
   Contents
     1. Base / brand variables
     2. Header + navbar (+ mobile dropdown)
     3. Hero
     4. About
     5. Services (GSAP stacked cards)
     6. Why choose us
     7. Testimonials (scroll-snap carousel)
     8. Contact form
     9. Footer (.xprt-footer)
    10. WordPress plumbing
    11. Contact Form 7 (only used when a CF7 shortcode is set)
   ========================================================================== */


/* ==========================================================================
   1. Base / brand variables
   ========================================================================== */

:root {
  --brand: #d11a2a;
  --brand-dark: #a70f1e;
  --nav-h: 84px;          /* header height at the top of the page */
  --nav-h-scrolled: 68px; /* it shrinks once the page scrolls */
  --nav-pad: 24px;        /* side gutter, widened on large screens below */
  /* seconds each Why-Choose row stays open; functions.php overrides this from
     the Customizer setting, and script.js gets the same number in ms */
  --wc-step: 6s;
}

@media (max-width: 991px) { :root { --nav-h: 72px; --nav-h-scrolled: 64px; } }
@media (max-width: 576px) { :root { --nav-h: 64px; --nav-h-scrolled: 58px; --nav-pad: 16px; } }

* { margin: 0; padding: 0; box-sizing: border-box; font-family: Arial, sans-serif; }

/* MUST stay `auto`. `scroll-behavior: smooth` here breaks ScrollTrigger: when it
   sets the scroll position while building or refreshing the services pin, the
   browser animates instead of jumping, so the measurement taken immediately
   after is short by however far the animation still had to travel — which is
   exactly scrollY. Measured, resizing back across 1024px while scrolled put the
   pin's start at 500, -551, -1701 and -2400 instead of 1590, and the section
   landed on top of About. With `auto` the drift is 0 at every position.
   Smooth scrolling for anchor links is done in js/script.js instead. */
html { scroll-behavior: auto; }

/* anchor links must not land under the fixed navbar */
section[id] { scroll-margin-top: calc(var(--nav-h-scrolled) + 12px); }


/* --- icons ----------------------------------------------------------------
   Font Awesome is gone. Each icon is <i class="ico"><svg><use href="#i-*">
   pointing at the sprite at the top of <body>. The <i> wrapper is kept on
   purpose: every existing `.something i { font-size: 13px; color: … }` rule
   still sizes and colours the icon, because the svg is 1em and fills with
   currentColor. Rules that set their own display (.wc-tag i) still win on
   specificity. */
.icon-sprite { display: none; }

.ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-style: normal;
  line-height: 1;
}

.ico svg {
  display: block;
  width: 1em;
  height: 1em;
  fill: currentColor;
}


/* ==========================================================================
   2. Header + navbar
   ========================================================================== */

/* The bar sits over the hero while it is transparent, so it is fixed from the
   start — that way it never jumps position when .scrolled is added. */
nav {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  background: transparent;
  z-index: 1000;
  transition: height .3s ease, background-color .3s ease, box-shadow .3s ease;
}

/* solid once the page scrolls — and while the mobile menu is open, so the bar
   and the panel below it read as one surface.
   No backdrop-filter: the bar is fixed and full width, so a blur here has to be
   recomputed on every scroll frame. At .97 alpha there is nothing left to see
   through anyway, so the extra 5% opacity buys the same look for free. */
nav.scrolled,
nav.open {
  background: rgba(12, 12, 14, .97);
  box-shadow: 0 6px 24px rgba(0, 0, 0, .28);
}

nav.scrolled { height: var(--nav-h-scrolled); }

.nav-container {
  max-width: 1280px;
  width: 100%;
  margin: 0 auto;
  padding: 0 var(--nav-pad);
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* same value as the gap between the nav links themselves, so the spacing runs
     evenly across the whole right-hand group instead of the last link sitting
     tighter to the Contact button than to its neighbours */
  gap: clamp(20px, 3vw, 44px);
}

/* Logo */
.logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.logo img {
  height: clamp(30px, 4.4vw, 44px);
  width: auto;
  display: block;
}

/* Nav links.
   Pushed to the right so they sit next to the Contact button instead of floating
   in the middle of the bar, which left a wide empty gap on either side. An auto
   margin rather than changing justify-content: space-between still has to hold,
   because below 992px .nav-links is display:none and it is what keeps the logo
   and the hamburger pinned to opposite ends. */
.nav-links { margin-left: auto; }

.nav-links ul {
  display: flex;
  align-items: center;
  list-style: none;
  gap: clamp(20px, 3vw, 44px);
}

.nav-links a {
  position: relative;
  display: inline-block;
  padding: 6px 2px;
  text-decoration: none;
  color: rgba(255, 255, 255, .82);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: .2px;
  transition: color .25s ease;
}

/* underline grows from the middle on hover / for the current section */
.nav-links a::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 0;
  height: 2px;
  background: var(--brand);
  border-radius: 2px;
  transform: translateX(-50%);
  transition: width .25s ease;
}

.nav-links a:hover,
.nav-links a:focus-visible,
.nav-links a.active { color: #fff; }

.nav-links a:hover::after,
.nav-links a:focus-visible::after,
.nav-links a.active::after { width: 100%; }

/* Right hand side: CTA + hamburger */
.actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.nav-cta {
  display: inline-block;
  padding: 11px 24px;
  background: var(--brand);
  color: #fff;
  text-decoration: none;
  font-size: 15px;
  font-weight: 700;
  border-radius: 6px;
  white-space: nowrap;
  transition: background .25s ease, transform .2s ease, box-shadow .25s ease;
}

.nav-cta:hover {
  background: var(--brand-dark);
  transform: translateY(-2px);
  box-shadow: 0 8px 18px rgba(209, 26, 42, .32);
}

/* Hamburger — three bars that fold into an X when the menu is open */
.menu-btn {
  display: none;
  width: 44px;
  height: 44px;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0;
  place-items: center;
}

.burger,
.burger::before,
.burger::after {
  content: "";
  display: block;
  width: 24px;
  height: 2px;
  background: #fff;
  border-radius: 2px;
  transition: transform .3s ease, opacity .2s ease;
}

.burger::before { transform: translateY(-7px); }
.burger::after  { transform: translateY(5px); }

nav.open .burger { background: transparent; }
nav.open .burger::before { transform: rotate(45deg); }
nav.open .burger::after  { transform: translateY(-2px) rotate(-45deg); }

/* Mobile dropdown — a full width panel under the bar, not a floating box */
.dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  padding: 8px var(--nav-pad) 20px;
  /* already .97 opaque — the blur it used to have was invisible and cost a
     full-width recomposite every time the panel animated */
  background: rgba(12, 12, 14, .98);
  border-top: 1px solid rgba(255, 255, 255, .08);
  box-shadow: 0 18px 30px rgba(0, 0, 0, .3);
  /* animated open/close — visibility keeps it out of the tab order when shut */
  opacity: 0;
  visibility: hidden;
  transform: translateY(-10px);
  transition: opacity .25s ease, transform .25s ease, visibility .25s;
}

nav.open .dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.dropdown a {
  padding: 14px 4px;
  text-decoration: none;
  font-size: 16px;
  font-weight: 600;
  color: rgba(255, 255, 255, .85);
  border-bottom: 1px solid rgba(255, 255, 255, .07);
  transition: color .2s ease, padding-left .2s ease;
}

.dropdown a:hover   { color: #fff; padding-left: 10px; }
.dropdown a.active  { color: var(--brand); }

.dropdown .dropdown-cta {
  margin-top: 16px;
  padding: 13px 20px;
  background: var(--brand);
  color: #fff;
  text-align: center;
  border: 0;
  border-radius: 6px;
}

.dropdown .dropdown-cta:hover { background: var(--brand-dark); padding-left: 20px; }

/* Responsive */
@media (max-width: 991px) {
  .nav-links { display: none; }
  .menu-btn  { display: grid; }
}

/* One Contact button at a time: it sits in the bar until the screen is too
   narrow for it, then it moves into the dropdown. */
@media (min-width: 481px) {
  .dropdown .dropdown-cta { display: none; }
}

@media (max-width: 480px) {
  .actions .nav-cta { display: none; }
}

@media (min-width: 992px) {
  .dropdown { display: none; }
}


/* ==========================================================================
   3. Hero
   ==========================================================================
   Three stacked layers — the background clip, a red bloom, a gradient scrim —
   and the copy on top. All CSS; the only JS the hero needs is the browser's
   own video playback.

   The `.rig-*` rules further down draw a device mock-up that used to sit on the
   right. Its markup was removed when the clip became the background: the
   laptop landed on top of the emblem and the two fought each other. The rules
   are left here so it can be put back — nothing references them, so they cost
   about a kilobyte gzipped and no render work. Delete them once the hero is
   settled. */

.hero-scene {
  position: relative;
  overflow: hidden;
  z-index: 1;

  /* what shows while the clip is still loading, and behind it wherever `cover`
     leaves a sliver — the same near-black the footage sits on */
  background: linear-gradient(135deg, #08070a 0%, #150a0d 100%);

  --rig-scale: .78;
  --rig-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* object-fit: cover, so the clip fills the hero at any shape and is cropped
   rather than letterboxed. It is 946x532 — a 540p source — so on a wide screen
   it is being upscaled and will look soft; that is the footage, not the CSS. */
.hero-bg-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  /* The hero box is wider than 16:9, so `cover` has to throw away a slice of
     the clip's height — about 18% at a 1600x738 hero. Centred, that slice takes
     the top off the emblem right where the navbar sits, which reads as a
     mistake rather than a crop. Biasing to 30% keeps the whole mark in frame
     and spends the loss on the empty board at the bottom instead. */
  object-position: center 30%;
  z-index: 0;
}

/* red glow behind the device. Sized in px, not %, so it stays a glow instead
   of stretching into an oval on wide screens */
.hero-bloom {
  position: absolute;
  z-index: 1;
  top: 50%;
  right: -4%;
  width: 820px;
  height: 820px;
  margin-top: -410px;   /* centring by margin leaves `transform` for the animation */
  pointer-events: none;
  background: radial-gradient(circle,
              rgba(209, 26, 42, .22) 0%, rgba(209, 26, 42, .07) 38%, transparent 68%);
  animation: hero-breathe 7s ease-in-out infinite;
}

@keyframes hero-breathe {
  0%, 100% { opacity: .7; transform: scale(1); }
  50%      { opacity: 1;  transform: scale(1.06); }
}

/* darkens the left third so the copy keeps its contrast over the clip, and
   the top and bottom edges so the navbar and the next section blend in */
.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    linear-gradient(95deg, #08070a 0%, rgba(8, 7, 10, .92) 28%, rgba(8, 7, 10, .3) 62%, rgba(8, 7, 10, .55) 100%),
    linear-gradient(180deg, rgba(8, 7, 10, .4) 0%, transparent 34%, rgba(8, 7, 10, .8) 100%);
}

.hero-inner {
  position: relative;
  z-index: 3;
  min-height: 82vh;
  max-width: 1600px;
  margin: 0 auto;
  padding: calc(var(--nav-h) + 24px) var(--nav-pad) 40px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(20px, 3vw, 56px);
}

.hero-content {
  color: #fff;
  max-width: 620px;
  opacity: 0;
  animation: hero-text-in 1s ease .1s forwards;
}

@keyframes hero-text-in {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: none; }
}

.hero-content h1 {
  font-size: clamp(2rem, 3.4vw, 3rem);
  font-weight: 700;
  line-height: 1.2;
  margin-bottom: 24px;
  text-transform: capitalize;
  letter-spacing: -0.5px;
}

.hero-content p {
  font-size: 1.15rem;
  line-height: 1.7;
  color: #e0e0e0;
  margin-bottom: 32px;
}

/* CTA button */
.hero-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 30px;
  background-color: var(--brand);
  color: #fff;
  text-decoration: none;
  font-size: 1rem;
  font-weight: 600;
  border-radius: 5px;
  box-shadow: 0 10px 30px rgba(209, 26, 42, .28);
  transition: background .3s ease, transform .2s ease, box-shadow .3s ease;
}

.hero-btn i { font-size: 13px; transition: transform .2s ease; }

.hero-btn:hover {
  background-color: var(--brand-dark);
  transform: translateY(-2px);
  box-shadow: 0 14px 34px rgba(209, 26, 42, .38);
}

.hero-btn:hover i { transform: translateX(4px); }


/* --- the rig --------------------------------------------------------------- */

/* `* { font-family: Arial }` at the top of this file is a *direct* declaration
   on every element, which beats anything inherited — so setting the mono face
   on a container does not reach the text nested inside it. These two ask for it
   themselves; everywhere else in the rig the text is a direct child of the rule
   that styles it. */
.rig-brand span,
.rig-code * { font-family: var(--rig-mono); }

.hero-rig-wrap {
  position: relative;
  width: calc(1010px * var(--rig-scale));
  height: calc(760px * var(--rig-scale));
}

.hero-rig {
  position: absolute;
  top: 0;
  left: 0;
  width: 1010px;
  height: 760px;
  transform-origin: top left;
  perspective: 1700px;
  opacity: 0;
  animation: hero-rig-in 1.4s cubic-bezier(.2, .7, .3, 1) .45s forwards;
}

/* the scale lives in the keyframes because an animated `transform` replaces
   the property outright — a separate `transform: scale()` rule would simply
   be overwritten for as long as this runs, and it runs with `forwards` */
@keyframes hero-rig-in {
  from { opacity: 0; transform: scale(calc(var(--rig-scale) * .93)); }
  to   { opacity: 1; transform: scale(var(--rig-scale)); }
}

.rig-float {
  height: 100%;
  transform-style: preserve-3d;
  animation: hero-bob 9s ease-in-out infinite;
}

@keyframes hero-bob {
  0%, 100% { transform: translateY(-14px) rotateX(2deg); }
  50%      { transform: translateY(14px) rotateX(-1deg); }
}

/* laptop */
.rig-laptop {
  position: absolute;
  left: 120px;
  top: 150px;
  width: 760px;
  transform: rotateY(-19deg) rotateX(7deg) rotateZ(-1.5deg);
  transform-style: preserve-3d;
}

.rig-screen {
  position: relative;
  padding: 12px;
  background: #0c0a0e;
  border: 1px solid rgba(209, 26, 42, .3);
  border-radius: 12px 12px 3px 3px;
  box-shadow: 0 30px 64px rgba(0, 0, 0, .65), 0 0 56px rgba(209, 26, 42, .11),
              inset 0 1px 0 rgba(255, 255, 255, .05);
}

.rig-ui {
  height: 452px;
  display: flex;
  background: #0f0c11;
  border-radius: 6px;
  overflow: hidden;
}

.rig-side {
  width: 150px;
  padding: 16px 12px;
  background: #0a080c;
  border-right: 1px solid rgba(209, 26, 42, .14);
}

.rig-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 26px;
  font-family: var(--rig-mono);
  font-size: 12px;
  color: #fff;
  letter-spacing: .12em;
}

.rig-dot {
  width: 22px;
  height: 22px;
  border-radius: 5px;
  background: var(--brand);
  box-shadow: 0 0 14px rgba(209, 26, 42, .6);
}

.rig-nav i {
  display: block;
  height: 9px;
  margin-bottom: 15px;
  border-radius: 2px;
  background: rgba(255, 255, 255, .07);
}

.rig-nav i:nth-child(1) { width: 78%; background: rgba(209, 26, 42, .5); }
.rig-nav i:nth-child(2) { width: 62%; }
.rig-nav i:nth-child(3) { width: 70%; }
.rig-nav i:nth-child(4) { width: 54%; }
.rig-nav i:nth-child(5) { width: 66%; }
.rig-nav i:nth-child(6) { width: 48%; }

.rig-main { flex: 1; padding: 18px 20px; }

.rig-head {
  margin-bottom: 16px;
  font-family: var(--rig-mono);
  font-size: 12px;
  color: #8c848a;
  letter-spacing: .2em;
  text-transform: uppercase;
}

.rig-kpis {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-bottom: 18px;
}

.rig-kpi {
  padding: 13px;
  background: #141017;
  border: 1px solid rgba(209, 26, 42, .16);
  border-radius: 6px;
}

.rig-kpi b {
  display: block;
  font-size: 24px;
  font-weight: 700;
  color: #fff;
  letter-spacing: -.02em;
}

.rig-kpi small {
  font-family: var(--rig-mono);
  font-size: 9px;
  color: #7e767c;
  letter-spacing: .14em;
  text-transform: uppercase;
}

.rig-kpi u {
  display: block;
  margin-top: 5px;
  text-decoration: none;
  font-family: var(--rig-mono);
  font-size: 10px;
  color: #ff5a63;
}

.rig-chart {
  height: 196px;
  padding: 14px;
  background: #141017;
  border: 1px solid rgba(209, 26, 42, .16);
  border-radius: 6px;
}

.rig-t {
  margin-bottom: 8px;
  font-family: var(--rig-mono);
  font-size: 10px;
  color: #8c848a;
  letter-spacing: .16em;
  text-transform: uppercase;
}

.rig-chart svg { display: block; width: 100%; height: 140px; }

/* the line draws itself once, a second after the rig lands */
.rig-spark {
  fill: none;
  stroke: var(--brand);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-dasharray: 900;
  stroke-dashoffset: 900;
  filter: drop-shadow(0 0 6px rgba(209, 26, 42, .75));
  animation: hero-draw 3.2s cubic-bezier(.4, 0, .2, 1) 1.5s forwards;
}

@keyframes hero-draw { to { stroke-dashoffset: 0; } }

.rig-base {
  position: relative;
  height: 17px;
  margin: 0 -34px;
  background: linear-gradient(180deg, #1a161c, #0a080b);
  border-radius: 0 0 16px 16px;
  box-shadow: 0 20px 38px rgba(0, 0, 0, .6);
}

.rig-base::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 3px;
  transform: translateX(-50%);
  width: 110px;
  height: 4px;
  border-radius: 3px;
  background: rgba(255, 255, 255, .06);
}

/* floating glass cards */
.rig-card {
  position: absolute;
  padding: 18px;
  background: linear-gradient(140deg, rgba(209, 26, 42, .14), rgba(24, 18, 26, .5));
  border: 1px solid rgba(209, 26, 42, .34);
  border-radius: 14px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .09);
  opacity: 0;
}

.rig-icn {
  width: 38px;
  height: 38px;
  margin-bottom: 11px;
  display: grid;
  place-items: center;
  color: #ff5a63;
  background: rgba(209, 26, 42, .2);
  border: 1px solid rgba(209, 26, 42, .4);
  border-radius: 9px;
}

.rig-lbl {
  font-family: var(--rig-mono);
  font-size: 13px;
  color: #fff;
  letter-spacing: .09em;
}

.rig-meta {
  margin-top: 5px;
  font-family: var(--rig-mono);
  font-size: 10px;
  color: #8e868c;
  letter-spacing: .1em;
}

/* each card pops in on its own beat, then drifts for good */
.rig-cloud {
  right: 150px;
  top: 36px;
  width: 112px;
  height: 112px;
  display: grid;
  place-items: center;
  border-radius: 22px;
  color: #ff5a63;
  animation: hero-pop 1.1s cubic-bezier(.2, .7, .3, 1) 1.05s forwards,
             hero-drift1 7.5s ease-in-out 2.15s infinite;
}

.rig-code {
  left: 82px;
  top: 0;
  width: 290px;
  padding: 15px;
  font-family: var(--rig-mono);
  font-size: 11.5px;
  line-height: 1.85;
  color: #8e868c;
  animation: hero-pop 1.1s cubic-bezier(.2, .7, .3, 1) 1.28s forwards,
             hero-drift1 10s ease-in-out 2.4s infinite;
}

.rig-code .rig-k { color: #ff5a63; }
.rig-code .rig-s { color: #c9c2c7; }

.rig-ai {
  right: 8px;
  top: 170px;
  width: 206px;
  animation: hero-pop 1.1s cubic-bezier(.2, .7, .3, 1) 1.5s forwards,
             hero-drift1 8s ease-in-out 2.6s infinite;
}

.rig-auto {
  left: 0;
  bottom: 112px;
  width: 214px;
  animation: hero-pop 1.1s cubic-bezier(.2, .7, .3, 1) 1.75s forwards,
             hero-drift2 9.5s ease-in-out 2.85s infinite;
}

.rig-dev {
  right: 66px;
  bottom: 52px;
  width: 96px;
  height: 96px;
  display: grid;
  place-items: center;
  font-family: var(--rig-mono);
  font-size: 26px;
  color: #ff5a63;
  animation: hero-pop 1.1s cubic-bezier(.2, .7, .3, 1) 2s forwards,
             hero-drift2 8.5s ease-in-out 3.1s infinite;
}

@keyframes hero-pop {
  from { opacity: 0; transform: translateY(34px) scale(.9); }
  to   { opacity: 1; transform: none; }
}

@keyframes hero-drift1 { 0%, 100% { transform: translateY(0); }  50% { transform: translateY(-17px); } }
@keyframes hero-drift2 { 0%, 100% { transform: translateY(0); }  50% { transform: translateY(15px); } }

.rig-orbit {
  position: absolute;
  left: 50%;
  bottom: 34px;
  width: 800px;
  height: 800px;
  border: 1px solid rgba(209, 26, 42, .16);
  border-radius: 50%;
  animation: hero-spin 26s linear infinite;
}

.rig-orbit::before {
  content: "";
  position: absolute;
  inset: 112px;
  border: 1px solid rgba(209, 26, 42, .1);
  border-radius: 50%;
}

.rig-orbit i {
  position: absolute;
  top: -4px;
  left: 50%;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #ff5a63;
  box-shadow: 0 0 16px var(--brand);
}

@keyframes hero-spin {
  from { transform: translateX(-50%) rotateX(76deg) rotate(0); }
  to   { transform: translateX(-50%) rotateX(76deg) rotate(360deg); }
}


/* Responsive.
   The --rig-scale steps below belong to the retired device mock-up and only
   matter if it is put back. What is live here is the 1024px switch to centred
   copy and the smaller type further down. */
@media (max-width: 1699px) { .hero-scene { --rig-scale: .68; } }
@media (max-width: 1399px) { .hero-scene { --rig-scale: .58; } }
@media (max-width: 1199px) { .hero-scene { --rig-scale: .5; } }

@media (max-width: 1023px) {
  .hero-scene { --rig-scale: .52; }

  .hero-inner {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    text-align: center;
    gap: 8px;
    padding-top: calc(var(--nav-h) + 40px);
  }

  .hero-bloom { right: 50%; margin-right: -410px; }
}

@media (max-width: 767px) {
  .hero-content p { font-size: 1rem; }
}

@media (max-width: 639px) {
  .hero-rig-wrap { display: none; }
  .hero-inner { min-height: 74vh; }
}

@media (max-width: 480px) {
  .hero-content p  { font-size: 0.95rem; }
  .hero-btn { padding: 12px 24px; font-size: 0.9rem; }
}

/* Motion is decoration here, so hold every animation on its finished frame.
   The background clip is not covered by this: a <video> with utoplay is the
   visitor's own media, and browsers already respect the OS setting for it. */
@media (prefers-reduced-motion: reduce) {
  .hero-bloom,
  .rig-float,
  .rig-orbit,
  .rig-cloud,
  .rig-code,
  .rig-ai,
  .rig-auto,
  .rig-dev { animation: none; }

  .hero-content,
  .rig-card { opacity: 1; animation: none; }

  .hero-rig { opacity: 1; animation: none; transform: scale(var(--rig-scale)); }

  .rig-spark { stroke-dashoffset: 0; animation: none; }
}


/* ==========================================================================
   4. About
   ========================================================================== */

.about {
  padding: 100px 8%;
  background: #fff;
  border-top: 1px solid #e5e7eb;
  border-bottom: 1px solid #e5e7eb;
}

/* capped like the navbar (1200px) so the copy can't stretch on wide screens */
.about-container {
  display: flex;
  gap: 56px;
  align-items: center;
  max-width: 1200px;
  margin: 0 auto;
}

/* --- left side: video card ------------------------------------------------ */
/* the card carries the video's own 9:16 ratio, so the whole frame is visible —
   nothing is cropped */
.about-media {
  flex: 0 0 clamp(240px, 25%, 300px);
  position: relative;
}

.media-card {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: 26px;
  overflow: hidden;
  background: #f1f2f4;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.14);
}

.about-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;   /* card matches the video ratio, so this crops nothing */
  display: block;
}

/* white pill floating over the bottom of the card */
.media-badge {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 20px;
  width: max-content;
  max-width: calc(100% - 24px);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 18px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.16);
  font-size: 13px;
  color: #1d2430;
  font-weight: 600;
  white-space: nowrap;
}

.media-badge i { color: var(--brand); font-size: 16px; }
.media-badge strong { color: var(--brand); font-weight: 800; }

/* --- right side: copy ---------------------------------------------------- */
.about-right {
  flex: 1.15;
}

.about-eyebrow {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: #1d2430;
}

.eyebrow-line {
  width: 34px;
  height: 2px;
  background: var(--brand);
}

.about-eyebrow b { color: var(--brand); font-weight: 700; }

.about-right h2 {
  margin: 0 0 18px;
  font-size: clamp(34px, 4vw + 6px, 56px);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -1px;
  text-transform: uppercase;
  color: #101827;
}

.about-lead,
.about-more p {
  font-size: 16px;
  line-height: 1.85;
  color: #555;
  text-align: justify;
  margin: 0;
}

/* read more toggle */
.about-readmore {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--brand);
  font-size: 15px;
  font-weight: 700;
}

.about-readmore i { transition: transform .3s ease; font-size: 13px; }
.about-readmore[aria-expanded="true"] i { transform: rotate(180deg); }

.about-more {
  max-height: 0;
  overflow: hidden;
  transition: max-height .45s ease;
}

.about-more.open { max-height: 460px; }
.about-more p { padding-top: 18px; }

/* checklist */
.about-checklist {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 18px 30px;
  margin: 28px 0 0;
  padding: 0;
}

.about-checklist li {
  display: flex;
  align-items: flex-start;   /* keeps the tick at the first line when an item wraps */
  gap: 12px;
  font-size: 16px;
  line-height: 1.5;
  color: #1d2430;
}

.about-checklist i {
  color: var(--brand);
  font-size: 19px;
  flex-shrink: 0;
  margin-top: 2px;
}

/* CTA */
.about-cta {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-top: 34px;
  padding: 16px 34px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--brand), #7d0f1a);
  color: #fff;
  text-decoration: none;
  font-size: 16px;
  font-weight: 700;
  box-shadow: 0 10px 26px rgba(209, 26, 42, 0.28);
  transition: transform .25s ease, box-shadow .25s ease;
}

.about-cta:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 32px rgba(209, 26, 42, 0.38);
}

.about-cta i { font-size: 14px; }

/* Responsive */
@media (max-width: 992px) {
  .about { padding: 80px 8%; }
  .about-container { flex-direction: column; gap: 45px; align-items: flex-start; }

  /* stacked, the video reads as a preface to copy nobody has met yet — so the
     column runs text first and the video after it. Order, not a DOM swap: on
     desktop it is still the left-hand card, and the markup keeps the reading
     order a screen reader gets. */
  .about-media { flex: none; width: 100%; max-width: 300px; order: 2; }
}

@media (max-width: 768px) {
  .about { padding: 60px 20px; }
  .about-lead,
  .about-more p { text-align: left; }
}

@media (max-width: 576px) {
  .media-card { border-radius: 20px; }
  .about-checklist { grid-template-columns: 1fr; gap: 14px; }
  .about-cta { width: 100%; justify-content: center; }
}


/* ==========================================================================
   5. Services (GSAP stacked cards)
   ==========================================================================
   Desktop (>=1024px): the section is pinned by ScrollTrigger and the cards
   stack over each other as you scroll. Below that the cards simply flow
   down the page — no pinning, no absolute positioning. */

.stack-services {
  position: relative;
  display: flex;
  align-items: center;
  padding: 48px 5%;
  color: #f5f5f5;
  background: #0b0b0d url('images/services-bg.avif') center / cover no-repeat;
  overflow: hidden;
}

/* --- backdrop: the active card's own image, blurred ----------------------
   Every backdrop is capped at 1920 px wide and served as WebP (see the
   <picture> tags in index.html), because the dark overlay on top turns each
   one into a colour wash rather than a picture. Desktop only: below 1024px the
   <source media> never matches, so mobile downloads a 43-byte placeholder
   instead of six photos it would never see, and the section keeps its static
   background. */
.stack-bg {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

.stack-bg-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
}

/* The darkening that keeps all six backdrops at a similar weight used to be
   `filter: saturate(1.15) brightness(.72)` on each image. GSAP animates their
   opacity and scale, so every frame of a cross-fade re-filtered a viewport-sized
   layer — six of them, all promoted. Measured on the live site that showed up as
   a 32ms 95th-percentile frame and one 186ms stutter.

   28% black over the image is arithmetically identical to brightness(.72):
   pixel * (1 - .28) == pixel * .72. So this is the same result from one static
   layer instead of six filtered ones, with nothing to recompute per frame.
   saturate(1.15) is dropped — under a 70%+ dark overlay it was not visible. */
.stack-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .28);
  pointer-events: none;
}

/* visible if GSAP never runs */
.stack-bg-img:first-child { opacity: 1; }

/* dark wash so the cards stay readable over the backdrop — heavy on the left
   where the copy sits, lighter on the right so the image reads */
.stack-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(95deg, rgba(6, 6, 8, .96) 0%, rgba(7, 7, 9, .92) 32%, rgba(10, 8, 10, .74) 62%, rgba(16, 8, 10, .66) 100%);
  z-index: 1;
}

/* the section is exactly one viewport tall, but guard against sub-pixel
   rounding leaving a light hairline in ScrollTrigger's pin wrapper */
.pin-spacer { background: #0b0b0d; }

.stack-container {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 1500px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: 36px;
  align-items: center;
}

/* --- left column: header ------------------------------------------------- */
.stack-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 15px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .12);
  background: rgba(255, 255, 255, .05);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: #e6e6e6;
}

.stack-eyebrow i { color: var(--brand); font-size: 13px; }

.stack-left h2 {
  margin: 16px 0 14px;
  font-size: clamp(30px, 2.6vw + 8px, 44px);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -1px;
  color: #fff;
}

.stack-left h2 span { color: var(--brand); }

.stack-left > p {
  max-width: 470px;
  font-size: 15.5px;
  line-height: 1.7;
  color: #b4b4b8;
  margin: 0;
}

.stack-cta {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-top: 24px;
  padding: 13px 28px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--brand), #7d0f1a);
  color: #fff;
  text-decoration: none;
  font-size: 15px;
  font-weight: 700;
  box-shadow: 0 10px 26px rgba(209, 26, 42, .32);
  transition: transform .25s ease, box-shadow .25s ease;
}

.stack-cta:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 32px rgba(209, 26, 42, .45);
}

.stack-cta i { font-size: 13px; }

/* scroll progress line — filled from JS while the section is pinned */
.stack-progress {
  display: none;
  width: 190px;
  height: 3px;
  margin-top: 28px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .13);
  overflow: hidden;
}

/* driven from script.js via transform, not width — width would force a layout
   pass on every frame of the pinned scroll, scaleX stays on the compositor */
.stack-progress-bar {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 999px;
  background: var(--brand);
  transform: scaleX(0);
  transform-origin: left center;
}

/* --- right column: the cards --------------------------------------------- */
.stack-cards {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* --- below 1024px: stack with position: sticky ---------------------------
   The desktop effect is a GSAP ScrollTrigger pin, and that cannot be reused
   here: the pin locks the section to 100vh, and on a phone the left-hand header
   plus one card is already taller than the screen, so the card would be clipped.

   sticky gives the same read — each card parks under the navbar and the next one
   slides up over it — with no JS, no scroll-jacking, and nothing to re-measure
   on resize, which is where the pinned version goes wrong. The staggered `top`
   is what leaves a visible edge of each parked card instead of burying them.

   Cards are opaque (see .card-item), so the one in front always wins. */
@media (max-width: 1023px) {
  /* sticky is dead inside an `overflow: hidden` ancestor — that ancestor becomes
     the scroll container, and since it does not scroll there is no range to
     stick over. The section only needs the clip for the desktop backdrop, which
     is display:none at these widths anyway. */
  .stack-services { overflow: visible; }

  .stack-cards {
    gap: 0;
    /* room under the last card so it can still scroll up to its sticky spot */
    padding-bottom: 20vh;
  }

  .card-item {
    position: sticky;
    top: calc(var(--nav-h-scrolled) + 14px);
    margin-bottom: 22px;
    /* a shadow above the card sells the "in front of" relationship */
    box-shadow: 0 -6px 18px rgba(0, 0, 0, .35), 0 26px 60px rgba(0, 0, 0, .55);
  }

  .card-item:nth-child(2) { top: calc(var(--nav-h-scrolled) + 26px); }
  .card-item:nth-child(3) { top: calc(var(--nav-h-scrolled) + 38px); }
  .card-item:nth-child(4) { top: calc(var(--nav-h-scrolled) + 50px); }
  .card-item:nth-child(5) { top: calc(var(--nav-h-scrolled) + 62px); }
  .card-item:nth-child(6) { top: calc(var(--nav-h-scrolled) + 74px); }
  .card-item:nth-child(n + 7) { top: calc(var(--nav-h-scrolled) + 86px); }
}

/* sticky is a scroll effect, so it goes too when motion is reduced */
@media (max-width: 1023px) and (prefers-reduced-motion: reduce) {
  .card-item { position: static; }
  .stack-cards { padding-bottom: 0; }
}

.card-item {
  display: flex;
  flex-direction: column;
  padding: 22px;
  border-radius: 20px;
  border: 1px solid rgba(255, 255, 255, .10);
  /* Opaque base, not rgba(…, .97). All six cards stack in the same spot on
     desktop, so a 3% translucent front card let the headings of the cards
     behind it read straight through. The blur that used to be tweened onto the
     receded cards hid that; it is gone (it stuttered the pinned scroll), so the
     card has to actually be opaque. Against a near-black section the missing
     3% is invisible. */
  background:
    radial-gradient(120% 120% at 100% 0%, rgba(209, 26, 42, .16) 0%, rgba(209, 26, 42, 0) 55%),
    rgb(17, 17, 20);
  box-shadow: 0 26px 60px rgba(0, 0, 0, .55);
}

/* will-change holds a composited layer in GPU memory for as long as it is set,
   so six cards plus six backdrops used to keep twelve layers alive for the
   whole page. script.js now adds .is-animating only while ScrollTrigger has
   the section pinned, and drops it again on the way out. */
.stack-services.is-animating .card-item,
.stack-services.is-animating .stack-bg-img {
  will-change: opacity, transform;
}

.card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 13px;
  margin-bottom: 14px;
  border-bottom: 1px solid rgba(255, 255, 255, .10);
}

.card-num {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 4px;
  color: var(--brand);
}

.card-thumb {
  width: 46px;
  height: 46px;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .12);
  flex-shrink: 0;
}

.card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* takes the slack in a fixed-height card, so leftover room splits above and
   below the copy instead of collecting in one gap above the footer */
.card-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.card-item h3 {
  margin: 0 0 9px;
  font-size: 21px;
  font-weight: 700;
  line-height: 1.3;
  color: #fff;
}

.card-body p {
  margin: 0 0 16px;
  font-size: 14px;
  line-height: 1.65;
  color: #a9a9ae;
}

.card-item ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.card-item ul li {
  display: flex;
  align-items: center;
  gap: 11px;
  font-size: 14px;
  color: #dcdce0;
}

.card-item ul li i {
  color: var(--brand);
  font-size: 15px;
  flex-shrink: 0;
}

.card-foot {
  padding-top: 13px;
  margin-top: 14px;
  border-top: 1px solid rgba(255, 255, 255, .07);
}

.card-foot a {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  text-decoration: none;
  transition: gap .25s ease, color .25s ease;
}

.card-foot a:hover { gap: 15px; color: var(--brand); }
.card-foot a i { font-size: 12px; }

/* --- desktop: two columns + absolutely stacked cards ---------------------- */
@media (min-width: 1024px) {
  /* exactly one viewport tall — a pinned section that is shorter than the
     screen leaves ScrollTrigger's spacer showing as a flat bar underneath */
  .stack-services {
    height: 100vh;
    padding: 0 3.5%;
  }

  .stack-bg { display: block; }

  .stack-container {
    grid-template-columns: 5fr 7fr;
    gap: 48px;
  }

  .stack-progress { display: block; }

  /* Every card sits in the same spot so GSAP can stack them. A single grid cell
     does that without taking the cards out of flow, which matters because the
     content is editable now: the row grows to the tallest card on its own, so a
     longer service description can never be clipped, and there is no fixed
     height left over as dead space inside the shorter cards.

     This replaced `height: clamp(390px, 60vh, 500px)` with the cards absolutely
     positioned inside it. Measured, that left 159px of empty space in the middle
     of every card — the tallest card only ever needed 341px of the 500px. */
  .stack-cards {
    display: grid;
    grid-template-areas: "stack";
    gap: 0;
  }

  .card-item {
    grid-area: stack;
    padding: 26px 30px;
  }
}


/* ==========================================================================
   6. Why choose us
   ========================================================================== */

/* Split layout: sticky left pitch + auto-playing accordion on the right.
   The open row fills a progress bar and advances itself (script.js);
   hovering the stack pauses it, clicking a row takes over. */

.why-choose {
  position: relative;
  overflow: hidden;
  padding: 120px 8% 120px;
  background: #fff;
  color: #111;
}

/* faint diagonal grid so the white doesn't read as empty */
.why-choose::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(17, 17, 17, .045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(17, 17, 17, .045) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(80% 60% at 50% 0%, #000, transparent 75%);
  -webkit-mask-image: radial-gradient(80% 60% at 50% 0%, #000, transparent 75%);
  pointer-events: none;
}

.wc-wrap {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: 80px;
  align-items: start;
}

/* ----- left column ----------------------------------------------------- */
.wc-left { position: sticky;  }

.wc-tag {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 16px 7px 7px;
  border: 1px solid #f6dde0;
  border-radius: 999px;
  background: #fff7f8;
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--brand);
}

.wc-tag i {
  display: grid;
  place-items: center;
  width: 24px; height: 24px;
  border-radius: 999px;
  background: var(--brand);
  color: #fff;
  font-size: 11px;
}

.wc-left h2 {
  margin: 22px 0 18px;
  font-size: clamp(30px, 2.6vw + 12px, 42px);
  line-height: 1.18;
  font-weight: 800;
  letter-spacing: -.6px;
  text-wrap: balance;
}

.wc-left h2 span {
  position: relative;
  color: var(--brand);
  white-space: nowrap;
}

/* marker sweep that draws itself in behind the words */
.wc-left h2 span::after {
  content: "";
  position: absolute;
  left: -6px; right: -6px; bottom: 2px;
  z-index: -1;
  height: .42em;
  border-radius: 3px 10px 4px 12px;
  background: linear-gradient(90deg, rgba(226, 32, 46, .16), rgba(255, 138, 148, .28));
  transform-origin: left;
  animation: wc-underline 1.1s .35s cubic-bezier(.65, 0, .35, 1) both;
}

@keyframes wc-underline {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

.wc-lead {
  max-width: 420px;
  font-size: 16px;
  line-height: 1.75;
  color: #5b6270;
}

.wc-metric {
  display: flex;
  align-items: center;
  gap: 16px;
  max-width: 420px;
  margin: 30px 0 30px;
  padding: 18px 22px;
  border: 1px solid #f4e2e4;
  border-left: 3px solid var(--brand);
  border-radius: 16px;
  background: linear-gradient(120deg, #fff6f7, #fff 65%);
  box-shadow: 0 18px 34px -28px rgba(17, 17, 17, .8);
  transition: transform .25s, box-shadow .25s;
}

.wc-metric:hover {
  transform: translateY(-2px);
  box-shadow: 0 22px 38px -26px rgba(226, 32, 46, .55);
}

.wc-metric-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  border-radius: 12px;
  background: var(--brand);
  color: #fff;
  font-size: 15px;
  box-shadow: 0 10px 20px -12px var(--brand);
}

.wc-metric-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.wc-metric strong {
  font-size: 40px;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -1px;
  color: var(--brand);
}

.wc-metric em {
  font-style: normal;
  font-size: 13px;
  line-height: 1.5;
  color: #6b7280;
}

/* ----- actions --------------------------------------------------------- */
.wc-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px 22px;
}

.wc-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 15px 30px;
  border-radius: 999px;
  background: #111;
  color: #fff;
  font-weight: 700;
  text-decoration: none;
  transition: background .25s, transform .25s, box-shadow .25s;
}

.wc-cta:hover {
  background: var(--brand);
  transform: translateY(-3px);
  box-shadow: 0 16px 30px -14px var(--brand);
}

.wc-cta i { transition: transform .25s; }
.wc-cta:hover i { transform: translateX(5px); }

.wc-cta-alt {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  border-bottom: 2px solid transparent;
  color: #111;
  font-weight: 700;
  font-size: 14.5px;
  text-decoration: none;
  transition: color .25s, border-color .25s;
}

.wc-cta-alt i { font-size: 12px; transition: transform .25s; }
.wc-cta-alt:hover { color: var(--brand); border-bottom-color: var(--brand); }
.wc-cta-alt:hover i { transform: translateX(4px); }

/* ----- accordion ------------------------------------------------------- */
.wc-panels {
  display: grid;
  gap: 14px;
}

.wc-item {
  position: relative;
  overflow: hidden;
  border-radius: 16px;
  border: 1px solid #e8e9ed;
  background: #fff;
  transition: border-color .35s ease, box-shadow .35s ease, background .35s ease;
}

.wc-item.is-open {
  border-color: transparent;
  background: #fdf6f7;
  box-shadow: 0 24px 50px -28px rgba(209, 26, 42, .55);
}

.wc-head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 24px 26px;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  font: inherit;
}

.wc-num {
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .08em;
  color: #b9bdc7;
  transition: color .3s ease;
}

.wc-item.is-open .wc-num { color: var(--brand); }

.wc-title {
  flex: 1;
  font-size: clamp(17px, .7vw + 13px, 20px);
  font-weight: 700;
  color: #111;
}

/* plus that rotates into a minus */
.wc-sign {
  position: relative;
  flex: 0 0 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid #e0e2e8;
  transition: background .3s ease, border-color .3s ease, transform .3s ease;
}

.wc-sign::before,
.wc-sign::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 13px; height: 2px;
  border-radius: 2px;
  background: #111;
  transform: translate(-50%, -50%);
  transition: transform .35s cubic-bezier(.65, 0, .35, 1), background .3s;
}

.wc-sign::after { transform: translate(-50%, -50%) rotate(90deg); }

.wc-item.is-open .wc-sign {
  background: var(--brand);
  border-color: var(--brand);
  transform: rotate(180deg);
}

.wc-item.is-open .wc-sign::before,
.wc-item.is-open .wc-sign::after { background: #fff; }
.wc-item.is-open .wc-sign::after { transform: translate(-50%, -50%) rotate(0deg); }

/* grid-rows trick: animates to auto height with no JS measuring */
.wc-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .45s cubic-bezier(.65, 0, .35, 1);
}

.wc-item.is-open .wc-body { grid-template-rows: 1fr; }

.wc-body > div {
  overflow: hidden;
  padding: 0 26px 0 62px;
}

.wc-item.is-open .wc-body > div { padding-bottom: 26px; }

.wc-body p {
  font-size: 15px;
  line-height: 1.7;
  color: #5b6270;
}

.wc-body ul {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
  list-style: none;
}

.wc-body li {
  padding: 6px 14px;
  border-radius: 999px;
  background: #fff;
  border: 1px solid #efd8db;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--brand);
}

/* autoplay progress bar along the bottom of the open row */
.wc-bar {
  position: absolute;
  left: 0; bottom: 0;
  height: 3px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left;
  background: linear-gradient(90deg, var(--brand), #ff8a94);
}

.wc-item.is-open .wc-bar {
  animation: wc-fill var(--wc-step, 6s) linear forwards;
}

.wc-panels.is-paused .wc-bar { animation-play-state: paused; }

@keyframes wc-fill {
  to { transform: scaleX(1); }
}

/* Responsive */
@media (max-width: 992px) {
  .why-choose { padding: 90px 6% 80px; }
  .wc-wrap { grid-template-columns: 1fr; gap: 48px; }
  .wc-left { position: static; }
  .wc-lead { max-width: none; }
  .wc-metric { max-width: none; }
}

@media (max-width: 560px) {
  .wc-head { padding: 20px; gap: 12px; }
  .wc-body > div { padding: 0 20px; }
  .wc-item.is-open .wc-body > div { padding-bottom: 20px; }
  .wc-metric { padding: 16px 18px; gap: 14px; }
  .wc-metric strong { font-size: 34px; }
  .wc-actions { gap: 10px 16px; }
  .wc-cta { padding: 14px 24px; }
}

@media (prefers-reduced-motion: reduce) {
  .wc-left h2 span::after,
  .wc-item.is-open .wc-bar { animation: none; }
  .wc-left h2 span::after { transform: scaleX(1); }
}



/* ==========================================================================
   7. Testimonials (scroll-snap carousel)
   ========================================================================== */

.testimonial-section {
  max-width: 1100px;
  margin: 80px auto;
  padding: 0 20px;
  position: relative;
}

.testimonial-header {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 20px;
  margin-bottom: 50px;
}

/* --- the carousel track --------------------------------------------------
   This used to be Swiper. Swiper's bundle is 151 KB of JS plus an 18 KB
   render-blocking stylesheet, and on a 4 Mbps link it was the single slowest
   resource on the page at ~1.8s — to show two slides with a prev/next pair and
   a timer. All of that is native now: scroll-snap does the paging, and touch
   swiping with momentum comes free with it on every phone. script.js only has
   to move scrollLeft. */
.testimonial-swiper {
  position: relative;
  margin-top: 90px;
  padding-bottom: 60px;
}

.testimonial-track {
  display: flex;
  align-items: stretch;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* the scrollbar is the paging mechanism, not a control the design wants seen */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.testimonial-track::-webkit-scrollbar { display: none; }

.testimonial-slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
}

.testimonial-header .quote {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: rgb(239, 68, 68);
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 34px;
  color: #fff;
  font-weight: bold;
}

.testimonial-header h2 {
  font-size: 34px;
  font-weight: 700;
  line-height: 1.3;
  margin-left: 0;
  margin-bottom: 0;
}

.testimonial-cards {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 40px;
}

.testimonial-card {
  padding-right: 20px;
  border-right: 1px solid #ccc;
  margin-top: 0;
}

.testimonial-card:last-child { border: none; }

.testimonial-card h3 {
  font-size: 20px;
  margin-bottom: 15px;
}

.testimonial-card p {
  color: #666;
  line-height: 1.6;
  font-size: 15px;
  margin-bottom: 25px;
}

.testimonial-profile {
  display: flex;
  align-items: center;
  gap: 15px;
}

.testimonial-profile img {
  width: 45px;
  height: 45px;
  border-radius: 50%;
  object-fit: cover;
}

.testimonial-profile h4 {
  font-size: 15px;
  font-weight: 600;
}

.testimonial-profile span {
  font-size: 13px;
  color: #666;
}

.testimonial-arrows.bottom-arrows {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 30px;
}

.testimonial-arrows .arrow {
  padding: 6px 12px;
  border-radius: 6px;
  border: none;
  background: rgb(239, 68, 68);
  color: #fff;
  font-size: 16px;
  font-weight: bold;
  cursor: pointer;
  /* `all` made the browser watch every animatable property; only background
     actually changes on hover */
  transition: background 0.3s ease;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  transform: translateX(-20px);
}

.testimonial-arrows .arrow:hover { background: #000; }

/* Responsive */
@media (max-width: 768px) {
  /* One quote per swipe on phones instead of two stacked in one slide.
     display:contents dissolves the slide wrapper and the 2-up grid, so the cards
     become direct flex children of the track and each takes a page of its own.
     No markup change, and desktop keeps its two-per-slide layout — which is why
     script.js counts pages from scrollWidth rather than counting slide elements. */
  .testimonial-slide,
  .testimonial-cards { display: contents; }

  .testimonial-card {
    flex: 0 0 100%;
    scroll-snap-align: start;
    border: none;
    padding-right: 0;
  }

  .testimonial-header { flex-direction: column; align-items: flex-start; }
}


/* ==========================================================================
   8. Contact form
   ========================================================================== */

.contact-form-banner {
  background: #f7f7f7;
  padding: 60px 20px;
  margin-top: 60px;
}

.contact-form {
  max-width: 700px;
  margin: 0 auto;
  text-align: left;
}

.contact-form h2 {
  font-size: 28px;
  margin-bottom: 10px;
}

/* scoped to the intro copy on purpose — Contact Form 7 wraps each of its fields
   in a <p>, and a generic `.contact-form p` rule would restyle and space those */
.contact-form .contact-intro {
  font-size: 14px;
  color: #555;
  margin-bottom: 20px;
}

/* :not() keeps the submit button out: it is an <input type="submit"> under
   Contact Form 7, and would otherwise inherit the full-width text-field look */
.contact-form form input:not([type="submit"]):not([type="button"]),
.contact-form form textarea,
.contact-form form select {
  width: 100%;
  padding: 12px;
  margin: 8px 0;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.contact-form textarea {
  height: 120px;
  resize: vertical;
}

.contact-form .note {
  /* block so the submit button lands underneath it without a <br> in the markup */
  display: block;
  font-size: 13px;
  color: #666;
}

.contact-form button,
.contact-form input[type="submit"] {
  display: inline-block;
  width: auto;
  background: rgb(239, 68, 68);
  color: #fff;
  padding: 12px 20px;
  border: none;
  font-size: 15px;
  cursor: pointer;
  border-radius: 3px;
  margin-top: 10px;
  transition: 0.3s;
}

.contact-form button:hover,
.contact-form input[type="submit"]:hover { background: #000; }


/* ==========================================================================
   9. Footer
   ========================================================================== */

.xprt-footer {
  position: relative;
  background: #0b0b0d;
  color: rgba(255, 255, 255, .68);
  border-top: 3px solid var(--brand);
  overflow: hidden;
}

/* soft brand glow bleeding in from the top left */
.xprt-footer::before {
  content: "";
  position: absolute;
  top: -180px;
  left: -120px;
  width: 520px;
  height: 420px;
  background: radial-gradient(circle, rgba(209, 26, 42, .18), transparent 68%);
  pointer-events: none;
}

.xprt-footer-container {
  position: relative;
  max-width: 1280px;
  margin: 0 auto;
  padding: clamp(48px, 6vw, 72px) var(--nav-pad) 48px;
  display: grid;
  /* the brand blurb and the map need more room than the link list */
  grid-template-columns: 1.6fr 1fr 1.4fr 1.4fr;
  gap: clamp(32px, 4vw, 56px);
}

/* Brand column */
.xprt-footer-logo {
  width: 168px;
  max-width: 100%;
  height: auto;
  display: block;
  margin-bottom: 18px;
}

.xprt-footer-text {
  font-size: 14.5px;
  line-height: 1.75;
  max-width: 34ch;
}

.xprt-footer-social {
  margin-top: 22px;
  display: flex;
  gap: 10px;
}

.xprt-footer-social a {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  color: #fff;
  font-size: 15px;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .1);
  transition: background .25s ease, border-color .25s ease, transform .25s ease;
}

.xprt-footer-social a:hover {
  background: var(--brand);
  border-color: var(--brand);
  transform: translateY(-3px);
}

/* Column headings — short red rule underneath */
.xprt-footer-title {
  position: relative;
  color: #fff;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: .3px;
  margin-bottom: 26px;
  padding-bottom: 12px;
}

.xprt-footer-title::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 36px;
  height: 2px;
  background: var(--brand);
  border-radius: 2px;
}

/* Quick links */
.xprt-footer-links { list-style: none; }

.xprt-footer-links li + li { margin-top: 12px; }

.xprt-footer-links a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: inherit;
  text-decoration: none;
  font-size: 14.5px;
  transition: color .22s ease, gap .22s ease;
}

/* the arrow is drawn in CSS so the markup stays clean */
.xprt-footer-links a::before {
  content: "\203A";           /* › */
  color: var(--brand);
  font-size: 18px;
  line-height: 1;
}

.xprt-footer-links a:hover { color: #fff; gap: 13px; }

/* Contact list */
.xprt-footer-contact { list-style: none; }

.xprt-footer-contact li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 14.5px;
  line-height: 1.6;
}

.xprt-footer-contact li + li { margin-top: 16px; }

.xprt-footer-ico {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: rgba(209, 26, 42, .14);
  color: var(--brand);
  font-size: 13px;
}

.xprt-footer-contact a {
  color: inherit;
  text-decoration: none;
  word-break: break-word;
  transition: color .22s ease;
}

.xprt-footer-contact a:hover { color: #fff; }

/* Map */
.xprt-footer-mapwrap {
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .12);
  line-height: 0;
}

.xprt-footer-map {
  width: 100%;
  height: 200px;
  border: 0;
  /* muted to sit inside the dark footer, full colour on hover */
  filter: grayscale(1) contrast(.9) brightness(.85);
  transition: filter .35s ease;
}

.xprt-footer-mapwrap:hover .xprt-footer-map,
.xprt-footer-map:focus-within { filter: none; }

/* Bottom bar */
.xprt-footer-bottom {
  position: relative;
  max-width: 1280px;
  margin: 0 auto;
  padding: 20px var(--nav-pad);
  border-top: 1px solid rgba(255, 255, 255, .12);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  font-size: 13.5px;
}

.xprt-footer-top {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: inherit;
  text-decoration: none;
  transition: color .22s ease;
}

.xprt-footer-top i { transition: transform .22s ease; }

.xprt-footer-top:hover { color: #fff; }
.xprt-footer-top:hover i { transform: translateY(-3px); }

/* Responsive */
@media (max-width: 992px) {
  .xprt-footer-container { grid-template-columns: 1fr 1fr; }
  .xprt-footer-text { max-width: none; }
}

@media (max-width: 600px) {
  .xprt-footer-container {
    grid-template-columns: 1fr;
    gap: 36px;
  }
  .xprt-footer-title { margin-bottom: 20px; }
  .xprt-footer-bottom { justify-content: center; text-align: center; }
}


/* ==========================================================================
   10. WordPress plumbing
   ==========================================================================
   Classes WordPress emits that the static build never had. Kept at the end so
   nothing above needs to change. */

/* screen-reader-only text — WordPress core markup relies on this class */
.screen-reader-text {
  border: 0;
  clip-path: inset(50%);
  height: 1px;
  width: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  position: absolute !important;
  white-space: nowrap;
}

.screen-reader-text:focus {
  clip-path: none;
  height: auto;
  width: auto;
  top: 5px;
  left: 5px;
  z-index: 100000;
  display: block;
  padding: 15px 23px 14px;
  background: #fff;
  color: var(--brand);
  font-size: 14px;
  font-weight: 700;
  border-radius: 4px;
}

/* the admin bar is 32px of fixed chrome at the top, and this navbar is fixed
   too — without this they sit on top of each other for logged-in editors */
body.admin-bar .site-nav { top: 32px; }
@media screen and (max-width: 782px) { body.admin-bar .site-nav { top: 46px; } }

/* wp_nav_menu wraps the mobile dropdown links in <ul><li>, where the static
   build had bare <a> children of a flex column. These two rules put the links
   back to being full-width blocks so the existing .dropdown a padding, border
   and hover rules keep working. */
.dropdown ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  width: 100%;
}

.dropdown a { display: block; }

/* the_custom_logo() emits .custom-logo, which needs the same sizing the static
   markup got from .logo img / .xprt-footer-logo */
.logo .custom-logo-link { display: block; }

.xprt-footer-brand .custom-logo {
  width: 168px;
  max-width: 100%;
  height: auto;
  display: block;
}

/* classic editor alignment + caption classes */
.alignleft   { float: left; margin: 0 1.5em 1em 0; }
.alignright  { float: right; margin: 0 0 1em 1.5em; }
.aligncenter { display: block; margin-left: auto; margin-right: auto; }
.wp-caption { max-width: 100%; }
.wp-caption-text, .gallery-caption { font-size: 14px; color: #6b6b73; }
.sticky, .bypostauthor { display: block; }

img, video, iframe { max-width: 100%; }

/* --- contact form feedback ------------------------------------------------ */
.xprt-notice {
  margin: 0 0 18px;
  padding: 13px 16px;
  border-radius: 8px;
  font-size: 15px;
  line-height: 1.5;
}

.xprt-notice-ok {
  background: rgba(22, 133, 63, .12);
  border: 1px solid rgba(22, 133, 63, .35);
  color: #14602f;
}

.xprt-notice-bad {
  background: rgba(209, 26, 42, .10);
  border: 1px solid rgba(209, 26, 42, .35);
  color: #8d1220;
}

/* the honeypot must be reachable by bots but never by people */
.xprt-hp {
  position: absolute !important;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- inner pages / posts (page.php, single.php, 404.php) ------------------
   The front page is the designed one-pager; everything else gets a plain,
   readable column that still sits clear of the fixed navbar. */
.xprt-page {
  max-width: 800px;
  margin: 0 auto;
  padding: calc(var(--nav-h) + 56px) 5% 80px;
  color: #23232b;
}

.xprt-page h1 { font-size: clamp(28px, 4vw, 42px); line-height: 1.15; margin-bottom: 18px; }
.xprt-page h2 { font-size: 26px; margin: 32px 0 12px; }
.xprt-page h3 { font-size: 21px; margin: 26px 0 10px; }
.xprt-page p, .xprt-page li { font-size: 16.5px; line-height: 1.75; color: #4b4b55; }
.xprt-page p { margin-bottom: 16px; }
.xprt-page ul, .xprt-page ol { margin: 0 0 16px 22px; }
.xprt-page a { color: var(--brand); }
.xprt-page img { border-radius: 12px; height: auto; }

.xprt-page .xprt-meta { font-size: 14px; color: #86868f; margin-bottom: 26px; }

.xprt-pagination { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 32px; }
.xprt-pagination a, .xprt-pagination span {
  padding: 8px 14px;
  border-radius: 6px;
  border: 1px solid rgba(0, 0, 0, .12);
  text-decoration: none;
  color: #23232b;
  font-weight: 600;
}
.xprt-pagination .current { background: var(--brand); border-color: var(--brand); color: #fff; }


/* ==========================================================================
   11. Contact Form 7
   ==========================================================================
   Only applies when a CF7 shortcode is set in the Customizer. CF7 renders its
   own markup — every field wrapped in a <p>, the submit as <input type="submit">
   — and these rules make it look like the built-in form instead of stacking
   the plugin's default spacing on top of the design. */

/* CF7 wraps each field in its own <p>. The browser's default paragraph margin
   on top of the fields' own `margin: 8px 0` is where the extra gaps come from. */
.contact-form .wpcf7 p {
  margin: 0;
  font-size: inherit;
  color: inherit;
}

/* the wrap is an inline <span> by default, which stops the field inside it from
   filling the row */
.contact-form .wpcf7-form-control-wrap {
  display: block;
  width: 100%;
}

/* A newline in the CF7 template becomes a <br>. When the line above is only a
   visually-hidden label there is nothing to break away from, but the <br> still
   reserves a full line: measured, that added 18px per field and made the section
   72px taller than the built-in form. Writing the label and the field on one
   line avoids it; this makes the other formatting harmless too. */
.contact-form .wpcf7 .screen-reader-text + br { display: none; }

/* CF7's own a11y summary must stay invisible even without the plugin stylesheet */
.contact-form .screen-reader-response {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* submit + spinner on one line */
.contact-form .wpcf7-spinner { margin: 0 0 0 12px; }

/* the status line under the form, restyled to match .xprt-notice */
.contact-form .wpcf7-response-output {
  margin: 18px 0 0;
  padding: 13px 16px;
  border: 1px solid transparent;
  border-radius: 8px;
  font-size: 15px;
  line-height: 1.5;
}

.contact-form form.sent .wpcf7-response-output {
  background: rgba(22, 133, 63, .12);
  border-color: rgba(22, 133, 63, .35);
  color: #14602f;
}

.contact-form form.invalid .wpcf7-response-output,
.contact-form form.unaccepted .wpcf7-response-output,
.contact-form form.payment-required .wpcf7-response-output,
.contact-form form.failed .wpcf7-response-output,
.contact-form form.aborted .wpcf7-response-output,
.contact-form form.spam .wpcf7-response-output {
  background: rgba(209, 26, 42, .10);
  border-color: rgba(209, 26, 42, .35);
  color: #8d1220;
}

/* per-field validation */
.contact-form .wpcf7-not-valid-tip {
  display: block;
  margin: 2px 0 4px;
  font-size: 13px;
  color: var(--brand);
}

.contact-form .wpcf7-form-control.wpcf7-not-valid {
  border-color: var(--brand);
}
