/*
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.1.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 (video)
     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 (video)
   ========================================================================== */

.hero-video {
  position: relative;
  width: 100%;
  height: 95vh;
  overflow: hidden;
  background: #000;
  z-index: 1;
}

.hero-video video.hero-bg-video {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  transform: translate(-50%, -50%);
  object-fit: cover;
  z-index: -1;
}

/* Subtle dark overlay for contrast */
.video-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

.hero-content {
  position: absolute;
  top: 50%;
  left: 8%;
  transform: translateY(-50%);
  color: #fff;
  max-width: 800px;
  z-index: 2;
  animation: fadeInUp 1s ease forwards;
  opacity: 0;
}

.hero-content h1 {
  font-size: 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-block;
  padding: 12px 28px;
  background-color: #d11a2a;
  color: #fff;
  text-decoration: none;
  font-size: 1rem;
  font-weight: 600;
  border-radius: 5px;
  transition: background 0.3s ease, transform 0.2s ease;
}

.hero-btn:hover {
  background-color: #a70f1e;
  transform: translateY(-2px);
}

@keyframes fadeInUp {
  0%   { opacity: 0; transform: translateY(30px); }
  100% { opacity: 1; transform: translateY(-50%); }
}

/* Responsive */
@media (max-width: 768px) {
  .hero-content {
    left: 5%;
    right: 5%;
    text-align: center;
    transform: translateY(-50%);
  }
  .hero-content h1 { font-size: 2.2rem; }
  .hero-content p  { font-size: 1rem; }
}

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


/* ==========================================================================
   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; }
  .about-media { flex: none; width: 100%; max-width: 300px; }
}

@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);
}
