/*
 * custom-overrides.css — project-specific tweaks layered on top of the verbatim
 * AgentArc theme stylesheets. Loaded LAST in index.html so these win the cascade
 * without editing the original theme CSS. Keep changes minimal and scoped.
 */

/* --- Brand colour -------------------------------------------------------------
   The theme shipped a visitor-facing colour picker (a floating gear button that
   opened a "Configuration" off-canvas with eight swatches). It wrote
   `data-color-primary="color-primary-N"` onto <body> and remembered the choice
   in localStorage. That whole widget has been removed — markup, JS, and the CSS
   that styled it — so the brand colour is fixed here instead.

   #f14444 was exactly the theme's own `color-primary-7`, so this is a value the
   design was already built to carry. That palette block is gone from
   theme-agentarc.css now (nothing could match it once the body attribute went),
   which makes this declaration the only definition of the brand colour on the
   site. The eight original swatches are archived verbatim in
   _temp_unused/removed-color-picker/dead-css.txt.

   :root rather than a body attribute, for two reasons. The theme still declares
   `:root { --brand: #FD3A25 }` and this file loads last, so an identical-
   specificity `:root` here wins on order. And a custom property set on <body>
   would beat one inherited from <html> for everything inside it, so re-adding an
   attribute would quietly re-create the override layer this change removed. */
:root {
  --brand: #f14444;

  /* Deeper red for brand-coloured text at body sizes — see "Brand ink" below. */
  --brand-ink: #c62828;
}

/* --- Brand ink (small text only) ----------------------------------------------
   #f14444 is a light red. Measured against the actual painted background it
   carries 3.41:1 on the #F5F5F5 chip fill and 3.15:1 on the #EDECEC header —
   comfortably past WCAG AA's 3:1 bar for large text, short of the 4.5:1 it wants
   for text at body size. Ten nodes paint brand red at 16px: the active/hover
   header nav link, the hero eyebrow, and the eight section eyebrow chips.

   Those ten get #c62828 instead — 4.77:1 on #EDECEC, 5.16:1 on #F5F5F5. It reads
   as the same brand red next to the buttons; it is simply a stop or two deeper.
   Everything else keeps --brand untouched: buttons, fills, borders, progress
   rings, the chip's own 6px dot, the hero eyebrow's SVG glyph, and hover states
   on non-text elements.

   Deliberately NOT applied to `.text-brand` ("in Your Voice"). That one is 32px
   on the dark #18181B card, where the relationship inverts: #f14444 measures
   4.42:1 there and #c62828 only 2.92:1, which would fail the 3:1 large-text bar.
   Darkening it would break the one node that currently passes.

   Lighthouse scores 100 on contrast either way — axe skips any node whose
   background is a gradient, and every chip here is gradient-backed — so these
   ratios were measured in-browser by compositing the theme's white radial over
   its base fill at each element's text centre. */
.item-link:hover,
.item-link.active {
  color: var(--brand-ink);
}

/* The theme's own `.link1:hover` rule is !important, so this has to match it. */
.link1:hover {
  color: var(--brand-ink) !important;
}

.section-hero .content-wrap .sub {
  color: var(--brand-ink);
}

.heading-section .heading-sub {
  color: var(--brand-ink);
}

/* --- Header logo -------------------------------------------------------------
   The theme's original logo.svg had its wordmark baked in as outlined vector
   paths (not <text>), so it could not be re-lettered. logo-mark.svg keeps the
   original icon glyph and its gradients verbatim; the wordmark is now live text
   in the site's own font. Text rather than a new SVG on purpose: an SVG loaded
   through <img> cannot use the page's webfonts, so an SVG <text> "AgentArc"
   would have silently fallen back to a system font. The gradient matches the
   original wordmark fill (#555D64 -> #292C2E). */
.logo-site {
  display: inline-flex;
  align-items: center;
  gap: 9px;
}
.logo-site img {
  flex-shrink: 0;
}
.logo-wordmark {
  font-family: 'Urbanist', sans-serif;
  font-weight: 700;
  /* Sized so the lockup totals ~120px — the original logo.svg's width — which
     keeps the header's `justify-content: space-between` spacing unchanged. */
  font-size: 21px;
  line-height: 1;
  letter-spacing: -0.035em;
  white-space: nowrap;
  /* Why the padding: with line-height:1 the box is exactly 21px tall, but the
     font's baseline sits 18px down and the "g" descender inks 6px past it — to
     24px, i.e. 3px outside the box. The gradient paints the box and
     background-clip:text reveals glyphs only where that gradient is, so the
     descender's bottom 3px had no fill and looked cut off. The 5px vertical
     padding extends the paint area (symmetric, so align-items:center keeps the
     glyphs optically centred and the lockup width unchanged). */
  padding: 5px 0;
  background: linear-gradient(120deg, #555d64 0%, #292c2e 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: #292c2e; /* fallback where background-clip:text is unsupported */
}

@media (max-width: 767px) {
  .logo-wordmark {
    font-size: 19px;
    padding: 4px 0; /* scales the paint-area extension with the font */
  }
  .logo-site img {
    width: 27px;
    height: 26px;
  }
}

/* --- Reduced motion: never leave content invisible --------------------------
   The theme hides every animated element up front (`.effectFade { opacity: 0 }`)
   and relies on GSAP to fade it in. useThemeScripts intentionally skips
   agentarcRunAnimations() when the visitor prefers reduced motion, so without
   this rule those elements would stay at opacity 0 — i.e. blank sections.

   The theme's own exported markup happened to dodge this by carrying inline
   `opacity: 1` styles baked in by the WordPress page builder; any hand-written
   markup (such as the rewritten #contact section) has no such safety net.
   Reveal them statically instead: the content simply appears without motion. */
@media (prefers-reduced-motion: reduce) {
  .effectFade,
  .textFadeUp,
  .textFadeUp2,
  .textFadeUp3,
  .scroll-fadeZoom,
  .animate-box {
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
  }
}

/* --- Fixed header + section anchor offsets (single-page site) -----------------
   The theme set `header { position: sticky }` with no `top`, which computes to
   static — so the navbar scrolled away. Going `fixed` keeps it on screen.

   Layout is unchanged by this: the theme already overlaps the hero by giving
   .tf-header `padding-top:48px` and `margin-bottom:-116px` (i.e. it pulls the
   next section up by exactly its own height). Taking the header out of flow
   reproduces that same overlap, so the hero still starts at y=0. */
#masthead {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
}

/* Scroll targets must clear the fixed header. Applies to hash navigation,
   keyboard focus and direct /#section URLs alike. Smooth scrolling itself comes
   from Bootstrap's `:root { scroll-behavior: smooth }`, which is already wrapped
   in `prefers-reduced-motion: no-preference`. */
#about,
#services,
#works,
#process,
#benefits,
#features,
#pricing,
#faqs,
#contact {
  scroll-margin-top: 132px;
}

/* The hero is the top of the document — never offset it. */
#hero {
  scroll-margin-top: 0;
}

@media (max-width: 991px) {
  #about,
  #services,
  #works,
  #process,
  #benefits,
  #features,
  #pricing,
  #faqs,
  #contact {
    scroll-margin-top: 116px;
  }
}

/* --- About Us: fix the laptop-width card -------------------------------------
   Two theme rules make this section look sparse between 992px and 1439px:
     1. `@media (max-width:1439px){ .section-about-us { min-height:100vh } }`
        forces a full viewport height, so the card floats in a tall empty column.
     2. `.col-left img { width:100% }` blows the earth illustration up to the full
        card width (~800px inside col-lg-8), dwarfing the badge/title/button.
   Both are sizing-only corrections — the card's design (dark rounded panel,
   centred badge, title, CTA, globe bleeding off the bottom) is unchanged. */
.section-about-us.flat-spacing {
  padding-top: 80px;
  padding-bottom: 80px;
}

/* Tighten the heading block's overshoot so the card sits closer to the title. */
.section-about-us .heading-section {
  margin-bottom: 4px;
}

/* Smaller headline so it takes less vertical room (design/type unchanged otherwise). */
.section-about-us .heading-section .heading-title {
  font-size: 60px;
  line-height: 62px;
}

/* Laptop band: let the section size to its content and give the card sane
   proportions instead of a near-square 800px slab. */
@media (min-width: 992px) and (max-width: 1439px) {
  .section-about-us {
    min-height: 0;
  }
  /* Narrow the card itself rather than shrinking only its contents. */
  .section-about-us .col-lg-8 {
    max-width: 620px;
  }
  .section-about-us .col-left {
    padding-top: 56px;
  }
  .section-about-us .col-left .title {
    margin-bottom: 24px;
  }
  /* Deliberately no max-width here.
     Capping the image narrower than the card is what put dark bands down both
     sides: `.col-lg-8` above already narrows the card to 620px (596px of content),
     so a 420px image sat as an island with 88px of empty card either side. It also
     explains why the section looked right at 80% browser zoom and wrong at 100% —
     zooming out grows the CSS viewport past 1439px, this band stops matching, and
     `width: 100%` takes over. Letting that through at every zoom level leaves the
     card's WIDTH untouched and grows only its height, at the image's own aspect
     ratio, so the globe fills the card without being stretched. */
  .section-about-us .col-left img {
    margin-top: -8px;
  }
}

@media (max-width: 991px) {
  .section-about-us.flat-spacing {
    padding-top: 60px;
    padding-bottom: 60px;
  }
  /* Same `min-height:100vh` reset as the laptop band above. The theme's rule is
     `@media (max-width:1439px)`, so it also fires on phones, where the content
     only needs ~587px — leaving ~285px of dead space under the card. */
  .section-about-us {
    min-height: 0;
  }
  .section-about-us .heading-section .heading-title {
    font-size: 46px;
    line-height: 52px;
  }
  .section-about-us .col-left {
    padding-top: 48px;
  }
  /* No max-width, for the same reason as the laptop band above: an image narrower
     than the card reads as dark bands down both sides, not as breathing room. */
}

/* --- Limited Onboarding (#contact) -------------------------------------------
   The theme sizes every .heading-section .heading-title at 72px. That is too
   loud for this headline, which is longer than the others and sits beside a
   form. Scoped to #contact by ID so no other section's type scale moves. */
#contact .heading-section .heading-title {
  font-size: 48px;
  line-height: 54px;
}

#contact .contact-subtext {
  max-width: 30em;
  margin-top: 20px;
  margin-bottom: 0;
}

/* col-left is `justify-content: space-between`; with four contact items the
   default 72px block padding leaves the list drifting away from the heading. */
#contact .col-left {
  padding: 56px 0;
  gap: 40px;
}

#contact .contact-item .content .text {
  color: var(--secondary);
}
#contact .contact-item a.text:hover {
  color: var(--brand);
}

#contact .form-reassurance {
  margin-top: 16px;
  margin-bottom: 0;
  text-align: center;
}

/* Validation / success message: the CF7 stylesheet only draws a border, which
   reads as a stray box inside the light form card. */
#contact .wpcf7-response-output {
  margin: 16px 0 0;
  padding: 12px 16px;
  border-radius: 12px;
  font-size: 14px;
  line-height: 20px;
}

/* Per-field validation messages. The CF7 sheet gives .wpcf7-not-valid-tip a red
   1em block and nothing else, which lands hard against the input it belongs to
   and outsizes the label above it. */
#contact .wpcf7-not-valid-tip {
  margin-top: 8px;
  font-size: 13px;
  line-height: 18px;
  color: #c62828; /* 5.16:1 on the form's #F5F5F5 card — the theme's #dc3232 is 4.2:1 */
}

#contact .wpcf7-form-control.wpcf7-not-valid {
  border-color: #c62828;
}

/* --- "Tell us about your front desk" textarea (#contact) --------------------
   The theme styles every other field in this form as a transparent box with a
   single bottom rule, and then styles `form textarea` completely differently:
   `height: 150px; border-radius: 32px`. Dropping a textarea into the form
   unchanged therefore produces one enormous pill among five underlines.

   So it is pulled back onto the same treatment as its siblings and sized by
   `rows` instead of a fixed height. Scoped to #contact — `form textarea` is the
   theme's own rule and other forms may rely on it.

   resize: vertical, not the theme's `none`. Someone who wants to write four
   sentences should be able to see them; horizontal resize is still off because
   it would break the grid. */
#contact textarea.form-control {
  height: auto;
  min-height: 0;
  border-radius: 0;
  resize: vertical;
  /* Matches the inputs' `padding: 0 0 11px`, plus a little top padding so the
     first line does not sit against the label.

     !important is load-bearing, not laziness: wp-blog-legacy.css sets
     `.section-contact .form-contact textarea { padding: 0 !important }`, which
     no amount of specificity here can outrank. Without it the textarea's text
     sits 11px lower against its own bottom rule than every input beside it. */
  padding: 4px 0 11px !important;
  line-height: 1.6;
  /* The theme colours fields via `form textarea, form input[type="text"], ...`.
     That selector is 0-0-2 for the textarea and 0-1-2 for the inputs, so
     Bootstrap's `.form-control` (0-1-0) loses to the inputs but beats the
     textarea — leaving this one field #212529 while its siblings are #09090B.
     Close to invisible alone, obvious once you know, so it is set explicitly. */
  color: var(--primary);
}

/* The hint under the textarea. Deliberately quiet: it is the second half of the
   question, not a second label, and at label weight it would compete with the
   five real labels above it.

   13px matches .wpcf7-not-valid-tip above rather than the theme's text-body-3,
   so a validation message and this hint never disagree about size in the same
   column. */
#contact .form-hint {
  display: block;
  margin-top: 8px;
  font-size: 13px;
  line-height: 18px;
}

/* The submit button spends up to a minute in its disabled "Sending…" state on a
   cold API instance, so it has to read as deliberately busy rather than broken. */
#contact .tf-btn[disabled] {
  opacity: 0.6;
  cursor: progress;
  pointer-events: none;
}

/*
   Honeypot (see the markup comment in src/fragments/home.html).

   display:none, not an off-screen box. Both hide the field from sighted users,
   but axe-core — and therefore Lighthouse — skips display:none subtrees entirely
   while it still evaluates an off-screen one, where a decoy label on an input no
   user can reach reads as an accessibility defect. Hiding it here rather than
   inline also costs a naive bot one extra stylesheet fetch to notice.

   Class name is intentionally dull: "hp-field"/"honeypot" is the first thing a
   spam script greps the stylesheet for.
*/
.contact-alt-field {
  display: none;
}

@media (max-width: 1199px) {
  #contact .heading-section .heading-title {
    font-size: 40px;
    line-height: 46px;
  }
}

@media (max-width: 991px) {
  #contact .col-left {
    padding: 0 0 32px;
    gap: 32px;
  }
}

@media (max-width: 767px) {
  #contact .heading-section .heading-title {
    font-size: 32px;
    line-height: 38px;
  }
  /* The theme hides <br> inside headings below 768px; keep the subtext readable. */
  #contact .contact-subtext {
    margin-top: 16px;
  }
  #contact .contact-item .icon {
    width: 52px;
    height: 52px;
    font-size: 22px;
  }
}


/* --- Hero title: responsive sizing -------------------------------------------
   The theme's .text-gradient-1 hardcodes font-size:65px with NO media queries,
   overriding .text-display-2's responsive steps (96→60→32). With the longer
   headline ("Your Client Just Called at 7pm / Nobody Picked Up") the 65px text
   overflows and overlaps on small screens (65px glyphs on a 40px inherited
   line-height). Scoped to the hero only; desktop (≥992px) is untouched. */
@media (max-width: 991px) {
  .section-hero .content-wrap .title {
    line-height: 1.15;
  }
  .section-hero .content-wrap .title .text-gradient-1 {
    font-size: 48px;
  }
}

@media (max-width: 767px) {
  .section-hero .content-wrap .title {
    line-height: 1.22;
    margin-bottom: 24px;
  }
  .section-hero .content-wrap .title .text-gradient-1 {
    /* fluid between ~28px (320px screens) and 38px (larger phones) */
    font-size: clamp(28px, 8.5vw, 38px);
  }
  /* Balance the first headline's line breaks (avoids a lone word like "7pm"). */
  .section-hero .content-wrap .title .title1 {
    display: inline-block;
    text-wrap: balance;
  }
  .section-hero .content-wrap .title .title2 {
    gap: 12px;
  }
  /* The animated pill icon is a fixed 255×155px block with no mobile rules —
     scale it down proportionally so it sits beside the smaller text. */
  .section-hero .content-wrap .title-icon {
    width: 166px;
    height: 101px;
  }
  .section-hero .content-wrap .title-icon > * {
    transform: scale(0.65);
    transform-origin: top left;
  }
}

/* --- Skip-to-content link (a11y): invisible until keyboard-focused ----------- */
.skip-link {
  position: fixed;
  top: -100px;
  left: 16px;
  z-index: 10000;
  padding: 10px 20px;
  border-radius: 99px;
  background: var(--primary, #09090b);
  color: var(--white, #fff);
  font-weight: 600;
  text-decoration: none;
  transition: top 0.2s ease;
}
.skip-link:focus-visible {
  top: 16px;
  color: var(--white, #fff);
}

/* --- Keyboard focus: restore a visible focus ring for keyboard users only.
   :focus-visible never triggers on mouse/touch, so pointer users see the design
   exactly as before. --- */
a:focus-visible,
button:focus-visible,
[role='button']:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--brand, #f14444);
  outline-offset: 2px;
}

/* Programmatic focus target for SPA navigation — never show a ring on <main>. */
#main-content:focus {
  outline: none;
}

/* --- Twemoji flag webfont ----------------------------------------------------
   Windows ships no emoji flag glyphs, so Chrome/Edge on Windows render the bare
   two-letter ISO pair ("US") where a flag should be — which is why the flags
   showed on the user's phone but not on desktop. This font carries only the
   regional-indicator range, so it adds ~77 KB and affects nothing else on the
   page; the unicode-range keeps the browser from downloading it at all unless a
   flag is actually painted. Platform emoji fonts stay ahead of it in the stacks
   below, so macOS/iOS/Android keep their own native flags. --------------------- */
@font-face {
  font-family: 'TwemojiCountryFlags';
  unicode-range: U+1F1E6-1F1FF;
  src: url('/assets/fonts/TwemojiCountryFlags.woff2') format('woff2');
  font-display: swap;
}

/* --- Phone country-code selector (#contact) ---------------------------------
   Trigger sits inline with the phone input and inherits the theme's contact
   form treatment: transparent, no side borders, 1px bottom rule. The panel
   itself is appended to <body> by useCountryCode (the form's `.overflow-hidden`
   wrapper and GSAP's transform on `.effectFade` would otherwise clip it), so it
   is styled here at top level rather than under `.section-contact`. --------- */
.phone-field {
  display: flex;
  align-items: stretch;
  gap: 10px;
}
.phone-field .wpcf7-form-control-wrap {
  flex: 1 1 auto;
  min-width: 0; /* lets the input shrink instead of forcing overflow */
}
.phone-field input[type='tel'] {
  width: 100%;
}

.country-toggle {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 6px 0 0;
  border: 0;
  border-bottom: 1px solid var(--neutral-300);
  background: none;
  color: inherit;
  font: inherit;
  line-height: 1.5;
  cursor: pointer;
  white-space: nowrap;
}
.country-toggle:hover {
  border-bottom-color: var(--brand, #f14444);
}
.country-toggle .country-flag {
  font-size: 1.15em;
  font-family: 'TwemojiCountryFlags', 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
}
.country-toggle .country-dial {
  font-variant-numeric: tabular-nums;
}
.country-toggle .country-caret {
  width: 0;
  height: 0;
  margin-left: 2px;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  opacity: 0.55;
  transition: transform 0.18s ease;
}
.country-toggle[aria-expanded='true'] .country-caret {
  transform: rotate(180deg);
}

.country-panel {
  position: fixed;
  z-index: 10050;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--white, #fff);
  border: 1px solid var(--neutral-300, #e4e4e7);
  border-radius: 16px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.16);
}
.country-panel[hidden] {
  display: none;
}
.country-panel__search {
  flex: 0 0 auto;
  padding: 10px;
  border-bottom: 1px solid var(--neutral-200, #f4f4f5);
}
.country-panel__input {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--neutral-300, #e4e4e7);
  border-radius: 10px;
  background: var(--neutral-100, #fafafa);
  font: inherit;
  color: inherit;
}
.country-panel__input:focus {
  outline: none;
  border-color: var(--brand, #f14444);
}
.country-panel__list {
  flex: 1 1 auto;
  margin: 0;
  padding: 6px;
  overflow-y: auto;
  list-style: none;
  overscroll-behavior: contain; /* stop the page scrolling once the list bottoms out */
  -webkit-overflow-scrolling: touch;
}
.country-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 10px;
  cursor: pointer;
}
.country-option[hidden] {
  display: none;
}
.country-option:hover,
.country-option.is-active {
  background: var(--neutral-100, #f4f4f5);
}
.country-option[aria-selected='true'] {
  font-weight: 600;
}
.country-option__flag {
  flex: 0 0 auto;
  font-size: 1.15em;
  font-family: 'TwemojiCountryFlags', 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
}
.country-option__name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.country-option__dial {
  flex: 0 0 auto;
  color: var(--neutral-500, #71717a);
  font-variant-numeric: tabular-nums;
}
.country-panel__empty {
  margin: 0;
  padding: 18px 12px;
  text-align: center;
  color: var(--neutral-500, #71717a);
}

.country-backdrop {
  position: fixed;
  inset: 0;
  z-index: 10040;
  background: rgba(0, 0, 0, 0.4);
}
.country-backdrop[hidden] {
  display: none;
}

/* Bottom sheet on phones: a viewport-anchored dropdown is awkward to thumb and
   can be pushed off-screen by the software keyboard. */
@media (max-width: 575.98px) {
  .country-panel.is-sheet {
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    width: auto;
    max-height: 72vh;
    max-height: 72dvh;
    border-radius: 18px 18px 0 0;
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .country-option {
    padding: 12px 10px; /* 44px touch target */
  }
}

/* Very narrow phones: the dial code alone keeps the input usable. */
@media (max-width: 359.98px) {
  .phone-field {
    gap: 6px;
  }
  .country-toggle .country-flag {
    display: none;
  }
}

/* --- Mobile typography corrections (≤575px) -----------------------------------
   Fixes reported in WhatsApp screenshots 2026-08-06: hero eyebrow too wide/
   prominent, About heading too large (wraps to 4 lines, bleeds container).
   Scoped to mobile-only per standing constraint: "all text sizes are connected
   in the website so make sure only one changes" — these rules sit inside a
   mobile media query and target only the specific sections named. ------------ */
@media (max-width: 575.98px) {
  /* Hero eyebrow: the theme's 16px pill measured 267px of a 375px viewport, so it
     read as wide as the navbar. 13px + tighter padding/gap/icon brings it to
     ~235px, leaving visible margin on both sides. */
  .section-hero .sub {
    font-size: 13px;
    line-height: 18px;
    gap: 6px;
    padding: 5px 12px;
  }
  /* The sparkle SVG carries width/height="20" attributes; CSS overrides them. */
  .section-hero .sub svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
  }

  /* About Us heading: 46px wraps to 4 lines and bleeds at 375px. Drop to 32px. */
  .section-about-us .heading-section .heading-title {
    font-size: 32px;
    line-height: 38px;
  }

  /* --- About Us dark card ----------------------------------------------------
     The card's inner column is only 334px at this width, but the theme sizes its
     contents for desktop: the badge measured 315px (94% of that), the h5 title
     334px (100% — edge to edge), and the CTA 189px. All three are scoped to
     `.section-about-us .col-left` so no other badge, h5 or .tf-btn on the site
     changes size. ---------------------------------------------------------- */

  /* "Now onboarding 5 med spas a month" — width:max-content, so shrinking the
     type shrinks the pill. */
  .section-about-us .col-left .sub {
    font-size: 12px;
    line-height: 17px;
    gap: 8px;
    padding: 4px 11px;
  }

  /* "Every Call Answered in Your Voice" — the theme's 22px measured 334px inside
     a 351px card, i.e. ~8px of margin each side, which is what read as bleeding.
     18px lands at ~273px (78% of the card) and stays the card's clear headline. */
  .section-about-us .col-left .title {
    font-size: 18px;
    line-height: 24px;
    margin-bottom: 18px;
  }

  /* "Hear My Agent Live" — scoped to this card only, not .tf-btn site-wide. */
  .section-about-us .col-left .tf-btn {
    font-size: 13px;
    line-height: 18px;
    padding: 11px 18px;
  }
}

/* ==========================================================================
   Colour contrast (WCAG 2.1 AA)
   --------------------------------------------------------------------------
   Lighthouse/axe flagged 11 nodes on the homepage. Each fix below is the
   smallest palette step that clears the threshold, and each is scoped to the
   backgrounds it was measured against so nothing on a dark surface changes.
   ========================================================================== */

/* `.text-secondary` (--secondary, zinc-500 #71717A) scored 4.39:1 on the page
   background #F4F4F5 and 4.09:1 on the footer's #EDECEC — both just under the
   4.5:1 required for body text. Every one of the 16 uses on this site sits on
   one of those two light surfaces (verified in the browser), so stepping the
   utility down one stop on the theme's own Zinc scale is safe site-wide:
   zinc-600 #52525B gives 7.03:1 and 6.56:1 respectively.
   The --secondary variable itself is left alone; only the text utility moves,
   so any border/background that reads from the variable is unaffected. */
.text-secondary {
  color: #52525b !important;
}

/* The process cards' "01 /03" step counters. These are real content (they tell
   you which of three steps you are reading), not decoration, so they have to
   meet the 3:1 large-text threshold — the current values score 2.33:1 and
   1.15:1 on #F4F4F5. Scoped to `.process-card .number` because
   `.text-neutral-200` is used in nine places, six of them over a dark
   rgba(0,0,0,.56) overlay where it already passes and must stay light. The
   light/dark relationship between the two spans is preserved: the current step
   stays clearly the darker of the pair. */
.process-card .number .text-neutral-400 {
  color: #52525b !important; /* 7.03:1 */
}

.process-card .number .text-neutral-200 {
  color: #8a8a92 !important; /* 3.12:1 */
}

/* ==========================================================================
   Pricing section (three flat plans)
   --------------------------------------------------------------------------
   Ported from the supplied drop-in file. Every selector keeps its `.gsp-`
   prefix and every type size lives under `.gsp`, so this block cannot reach
   any of the site's shared text sizes — the sizes here are new classes, not
   overrides of the theme's h1-h6 / .text-* scale.
   Deviations from the drop-in, all deliberate:
     - breaks to one column at 991.98px, not 960px, so it lines up with the
       theme's lg breakpoint instead of squeezing three cards into the
       960-991px band;
     - cards stretch to equal height and the minutes line is pushed to the
       bottom with margin-top:auto, so the three footers align;
     - adds :focus-visible rings, since .gsp-cta is a new class the theme's
       own focus styles don't cover;
     - drops the unused `.gsp-setup-price .n s` strikethrough rule.
   ========================================================================== */
.gsp {
  --gsp-ink: #1b1b1b;
  --gsp-mut: #6f6f6f;
  --gsp-red: #f5352a;
  --gsp-line: rgba(0, 0, 0, 0.08);
  --gsp-dark: #1c1c1c;
  background: #ebebeb;
  padding: 88px 24px 96px;
  font-family: inherit;
  color: var(--gsp-ink);
  -webkit-font-smoothing: antialiased;
}

.gsp *,
.gsp *::before,
.gsp *::after {
  box-sizing: border-box;
}

.gsp * {
  margin: 0;
}

.gsp-in {
  max-width: 1140px;
  margin: 0 auto;
}

/* The drop-in shipped its own chip — a white 999px pill with a 13px label and a
   7px flex-gap dot. Every other section on the page uses the theme's eyebrow
   (`.heading-section .heading-sub`: an 8px-radius #F5F5F5 tab with a white
   radial sheen, three inset shadows and a 6px dot set 16px in), so the pricing
   chip was the odd one out. These declarations are the theme rule's, copied
   value-for-value, with two differences forced by this section's markup:

     - the dot is a real <i> element here, not a ::before, so it is positioned
       absolutely into the same 30px left padding rather than sitting in the
       flex flow. Visually identical; the flex `gap` is gone because an
       out-of-flow child does not consume one;
     - the theme rule ends with `margin-bottom: 32px`. That is left at 0 — the
       heading below carries its own `margin-top: 26px`, and since a flex
       container's margins do collapse with an adjacent sibling's, declaring 32
       here would silently win and stretch the pricing section's rhythm.

   Colour follows the same split as the theme chips after the brand change:
   label in --brand-ink (#c62828 on #F5F5F5 = 5.16:1), dot in --brand. The chip
   paints its own opaque fill, so the #ebebeb section background behind it does
   not enter the contrast calculation.

   The auto side margins are folded in here rather than living in a separate
   override at the foot of the file: `display: flex` + `width: max-content` now
   come from this rule, and those were the only reason the override existed. */
.gsp-badge {
  display: flex;
  position: relative;
  align-items: center;
  width: max-content;
  margin-left: auto;
  margin-right: auto;
  border-radius: 8px;
  padding: 6px 16px 6px 30px;
  color: var(--brand-ink);
  font-size: 16px;
  font-weight: 600;
  line-height: 24px;
  background: radial-gradient(62.56% 62.56% at 28.14% -10.42%, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%), linear-gradient(0deg, #F5F5F5, #F5F5F5);
  box-shadow: 0px -3px 0px 0px #E9E9E9 inset, 0px 1px 0px 0px rgba(255, 255, 255, 0.6980392157) inset, 0px 3px 3px 0px rgba(0, 0, 0, 0.1411764706);
}

.gsp-badge i {
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  width: 6px;
  height: 6px;
  border-radius: 99px;
  background: var(--brand);
}

.gsp-h {
  font-size: clamp(32px, 4.4vw, 58px);
  line-height: 1.08;
  font-weight: 500;
  letter-spacing: -0.02em;
  margin: 26px auto 0;
  max-width: 19ch;
  text-align: center;
}

/* The price is the line that has to land, so it gets the weight jump and the
   colour: --brand-ink, not --brand. Both clear WCAG on #ebebeb at this size
   (everything from the 32px floor up is "large text", so the bar is 3:1), but
   #f14444 only makes 3.12:1 while #c62828 makes 4.71:1 — enough margin that the
   line stays legible if the section fill is ever lightened. */
.gsp-h b {
  font-weight: 700;
  color: var(--brand-ink);
}

/* From the theme's lg breakpoint up, break the sentences apart: the price gets
   its own line instead of trailing the comparison mid-sentence.

   `display: block` on the <b> is the whole mechanism — the run of text before
   it becomes an anonymous block box, which is exactly the sibling line we want,
   so the markup needs no extra wrapper. max-width has to come off for it to
   work: the comparison sentence measures ~792px at the 58px cap and 19ch is
   only ~659px, so it would wrap and produce three lines rather than two. The
   1140px container leaves ~44% headroom at every width in this range, so it
   stays one line even if Urbanist fails to load and a wider fallback renders.
   Below 992px the two sentences flow together as before. */
@media (min-width: 992px) {
  .gsp-h {
    max-width: none;
  }

  .gsp-h b {
    display: block;
  }
}

/*
 * Stacked-card lip — the same detail the FAQ accordion items carry.
 *
 * theme-agentarc.css:9251 builds it purely out of box-shadow, no extra elements:
 * an inset band along the bottom reads as a second card sitting behind this one,
 * an inset hairline along the top catches the light, and two outer shadows lift
 * the whole thing off the page. Reproduced here rather than by borrowing the
 * theme's selector, because `.accordion-faq_item` also sets padding, radius and
 * `overflow: hidden`, which these cards define for themselves.
 *
 * Split into a top/bottom pair of custom properties so the dark Growth card can
 * swap the two alphas without restating the outer shadows. On #fff the reference
 * card's rgba(255,255,255,0.6) top lip would be invisible, so the light variant
 * uses a faint neutral instead — same "lip" read, just inverted for the surface
 * it sits on. Bottom stays a shade of black in both, which is what actually
 * carries the effect.
 */
/*
 * Alphas are calibrated to the absolute darkness of the reference band, not
 * copied from it. The FAQ item's face is --neutral-100 (#F4F4F5), so its
 * rgba(0,0,0,0.05) bottom band lands at ~rgb(232) — a shade darker than the
 * #EBEBEB page behind it, which is what makes it read as a card edge. These
 * cards are pure #fff, so the same 0.05 would land at rgb(241) and disappear
 * into the lift shadow. 0.09 puts the band back at ~rgb(232), matching what the
 * reference actually looks like.
 *
 * The top hairline is a highlight in the reference (white 0.6 over #F4F4F5,
 * ~+7 levels). Nothing is brighter than #fff, so the light variant goes the
 * same distance the other way — a dark hairline, which reads as the edge of a
 * card just above rather than a highlight on this one.
 *
 * Bottom outranks top deliberately, and that hierarchy is carried by BOTH
 * thickness (8px vs 5px) and contrast against the face (-23 vs -19 levels), not
 * by keeping the top nearly invisible. An earlier -9 was too quiet to register
 * at all on a #fff card.
 */
.gsp {
  --gsp-lip-top: 0 5px 0 0 rgba(0, 0, 0, 0.075) inset;
  --gsp-lip-bottom: 0 -8px 0 0 rgba(0, 0, 0, 0.09) inset;
  --gsp-lift: 0 7.77px 16px 0 rgba(0, 0, 0, 0.06), 0 3px 3px 0 rgba(0, 0, 0, 0.1);
}

/* --- $997 setup / refund card --- */
.gsp-setup {
  margin-top: 40px;
  background: #fff;
  border: 1px solid var(--gsp-line);
  border-radius: 26px;
  padding: 34px 36px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 28px;
  align-items: center;
  box-shadow: var(--gsp-lift), var(--gsp-lip-bottom), var(--gsp-lip-top);
}

.gsp-eyebrow {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #d92b20; /* 4.457:1 on #fff — the drop-in's #f5352a scored 3.4:1 */
}

.gsp-setup h3 {
  font-size: 23px;
  font-weight: 500;
  letter-spacing: -0.01em;
  margin-top: 10px;
}

.gsp-setup p {
  font-size: 15px;
  line-height: 1.6;
  color: var(--gsp-mut);
  margin-top: 12px;
  max-width: 62ch;
}

.gsp-setup-list {
  list-style: none;
  padding: 0;
  margin: 16px 0 0;
  display: grid;
  gap: 9px;
}

.gsp-setup-list li {
  display: grid;
  grid-template-columns: 16px 1fr;
  gap: 10px;
  font-size: 14px;
  line-height: 1.45;
  color: #3d3d3d;
}

.gsp-setup-list li::before {
  content: "✓";
  color: #0f7a37;
  font-weight: 700;
  line-height: 1.45;
}

.gsp-setup-price {
  text-align: right;
  white-space: nowrap;
}

.gsp-setup-price .n {
  font-size: 40px;
  font-weight: 500;
  letter-spacing: -0.02em;
  display: block;
}

.gsp-setup-price .l {
  font-size: 13px;
  color: var(--gsp-mut);
  display: block;
  margin-top: 4px;
}
/* --- the three plan cards --- */
.gsp-cards {
  margin-top: 22px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  align-items: stretch; /* equal height; drop-in used `start` */
}

.gsp-card {
  background: #fff;
  border: 1px solid var(--gsp-line);
  border-radius: 26px;
  padding: 30px 28px 32px;
  display: flex;
  flex-direction: column;
  box-shadow: var(--gsp-lift), var(--gsp-lip-bottom), var(--gsp-lip-top);
}

/* Growth — the best-seller card. Its own lift shadow stays (it is what separates
   this card from the two beside it), so only the two lips are re-pointed.

   BOTH lips invert to white here, which is the one place this deviates from the
   reference's direction. On the light cards the bottom lip is darker than the
   face — a shadowed sliver of a second card. Repeating that on #1c1c1c does not
   work: the face is already at level 28, so there are only 28 levels of headroom
   below it, and the card's own `0 22px 50px -18px rgba(0,0,0,0.4)` drop shadow
   sits directly under that edge. A darker band there is indistinguishable from
   the silhouette — rendered side by side against black-at-0.32 and black-at-0.72,
   neither read as a lip at all.
   Going lighter has the whole range above 28 to work with and reads immediately:
   the sliver becomes the lit edge of the card beneath instead of its shadow.
   Same "stacked card" effect, lit from the only direction that has contrast to
   spend on a near-black surface. */
.gsp-card.mid {
  background: var(--gsp-dark);
  color: #fff;
  border-color: transparent;
  --gsp-lip-top: 0 5px 0 0 rgba(255, 255, 255, 0.085) inset;
  --gsp-lip-bottom: 0 -8px 0 0 rgba(255, 255, 255, 0.15) inset;
  box-shadow: 0 22px 50px -18px rgba(0, 0, 0, 0.4), var(--gsp-lip-bottom), var(--gsp-lip-top);
}

.gsp-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.gsp-name {
  font-size: 15px;
  font-weight: 600;
}

.gsp-for {
  font-size: 13px;
  color: var(--gsp-mut);
}

.gsp-card.mid .gsp-for {
  color: #a5a5a5;
}

.gsp-pill {
  /* Not var(--gsp-red): white on #f5352a is 3.87:1, and at 11px bold this text
     is not "large" under WCAG, so it needs 4.5:1. #c4231a gives 5.72:1 and is
     the same hue family as the eyebrow's #d92b20. */
  background: #c4231a;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 5px 11px;
  border-radius: 999px;
  white-space: nowrap;
}

.gsp-price {
  margin-top: 22px;
  font-size: 52px;
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1;
}

.gsp-flat {
  margin-top: 9px;
  font-size: 13px;
  font-weight: 600;
  color: #0f7a37;
}

.gsp-card.mid .gsp-flat {
  color: #4ade80;
}

.gsp-cta {
  margin-top: 22px;
  display: block;
  text-align: center;
  text-decoration: none;
  background: var(--gsp-dark);
  color: #fff;
  border-radius: 999px;
  padding: 14px 20px;
  font-size: 14px;
  font-weight: 600;
  transition:
    transform 0.16s,
    opacity 0.16s;
}

.gsp-card.mid .gsp-cta {
  background: #fff;
  color: var(--gsp-dark);
}

.gsp-cta:hover {
  transform: translateY(-1px);
  opacity: 0.9;
  color: #fff;
}

.gsp-card.mid .gsp-cta:hover {
  color: var(--gsp-dark);
}

/* .gsp-cta is a new class, so the theme's focus styling doesn't reach it. */
.gsp-cta:focus-visible {
  outline: 3px solid var(--gsp-red);
  outline-offset: 3px;
}

.gsp-card.mid .gsp-cta:focus-visible {
  outline-color: #fff;
}

@media (prefers-reduced-motion: reduce) {
  .gsp-cta {
    transition: none;
  }

  .gsp-cta:hover {
    transform: none;
  }
}

.gsp-hr {
  height: 1px;
  background: var(--gsp-line);
  margin: 26px 0 20px;
}

.gsp-card.mid .gsp-hr {
  background: rgba(255, 255, 255, 0.14);
}

.gsp-inc {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.gsp-list {
  list-style: none;
  padding: 0;
  /* Bottom margin is the MINIMUM gap before the minutes line. It has to live
     here rather than as `.gsp-list + .gsp-mins { margin-top }`, because that
     adjacent rule would beat the `margin-top:auto` below and unpin the
     footer — which is how the Growth card's taller "Most spas" pill pushed
     its minutes line 10px below the other two. */
  margin: 16px 0 18px;
  display: grid;
  gap: 12px;
  align-content: start;
}

.gsp-list li {
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: 11px;
  font-size: 14px;
  line-height: 1.45;
  color: #3d3d3d;
}

.gsp-card.mid .gsp-list li {
  color: #dcdcdc;
}

.gsp-list li::before {
  content: "";
  width: 16px;
  height: 16px;
  border-radius: 5px;
  background-color: #f0f0f0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23444' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
  background-size: 11px;
  background-repeat: no-repeat;
  background-position: center;
  margin-top: 2px;
}

.gsp-card.mid .gsp-list li::before {
  background-color: rgba(255, 255, 255, 0.14);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
}

/* margin-top:auto pins the minutes line to the card bottom so all three
   footers sit on one line regardless of bullet wrapping. */
.gsp-mins {
  margin-top: auto;
  padding-top: 15px;
  border-top: 1px solid var(--gsp-line);
  font-size: 13px;
  color: var(--gsp-mut);
}

.gsp-card.mid .gsp-mins {
  border-top-color: rgba(255, 255, 255, 0.14);
  color: #a5a5a5;
}

.gsp-anchor {
  margin-top: 26px;
  text-align: center;
  font-size: 13.5px;
  color: #5f5f5f; /* 5.57:1 on #ebebeb; the drop-in's #6f6f6f was 4.31:1 */
  line-height: 1.6;
}

/* --- responsive --- */
@media (max-width: 1199.98px) {
  .gsp-card {
    padding: 26px 22px 28px;
  }

  .gsp-price {
    font-size: 44px;
  }
}

/* One column from the theme's lg breakpoint down. */
@media (max-width: 991.98px) {
  .gsp-cards {
    grid-template-columns: 1fr;
  }

  .gsp-setup {
    grid-template-columns: 1fr;
  }

  .gsp-setup-price {
    text-align: left;
  }

  .gsp {
    padding: 64px 18px 72px;
  }

  .gsp-card {
    padding: 28px 26px 30px;
  }

  .gsp-price {
    font-size: 48px;
  }
}

@media (max-width: 575.98px) {
  .gsp {
    padding: 48px 16px 56px;
  }

  .gsp-h {
    max-width: none;
  }

  .gsp-setup {
    padding: 26px 22px;
    border-radius: 20px;
  }

  .gsp-setup h3 {
    font-size: 20px;
  }

  .gsp-setup-price .n {
    font-size: 34px;
  }

  .gsp-card {
    padding: 24px 20px 26px;
    border-radius: 20px;
  }

  .gsp-price {
    font-size: 42px;
  }

  /* Stack name and badge when both would crowd a 320px line. */
  .gsp-top {
    flex-wrap: wrap;
  }
}

/* --- Centred eyebrow chips ---------------------------------------------------
   Three sections have a left-aligned eyebrow because their .heading-section has
   no `center` class: #services, #process and #contact. The theme already
   centres chips in the `center` sections with
   `.heading-section.center .heading-sub { margin-inline: auto }` — that works
   because .heading-sub is `display:flex; width:max-content`, so auto margins
   have free space to split. Reusing that exact idiom here.

   Only the chip moves; the h2 and body copy under it stay left-aligned, which
   is what was asked for. Nothing here touches font-size, so the site's shared
   type scale is untouched.

   991.98px, not 767.98px: that is where all three sections switch from the
   stacked layout (heading full-width above the content) to side-by-side
   columns. Centring is only coherent in the stacked range — in a narrow left
   column a centred chip reads as a mistake. Tying the query to the layout's
   own breakpoint keeps phone and tablet portrait consistent.

   #pricing is not in this list: its chip is centred at every width, and that
   now lives in the .gsp-badge rule itself. */
@media (max-width: 991.98px) {
  #services .heading-section .heading-sub,
  #process .heading-section .heading-sub,
  #contact .heading-section .heading-sub {
    margin-left: auto;
    margin-right: auto;
  }
}

/* --- Services: copy panel in place of the rotating photo ---------------------
   #services used to end with a 416x240 photo (service-1..4.jpg) that swapped its
   src as you opened each accordion card. The photos were generic stock and said
   nothing the cards did not already say, so they are gone and this panel carries
   a lead line plus three points per card instead. Same slot, same swap-on-click
   behaviour, content that argues for the offer.

   Positioning is copied from the theme's `.services-image` deliberately, not
   reinvented: `position:absolute; bottom:0` against `.container` (the only
   positioned ancestor, `theme-agentarc.css:1667`), landing in the 260px of space
   `.section-services .col-left` reserves below the heading. Keeping the exact
   same contract means the block sits where the photo sat at every width.

   The one change is height. The photo was a fixed 240px; copy cannot be, so the
   height is natural and the bottom edge is what stays pinned — a panel that
   wraps to one more line grows upward into reserved space rather than pushing
   anything down.

   Every font-size here is under `.service-points`, so the site's shared type
   scale is untouched. */
.service-points {
  position: absolute;
  bottom: 0;
  width: 100%;
  max-width: 416px;
}

/* Hidden panels are display:none, so they leave the accessibility tree with the
   layout — a screen reader reads the open card's copy and not the other three. */
.service-points_panel {
  display: none;
  padding: 28px 28px 30px;
  border-radius: 16px;
  background-color: var(--neutral-100);
  box-shadow:
    0px 7.77px 16px 0px rgba(0, 0, 0, 0.0588235294),
    0px 3px 3px 0px rgba(0, 0, 0, 0.1019607843),
    0px -6px 0px 0px rgba(0, 0, 0, 0.0509803922) inset,
    0px 3px 0px 0px rgba(255, 255, 255, 0.6) inset;
}

/* The photo cross-faded on swap; this keeps that beat. An animation rather than a
   transition because the element goes display:none -> block, and a transition has
   nothing to interpolate from across that. */
.service-points_panel.is-active {
  display: block;
  animation: servicePointsIn 0.28s ease both;
}

@keyframes servicePointsIn {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .service-points_panel.is-active {
    animation: none;
  }
}

.service-points_lead {
  margin: 0 0 18px;
  font-size: 15px;
  line-height: 22px;
  font-weight: 500;
  color: var(--neutral-600);
}

.service-points_list {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* neutral-800 on neutral-100 is ~11:1. Worth stating because the theme's own
   `.text-neutral-300` body copy in this section sits at roughly 1.2:1 on the same
   background — readable colour here is a choice, not the inherited default. */
.service-points_list li {
  position: relative;
  padding-left: 26px;
  font-size: 15px;
  line-height: 21px;
  font-weight: 600;
  color: var(--neutral-800);
}

/* Brand disc plus a two-border tick, so the marker costs no request and scales
   with the text instead of pixelating. */
.service-points_list li::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 0;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background-color: var(--brand);
}

.service-points_list li::after {
  content: "";
  position: absolute;
  top: 7.5px;
  left: 4.5px;
  width: 6px;
  height: 3px;
  border-left: 2px solid var(--white);
  border-bottom: 2px solid var(--white);
  transform: rotate(-45deg);
}

/* Below 992px the section stacks and the panel rejoins the flow, matching what
   the theme did with `.services-image` at this breakpoint. It goes full width
   rather than staying a centred 416px block, because the accordion cards above it
   are full width and a narrow column under them reads as a mistake. Three points
   in a row then fill that width instead of leaving a tall ragged edge. */
@media (max-width: 991.98px) {
  .service-points {
    position: static;
    max-width: 100%;
    margin-top: 24px;
  }

  .service-points_list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px 24px;
  }
}

/* One column again once a third of the viewport can no longer hold a short line
   without breaking after every second word. */
@media (max-width: 575.98px) {
  .service-points_panel {
    padding: 22px 20px 24px;
  }

  .service-points_list {
    grid-template-columns: 1fr;
    gap: 12px;
  }
}
