/*
  WebGuy IT — New Site (rewrite)
  Brand design layer on top of Bootstrap 5.

  Ported from the Astro site's src/styles/global.css (@theme tokens + component
  classes). Bootstrap provides the grid, navbar, accordion, and base utilities;
  this file provides the brand tokens, typography, buttons, and the custom
  section/card/hero/CTA components. Load AFTER Bootstrap so these win.
*/

:root {
  /* Brand tokens (single source of truth) — greens match the logo olive */
  --wg-primary: #32620e;
  --wg-primary-deep: #264d0a; /* AA-safe green for fills / small text */
  --wg-navy: #032841;
  --wg-gold: #d8ac2f;
  --wg-darkgreen: #202d10;
  --wg-lightgreen: #97ba66;
  --wg-offwhite: #e6e7e2;
  --wg-accent-green: #34904A; /* How We Run page: value card accents */

  /* Hand-drawn marker swipe (nav mega panel + case study headings) */
  --wg-marker: linear-gradient(transparent 62%, rgba(151, 186, 102, 0.5) 62%, rgba(151, 186, 102, 0.5) 96%, transparent 96%);

  --wg-font-display: "Expletus Sans", ui-sans-serif, system-ui, sans-serif;
  --wg-font-body: "Nunito Sans", ui-sans-serif, system-ui, sans-serif;

  /* Map Bootstrap's primary onto the brand green */
  --bs-primary: #32620e;
  --bs-primary-rgb: 50, 98, 14;
  --bs-body-color: #032841;
  --bs-body-bg: #e6e7e2;
  --bs-body-font-family: var(--wg-font-body);
  --bs-link-color: #32620e;
  --bs-link-hover-color: #202d10;
  --bs-border-color: rgba(3, 40, 65, 0.1);
}

/* ── Base ─────────────────────────────────────────────── */
html {
  scroll-behavior: smooth;
}

body {
  background-color: var(--wg-offwhite);
  color: var(--wg-navy);
  font-family: var(--wg-font-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--wg-font-display);
  font-weight: 700;
  color: var(--wg-navy);
  text-wrap: balance;
}

p { text-wrap: pretty; }

:focus-visible {
  outline: 3px solid var(--wg-navy);
  outline-offset: 2px;
  border-radius: 2px;
}

::selection {
  background-color: var(--wg-lightgreen);
  color: var(--wg-darkgreen);
}

/* ── Color helpers (mirror the Astro utility intent) ──── */
.text-navy   { color: var(--wg-navy) !important; }
.text-navy-85 { color: rgba(3, 40, 65, 0.85) !important; }
.text-navy-70 { color: rgba(3, 40, 65, 0.7) !important; }
.text-navy-60 { color: rgba(3, 40, 65, 0.6) !important; }
.text-primary-deep { color: var(--wg-primary-deep) !important; }
.text-darkgreen { color: var(--wg-darkgreen) !important; }
.text-lightgreen { color: var(--wg-lightgreen) !important; }
.text-gold   { color: var(--wg-gold) !important; }
.text-offwhite { color: var(--wg-offwhite) !important; }
.text-offwhite-85 { color: rgba(230, 231, 226, 0.85) !important; }
.text-offwhite-70 { color: rgba(230, 231, 226, 0.7) !important; }
.text-offwhite-60 { color: rgba(230, 231, 226, 0.6) !important; }

.bg-navy { background-color: var(--wg-navy) !important; }
.bg-offwhite { background-color: var(--wg-offwhite) !important; }
.bg-white-panel { background-color: #fff !important; }
.bg-gold { background-color: var(--wg-gold) !important; }

.font-display { font-family: var(--wg-font-display) !important; }

/* ── Layout scaffolding ───────────────────────────────── */
.wg-container {
  width: 100%;
  max-width: 80rem; /* ~ max-w-7xl */
  margin-inline: auto;
  padding-inline: 1rem;
}
@media (min-width: 640px) {
  .wg-container { padding-inline: 1.5rem; }
}

.wg-narrow { max-width: 60rem; } /* max-w-3xl */
.wg-measure { max-width: 42rem; } /* max-w-2xl */

/* .wg-narrow plus the how-we-work timeline's arrow gutter. The gutter is
   additive rather than carved out of the measure, so the step text keeps the
   same 48rem reading width it would have had without the arrows. Below 768px
   there is no gutter (see .timeline), so this collapses back to .wg-narrow. */
.wg-narrow-gutter { max-width: 48rem; }
@media (min-width: 768px) {
  .wg-narrow-gutter { max-width: 55.5rem; } /* 48rem + 7.5rem */
}

.section { padding-block: 4rem; }
@media (min-width: 768px) { .section { padding-block: 5rem; } }
.section-tight { }
/* Cuts just the top padding on an otherwise normal .section — used where the
   section above already ends with its own bottom margin/whitespace, so the
   combined gap doesn't need a full .section top padding on both sides. */
.section-top-tight { padding-top: 1.5rem; }
@media (min-width: 768px) { .section-top-tight { padding-top: 2rem; } }
/* Gold hairline top and bottom separates the white section from whatever
   comes before/after it. .border-y-navy (below) is defined later, so on the
   trust strip — the one section that opts into it — it wins the cascade tie
   and keeps that section's subtler navy border instead of gold. */
.section-white {
  background-color: #fff;
  border-top: 3px solid var(--wg-gold);
  border-bottom: 3px solid var(--wg-gold);
}
/* Modifier: drop the top hairline only, for a section-white that follows
   directly after another white/light section (e.g. About's origin story
   hero into "Meet the team"), where the extra rule just adds visual noise. */
.section-white-no-top-border { border-top: 0; }
/* Modifier: drop the bottom hairline, for a section-white immediately
   followed by another white section — same reasoning as the top variant,
   for the seam below instead of above. Combine both on a section-white
   sandwiched between two other white sections. */
.section-white-no-bottom-border { border-bottom: 0; }
.section-greygreen {
  background-color: #4f585e;
  background-image: url('../images/GreyGreenBackground.jpg');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
/* The grey photo texture back as this section's own background (painted
   at the very back automatically), with a semi-transparent gradient tint
   layered over it (::before, z-index:-2) instead of a flat opaque one —
   #55583d is the hero photo's own sampled bottom-edge color, fading to
   the brand's darkest green, so the texture shows through softly rather
   than being fully covered like .section-greygreen's opaque tiles use it. */
.section-brand-green {
  position: relative;
  z-index: 0;
  background-color: #4f585e;
  background-image: url('../images/GreyGreenBackground.jpg');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.section-brand-green::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background: linear-gradient(180deg, rgba(100, 102, 98, 0.4) 0%, rgba(60, 64, 56, 0.65) 100%);
}
/* Per-industry photo, swapped in behind the base photo when a "Who we
   serve" tile is hovered or focused (see site.js). z-index:-1, placed
   after the base layers in the DOM so it paints on top of them within
   that same negative stacking level. */
.who-serve-photo {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  opacity: 0;
  transition: opacity 400ms ease;
}
.who-serve-photo.is-visible { opacity: 1; }
/* Two stacked <img> layers instead of one, so switching from one tile's
   photo to another's crossfades between them (site.js toggles
   .is-active on whichever layer just got the new src) instead of the
   image hard-cutting from one industry photo straight to the next. */
.who-serve-photo-img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: 0;
  transition: opacity 500ms ease;
}
.who-serve-photo-img.is-active { opacity: 1; }
/* Same top-to-bottom colors as .section-brand-green's own gradient
   (sampled from the hero photo), so an industry photo tints toward the
   same palette as the rest of the section instead of a mismatched navy. */
.who-serve-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(100, 102, 98, 0.55) 0%, rgba(60, 64, 56, 0.75) 100%);
}
/* Same offwhite scrim treatment as .hero-media-scrim, laid over the
   base/hover photo layers (all negative z-index, this paints last so it
   sits on top) to soften the section the same way the hero photo is
   softened, instead of the flat saturated gradient underneath. */
.section-brand-green::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: rgba(230, 231, 226, 0.18);
}
.border-y-navy {
  border-top: 3px solid rgba(3, 40, 65, 0.1);
  border-bottom: 3px solid rgba(3, 40, 65, 0.1);
}

/* ── Eyebrow ──────────────────────────────────────────── */
.eyebrow {
  display: block;
  font-family: var(--wg-font-body);
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--wg-primary-deep);
  margin-bottom: 0.75rem;
}
.eyebrow.eyebrow-tight { margin-bottom: 0.5rem; }
.eyebrow.eyebrow-gold { color: var(--wg-gold); }
.eyebrow.eyebrow-dark { color: var(--wg-darkgreen); }

/* Decorative Font Awesome icon next to a page-intro heading (wg_page_intro's
   optional icon arg): a padlock on Privacy Policy, scales of justice on Terms.
   Purely decorative (the function marks it aria-hidden), so it is just a
   large brand-gold glyph, not an interactive element. */
.page-intro-icon {
  font-size: 5rem;
  color: var(--wg-gold);
  opacity: 0.9;
}

/* ── Buttons (built on Bootstrap .btn) ────────────────── */
.btn-brand {
  background-color: var(--wg-primary-deep);
  color: #fff;
  border: 2px solid var(--wg-primary-deep);
  font-weight: 700;
}
.btn-brand:hover, .btn-brand:focus {
  background-color: var(--wg-darkgreen);
  border-color: var(--wg-darkgreen);
  color: #fff;
}
.btn-outline-navy {
  background-color: transparent;
  color: var(--wg-navy);
  border: 2px solid var(--wg-navy);
  font-weight: 700;
}
.btn-outline-navy:hover, .btn-outline-navy:focus {
  background-color: var(--wg-navy);
  color: var(--wg-offwhite);
}
.btn-on-dark {
  background-color: var(--wg-offwhite);
  color: var(--wg-navy);
  border: 2px solid var(--wg-offwhite);
  font-weight: 700;
}
.btn-on-dark:hover, .btn-on-dark:focus {
  background-color: var(--wg-lightgreen);
  border-color: var(--wg-lightgreen);
  color: var(--wg-darkgreen);
}
.btn-brand, .btn-outline-navy, .btn-on-dark {
  padding: 0.875rem 1.75rem;
  border-radius: 0.375rem;
}
.btn-sm-brand { padding: 0.55rem 1.15rem; font-size: 0.9rem; }

/* ── Cards / tiles ────────────────────────────────────── */
.tile {
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 1px solid rgba(3, 40, 65, 0.1);
  background-color: #fff;
  border-radius: 0.5rem;
  padding: 1.5rem;
  transition: box-shadow 150ms ease, opacity 200ms ease;
  text-decoration: none;
  color: inherit;
}
a.tile:hover { box-shadow: 0 8px 24px rgba(3, 40, 65, 0.1); }
/* Who we serve: dim the other industry tiles on hover/focus so more of
   the per-industry photo underneath (see .who-serve-photo in site.js)
   shows through, and grow the active one so it stands out against them.
   The trigger is the unscaled .who-serve-cell wrapper, not the .tile
   itself: scaling .tile up would grow its own hit box into the next
   cell, so a mouse moving tile-to-tile would clip the edge of the
   still-enlarging neighbor and cause the hover state to stick or
   flicker between the two. Keeping the hover source fixed to the
   original grid cell means the pointer crosses a clean, stable
   boundary no matter how big the tile visually grows.
   Hover-capable pointers only, so touch doesn't get stuck with a faded
   or scaled tile after a tap. */
@media (hover: hover) and (pointer: fine) {
  .who-serve-grid .tile {
    /* position/z-index are set unconditionally (not just on :hover) so
       hovering never toggles them mid-transition: since neither property
       can animate, flipping them only while :hover is active means a
       quick tile-to-tile move could pop the outgoing tile's stacking
       order instantly while its scale/opacity were still easing back,
       a visible snap layered on top of the animation. Fixing them in
       place leaves only transform/opacity to animate, so an interrupted
       transition just reverses smoothly instead of jumping. A short
       120ms is used instead of the fade's 200ms so a fast tile-to-tile
       pass settles before the next hover fires. */
    position: relative;
    z-index: 0;
    transition: box-shadow 150ms ease, opacity 200ms ease, transform 120ms ease-out;
  }
  .who-serve-grid:has(.who-serve-cell:hover) .who-serve-cell:not(:hover) .tile,
  .who-serve-grid:has(.who-serve-cell:focus-within) .who-serve-cell:not(:focus-within) .tile {
    opacity: 0.45;
  }
  .who-serve-cell:hover .tile,
  .who-serve-cell:focus-within .tile {
    z-index: 1;
    transform: scale(1.05);
  }
}
.tile-navy { background-color: var(--wg-navy); border-color: var(--wg-navy); }
.tile-soft { background-color: rgba(230, 231, 226, 0.5); }
.tile-lightgreen { background-color: rgba(151, 186, 102, 0.25); }
.tile-offwhite { background-color: var(--wg-offwhite); border-color: var(--wg-offwhite); }
.tile-arrow { margin-top: 1rem; font-size: 0.875rem; font-weight: 700; color: var(--wg-primary-deep); }
a.tile:hover .tile-heading { color: var(--wg-primary-deep); }

.check-item { display: flex; gap: 0.75rem; color: rgba(3, 40, 65, 0.85); }
.check-item svg { margin-top: 0.35rem; flex-shrink: 0; color: var(--wg-primary-deep); }

.border-left-green { border-left: 4px solid var(--wg-lightgreen); padding-left: 1.25rem; }
.border-left-gold  { border-left: 4px solid var(--wg-gold); padding-left: 1.5rem; }

/* ── Icon-badge list (Managed IT "What managed IT includes",
   industry pages "What we do about it") ──────────────────── */
/* A spine connecting every icon top-to-bottom reads as one continuous,
   strung-together checklist rather than a stack of identical feature
   cards, without needing a number on each row to say so. */
.included-list { position: relative; }
.included-item {
  position: relative;
  display: flex;
  gap: 1.25rem;
  align-items: flex-start;
  padding: 1.75rem 0;
}
.included-item + .included-item { border-top: 1px solid rgba(3, 40, 65, 0.1); }
.included-icon {
  position: relative;
  z-index: 1;
  flex: none;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--wg-primary-deep);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  transition: background-color 0.2s ease;
}
.included-item:hover .included-icon { background: var(--wg-gold); color: var(--wg-darkgreen); }
.included-body { min-width: 0; }
/* Spine: runs through every icon's own center, top icon to bottom icon,
   so the row of circles reads as one strung-together checklist. */
.included-list::before {
  content: "";
  position: absolute;
  top: 1.75rem;
  bottom: 1.75rem;
  left: 1.5rem;
  width: 2px;
  background: var(--wg-gold);
  opacity: 0.3;
}

/* ── "Who this is for / not for" panels (Managed IT page) ──── */
.fit-panel { height: 100%; border-radius: 0.75rem; padding: 1.75rem; }
.fit-panel-yes { background: rgba(151, 186, 102, 0.2); }
.fit-panel-no  { background: rgba(230, 231, 226, 0.6); }
.fit-icon {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  margin-top: 0.15rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.fit-icon-yes { color: var(--wg-primary-deep); }
.fit-icon-yes svg { width: 100%; height: 100%; }
.fit-icon-no { color: rgba(3, 40, 65, 0.45); font-size: 0.9rem; }

/* ── Hand-drawn circle around a word or phrase ────────── */
/* Two users with different triggers: the pricing tier names draw on card
   hover, the How We Work guarantee line draws once on scroll reveal. Geometry
   and stroke are shared; the trigger rules are kept separate so the two cannot
   fight over stroke-dashoffset. */
.tier-name,
.wg-circled {
  position: relative;
  display: inline-block;
}
.tier-name {
  /* .tile is a column flexbox, so every direct child defaults to
     align-items:stretch and fills its full width no matter what its own
     display is set to; align-self overrides that so this shrinks to its
     own text instead of stretching the circle across the whole card. */
  align-self: flex-start;
  margin-top: -0.6875rem;
  margin-bottom: calc(1.125rem - 0.6875rem);
  margin-left: -1.125rem;
  padding: 0.6875rem 1.125rem;
}
.wg-circled {
  /* Sits inline inside a sentence, so it needs far less padding than the
     tier-name block and must not add height to the line box. */
  padding: 0.15rem 0.7rem;
}
.tier-name-label,
.wg-circled-label { position: relative; z-index: 1; }
.tier-name-circle,
.wg-circled-svg {
  /* The padding above already reserves breathing room around the text;
     this is just a small extra allowance for the stroke itself. */
  position: absolute;
  top: -3px;
  left: -3px;
  width: calc(100% + 6px);
  height: calc(100% + 6px);
  overflow: visible;
  pointer-events: none;
}
.tier-name-circle path,
.wg-circled-svg path {
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 101;
}

/* Pricing: hover-driven, un-draws on leave */
.tier-name-circle path {
  stroke: var(--wg-primary);
  stroke-dashoffset: -101;
  transition: stroke-dashoffset 260ms ease-in;
}
.tile:hover .tier-name-circle path {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 420ms ease-out;
}

/* Guarantee line: gold, drawn once when the section scrolls into view.
   Default is fully drawn, so it still reads with JS off or reduced motion
   (site.js only adds .reveal-ready when it is going to animate). */
.wg-circled-svg path {
  stroke: var(--wg-gold);
  stroke-dashoffset: 0;
}
.reveal-ready .wg-circled-svg path { stroke-dashoffset: -101; }
.reveal-ready [data-reveal].is-revealed .wg-circled-svg path {
  animation: wg-arrow-draw 620ms ease-out 380ms forwards;
}

.badge-pill-solid { background: var(--wg-primary-deep); color: #fff; border-color: var(--wg-primary-deep); }

.pricing-tier-elevated { margin-top: 0; }
/* padding-top used to be a 19% inline style on .pricing-tiers-wrap at every
   width — that space exists only to give the desktop arrow SVG (drawn from
   the headline down to the cards) somewhere to paint. Mobile hides that
   SVG's job entirely (see .pricing-tier-elevated below), so it doesn't
   need the reserved space either; keeping it just pushed the now-first
   MSA card down for no reason. */
.pricing-tiers-wrap { padding-top: 4%; }
@media (min-width: 768px) {
  .pricing-tiers-wrap { padding-top: 19%; }
  /* Bootstrap's .row is flexbox, not grid: percentage margins resolve against
     the row's full width, not this column's own track, so this is ~1/3 of the
     mockup's original 29% (which assumed a CSS Grid column-width basis). */
  .pricing-tier-elevated { margin-top: 9%; }
}
@media (max-width: 767.98px) {
  /* The connecting arrows are hand-drawn SVG paths at fixed pixel
     coordinates assuming card 1 = Break/Fix, card 2 = MSA (featured,
     middle), card 3 = Pre-Paid — they don't hold up once the cards stack
     single-column on mobile, so the mobile variant doesn't render
     usefully. Rather than redraw it, put the featured MSA card first in
     source order here (only here — .row is flex, so this doesn't touch
     desktop's left-to-right order the arrows are still drawn for). */
  .pricing-tier-elevated { order: -1; }
  /* Requested independently of the arrow issue above: Pre-Paid before
     Break/Fix on mobile. MSA (the middle child) is untouched by these
     first/last selectors, so this only swaps the other two. */
  .pricing-tiers-wrap .row > .col:first-child { order: 1; }
  .pricing-tiers-wrap .row > .col:last-child { order: 0; }
}

/* Arrows draw from the path's start point (up by the headline) down toward the
   tier card, so the stroke travels the way the arrow points. A positive
   dashoffset holds the dash off the front of the path; animating it to 0 walks
   the visible run forward from t=0. (A negative offset reverses that and draws
   tail-first, from the arrowhead back up.) */
@keyframes wg-arrow-draw { to { stroke-dashoffset: 0; } }
.pricing-arrows path,
.pricing-arrow-mobile path {
  stroke-dasharray: 101;
  stroke-dashoffset: 101;
  animation: wg-arrow-draw 900ms ease-out 1000ms forwards;
}
/* The two head strokes start at the tip, so they hold until the shaft lands. */
.pricing-arrows .wg-arrowhead,
.pricing-arrow-mobile .wg-arrowhead {
  animation-duration: 300ms;
  animation-delay: 1800ms;
}

/* ── Hero + contour ───────────────────────────────────── */
.hero { position: relative; overflow: hidden; background-color: var(--wg-offwhite); }
.hero .wg-container { position: relative; }
.contour {
  pointer-events: none;
  position: absolute;
  inset: 0;
  height: 100%;
  width: 100%;
}

/* Photo hero (home). The headline stays navy on the page's off-white, so the
   photo sits under a scrim that is near-opaque behind the text and clears
   toward the right, where the valley view is. */
.hero-media { min-height: clamp(22rem, 38vw, 32rem); display: flex; align-items: center; }
.hero-media-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 55%;
}
.hero-media-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    rgba(230, 231, 226, 0.86) 0%,
    rgba(230, 231, 226, 0.78) 34%,
    rgba(230, 231, 226, 0.5) 62%,
    rgba(230, 231, 226, 0.18) 100%
  );
}
/* Narrow screens: the text spans the full width, so the scrim has to as well */
@media (max-width: 767.98px) {
  .hero-media-scrim {
    background: linear-gradient(
      180deg,
      rgba(230, 231, 226, 0.95) 0%,
      rgba(230, 231, 226, 0.88) 60%,
      rgba(230, 231, 226, 0.6) 100%
    );
  }
}

/* Home hero mascot: the frog-in-circle mark tucked into the bottom-right
   corner of the photo, clear of the headline/buttons column. d-none d-lg-block
   on the <img> hides it on phones AND tablets (at md width, the headline
   still spans nearly the full container and collides with it); this just
   handles placement once it's shown. */
.hero-mascot {
  position: absolute;
  right: 1.5rem;
  bottom: 1.5rem;
  height: auto;
  z-index: 1;
  pointer-events: none;
}
@media (min-width: 640px) {
  .hero-mascot { right: 8rem; bottom: 4rem; }
}

/* Photo hero for interior pages (breadcrumb + page intro). Same scrim idea as
   the home hero, but the block sizes to its content instead of a min-height,
   and the scrim closes back to solid off-white at the bottom so the photo
   hands off cleanly to the section below. */
/* The photo carries on past the intro text and behind the gold arrows, ending
   just below the arrowheads. The overhang is added as padding here and taken
   back off the next section, so only the photo box grows — nothing below it
   moves. It tracks the arrows because both scale with the container: the middle
   arrowhead sits 292/1200 (~24%) of the container's width below the arrow
   origin, and the clamp caps out once .wg-container hits its 80rem max. Below
   768px the desktop arrows are hidden, so there is nothing to reach and the
   overhang drops to zero.

   --hero-page-gap is the breathing room between the intro copy and where the
   arrows start. It is tight on desktop so the arrows read as coming off the
   headline; with the arrows hidden below 768px it opens back up to a normal
   section gap. */
:root { --hero-page-overhang: 0rem; --hero-page-gap: 2.5rem; }
@media (min-width: 768px) {
  :root { --hero-page-overhang: clamp(11rem, 24vw, 15rem); --hero-page-gap: 0.5rem; }
}
.hero-page {
  /* The colour the hero resolves to, as an "r, g, b" triplet so the scrim can
     build rgba() from it. The negative margin on .hero-page + * pulls every
     later section up too, so whatever follows paints over the hero's bottom
     edge — this has to match that section's background or the overlap shows as
     a hard line. Defaults to the body offwhite; pages whose next band is white
     add .hero-page-white. */
  --hero-page-bg: 230, 231, 226;
  position: relative;
  overflow: hidden;
  background-color: rgb(var(--hero-page-bg));
  padding-bottom: calc(var(--hero-page-gap) + var(--hero-page-overhang));
}
.hero-page-white { --hero-page-bg: 255, 255, 255; }
/* Compact hero: no arrow overhang, just a normal section gap below the intro.
   The matching ".hero-page-compact + * { margin-top: 0; }" override lives
   further down, after the general ".hero-page + *" rule it needs to beat in
   the cascade (equal specificity, later source order wins) — see the note
   there for why. */
.hero-page-compact { --hero-page-overhang: 0rem; --hero-page-gap: 2rem; }
/* Industry pages: the photo/scrim now sits behind the whole hero — breadcrumb,
   headline, and the "operational reality" body copy — as one section, instead
   of bleeding into a separate section below via the overhang/negative-margin
   trick the other hero variants use. Body length varies per industry, so
   there's nothing to bleed into predictably; the image's own mask (below)
   fades it out to flat background well before the text runs out. No overhang,
   no extra gap: the section's height comes from its own content. */
.hero-page-industry {
  --hero-page-overhang: 0rem;
  --hero-page-gap: 0rem;
  /* .hero-page relies on overflow:hidden + its absolutely positioned img/scrim
     resolving inset:0 against a definite height. With no explicit height and
     body-copy length varying per industry, that definite-height requirement
     was previously satisfied by a min-height alone; without it, some browsers
     fall back to a much shorter height for that positioning calculation, and
     overflow:hidden then clips the real (taller) in-flow text at that shorter
     height — cutting paragraphs off mid-sentence. Since the mask already fades
     the photo out well before the text runs out, nothing needs clipping here,
     so overflow stays visible and the section is always exactly as tall as
     its own content, however long that industry's copy is. */
  overflow: visible;
  min-height: clamp(20rem, 32vw, 26rem);
}
.hero-page > .wg-container { position: relative; }
/* The hero's photo and scrim are position:absolute with the default z-index:
   auto, so per the CSS painting order they paint in the positioned-descendant
   bucket, which comes after normal in-flow content regardless of DOM order.
   Without an explicit stacking context here, the negative margin above would
   pull this section's own text up underneath the hero image/scrim and the
   photo would paint over it. position:relative + z-index:1 puts this section
   in its own stacking context above the hero's, so the overlap only ever
   shows the photo fading behind the text, never the text getting covered.

   This only targets the arrow-overhang hero variants (home/interior pages
   that use plain .hero-page or .hero-page-compact). The industry hero does
   NOT use this sibling-based bleed trick at all — see .hero-page-industry-next
   below, which is applied directly via its own class instead of relying on
   a generic "+ *" selector picking up --hero-page-overhang from :root. That
   combination of an inherited custom property plus a same-specificity sibling
   selector was fragile (source order decided which rule won) and had already
   caused the industry hero's next section to get pulled up 11–15rem and bury
   the tail of the body copy underneath it. */
.hero-page + * { position: relative; z-index: 1; margin-top: calc(-1 * var(--hero-page-overhang)); }
.hero-page-compact + * { margin-top: 0; }
/* Section that follows the industry hero. Applied as an explicit class on
   that section in the template (not a "+ *" sibling selector) so it can
   never be affected by --hero-page-overhang or by cascade/source-order ties
   with the rules above — it simply always has zero extra top margin. */
.hero-page-industry-next { margin-top: 0; }
.hero-page-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 58%;
  /* Dissolve the photo into the section's own background before the bottom
     edge, instead of leaving the scrim to bury it in the last few percent.
     Without this the image is still faintly visible where the next section
     starts painting over the hero, and gets clipped mid-frame. Finishing at
     92% leaves a clean strip of --hero-page-bg for that overlap to land on. */
  -webkit-mask-image: linear-gradient(180deg, #000 45%, rgba(0, 0, 0, 0.45) 74%, transparent 92%);
  mask-image: linear-gradient(180deg, #000 45%, rgba(0, 0, 0, 0.45) 74%, transparent 92%);
}
/* Industry pages: a fixed-length mask (e.g. "transparent at 24rem") was tried
   here, but the section's actual height is set by its own content — the img
   is absolutely positioned with inset:0 and stretches to whatever height the
   in-flow breadcrumb/headline/body copy give the section, which for a
   four-paragraph industry runs well past 24rem. A mask measured in a fixed
   length finishes dissolving to background at that same absolute depth on
   every page regardless of how tall the section actually is, so on longer
   pages the photo was fading out around the section's vertical midpoint and
   leaving a large flat, image-less gap below it. Using percentages instead
   ties the fade to the section's own resolved height (the same box the img
   is stretched to fill), so it always finishes dissolving into flat
   background right near the bottom of that page's hero, however tall the
   copy makes it — matching the plain .hero-page-img mask below, just tuned
   to fade a little earlier since the industry hero has no arrow overhang to
   land the last bit of photo behind. */
.hero-page-industry .hero-page-img {
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 35%, rgba(0, 0, 0, 0.45) 60%, transparent 85%);
  mask-image: linear-gradient(180deg, #000 0%, #000 35%, rgba(0, 0, 0, 0.45) 60%, transparent 85%);
}
/* Only the horizontal wash lives here now: it keeps the navy breadcrumb and
   headline legible over the left of the photo. The vertical fade that used to
   sit on top of it was doing the bottom blend-out, which the image's own mask
   now handles — running both just washed out the middle of the photo twice. */
.hero-page-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    rgba(var(--hero-page-bg), 0.9) 0%,
    rgba(var(--hero-page-bg), 0.82) 40%,
    rgba(var(--hero-page-bg), 0.55) 70%,
    rgba(var(--hero-page-bg), 0.28) 100%
  );
}
/* Narrow screens: the text spans the full width, so the scrim has to as well */
@media (max-width: 767.98px) {
  .hero-page-scrim {
    background: linear-gradient(
      180deg,
      rgba(var(--hero-page-bg), 0.95) 0%,
      rgba(var(--hero-page-bg), 0.9) 55%,
      rgba(var(--hero-page-bg), 0.98) 100%
    );
  }
}

/* ── Trust strip ──────────────────────────────────────── */
/* Navy band instead of the plain white strip: a subtle top hairline and
   grey bottom border (not the site's usual gold hairline) set it apart as
   its own accent band, and the text/dot colors switch to light variants
   so they stay readable against navy instead of the near-invisible
   dark-on-dark of the default .trust-strip styling. */
.trust-strip-band {
  background-color: var(--wg-primary-deep);
  border-top: 2px solid var(--wg-primary);
}
.trust-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.75rem 2.5rem;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--wg-offwhite);
  padding-block: 0.2rem;
}
.trust-strip .dot { display: inline-block; height: 0.5rem; width: 0.5rem; border-radius: 999px; }
.trust-strip .dot-gold { background-color: var(--wg-gold); }
.trust-strip .dot-green { background-color: var(--wg-lightgreen); }

/* ── CTA band ─────────────────────────────────────────── */
/* Flat mid-grey: separates from both the light page above and the navy footer
   below. Kept on the dark side of "medium" because the headline, body copy, and
   phone link on this band are all off-white — this is about as light as the
   grey can go while that text still meets contrast (5.7:1 here). */
/* Case-study vertical tab: folder-tab popout anchored to the CTA band below */
.cs-vertical-tab-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: 0;
  padding-bottom: 0;
  position: relative;
  z-index: 1;
}
.cs-vertical-tab {
  display: inline-block;
  background: #000;
  color: #4f585e;
  font-weight: 600;
  font-size: 0.875rem;
  padding: 0.6rem 1.75rem;
  border-radius: 1.5rem 1.5rem 0 0;
  text-decoration: none;
  transition: background-color 0.2s ease;
  position: relative;
  top: 1px;           /* overlap the CTA band border so the tab feels connected */
}
.cs-vertical-tab:hover,
.cs-vertical-tab:focus {
  background: #222;
  color: #fff;
  text-decoration: none;
}

.cta-band {
  background-color: #4f585e;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.cta-band .cta-panel { background-color: var(--wg-offwhite); border-radius: 0.5rem; padding: 1.5rem; }
@media (min-width: 640px) { .cta-band .cta-panel { padding: 2rem; } }
.cta-link {
  font-weight: 700;
  color: var(--wg-offwhite);
  text-decoration: underline;
  text-decoration-color: var(--wg-lightgreen);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.cta-link:hover { color: var(--wg-lightgreen); }

.text-underline-green {
  font-weight: 700;
  color: var(--wg-primary-deep);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.text-underline-green:hover { color: var(--wg-darkgreen); }

/* ── Badge pill ───────────────────────────────────────── */
.badge-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  border-radius: 0.375rem;
  border: 1px solid rgba(216, 172, 47, 0.6);
  padding: 0.375rem 0.75rem;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.badge-pill-gold { color: var(--wg-gold); }
.badge-pill-dark { color: var(--wg-darkgreen); background: #fff; }

/* ── Prose ────────────────────────────────────────────── */
.prose-site { max-width: 65ch; }
.prose-site p + p { margin-top: 1rem; }
.prose-site.prose-legal h2 { margin-top: 2rem; font-size: 1.5rem; }
.prose-site.prose-legal ul { margin-top: 0.75rem; padding-left: 1.5rem; list-style: disc; }
.prose-site.prose-legal li { margin-top: 0.375rem; }
/* Industry pages: match the width of the hero's own headline/subhead column
   (.wg-narrow, 60rem) instead of .prose-site's default 65ch reading measure,
   so the body copy's right edge lines up with the intro text above it rather
   than stopping well short of it. Case study pages already override this via
   .case-study-body (max-width: none), so this only affects industry.php. */
.prose-body { max-width: 60rem; }
.prose-body h2 { margin-top: 2.5rem; font-size: 1.5rem; }
.prose-body ul { margin-top: 1rem; padding-left: 1.5rem; list-style: disc; }
.prose-body li { margin-top: 0.5rem; }
.prose-body p + p { margin-top: 1rem; }

/* ── Homepage "About WebGuy IT" watermark heading ─────── */
/* The tagline (WG_SITE_TAGLINE) used to sit as a normal bold <h2> above the
   copy. It's now a large, faded decorative watermark sitting behind the
   paragraph text instead of acting as a visible title — the <h2> stays in
   the DOM for SEO/structure (aria-hidden, with a visually-hidden duplicate
   for screen readers) but is absolutely positioned, oversized, and
   low-opacity so it reads as background texture, not a heading. */
.about-watermark-wrap {
  position: relative;
  overflow: hidden;
  padding-top: 2rem;
  padding-bottom: 2.5rem;
}
@media (min-width: 768px) {
  .about-watermark-wrap { padding-top: 2.5rem; padding-bottom: 3rem; }
}
.about-watermark {
  position: absolute;
  bottom: 1.5rem;
  right: 0;
  left: auto;
  max-width: 90%;
  margin: 0;
  text-align: right;
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 4vw, 2.75rem);
  line-height: 1;
  color: var(--wg-lightgreen);
  opacity: 0.45;
  white-space: nowrap;
  text-overflow: ellipsis;
  pointer-events: none;
  z-index: 0;
}
/* Gold reads better than the default lightgreen as background texture on
   .section-brand-green, since green-on-green loses most of its shape. */
.about-watermark-gold {
  color: var(--wg-gold);
  opacity: 0.3;
}
.about-watermark-wrap > .fs-5 {
  position: relative;
  z-index: 1;
}
@media (max-width: 575.98px) {
  /* Absolute + bottom:1.5rem assumes the watermark is short enough to
     tuck below the paragraph with room to spare. At this width it wraps
     and grows taller than that reserved space, so its top edge climbs
     up into the "Read our full story" link above it. Static flow avoids
     the problem outright: it becomes a normal block in the panel instead
     of an overlay, so it can never overlap content regardless of how
     tall it renders. It's first in the DOM (screen readers get the
     visually-hidden duplicate right away, ahead of the body copy it
     decorates), so the wrap is switched to a flex column here and the
     watermark given a high `order` to move it to the visual end without
     touching the DOM order. */
  .about-watermark-wrap { display: flex; flex-direction: column; }
  .about-watermark {
    position: static;
    display: block;
    order: 3;
    margin-top: 1.25rem;
    text-align: left;
    white-space: normal;
    font-size: clamp(1.25rem, 6vw, 1.875rem);
    max-width: 100%;
  }
}

/* ── Case studies index page ─────────────────────────────── */
/* Extra breathing room below the teaser grid, on top of the row's own
   Bootstrap gutter (g-4 sets --bs-gutter-y). */
.case-studies-grid { margin-bottom: calc(2 * var(--bs-gutter-y)); }

/* ── Case study page ──────────────────────────────────── */
/* The body fills the reading column (wider than the slider) rather than
   stopping at the default 65ch prose measure */
.prose-site.case-study-body { max-width: none; }
.case-study-head { display: flex; align-items: flex-start; gap: 2rem; }
.case-study-head-main { flex: 1 1 auto; min-width: 0; }
.case-study-logo {
  flex: none;
  width: 9rem;
  max-width: 100%;
  height: auto;
  padding: 0.5rem;
  border: 1px solid rgba(3, 40, 65, 0.1);
  border-radius: 0.75rem;
  background: #fff;
}
/* Mobile: the logo moves above the title and is capped by HEIGHT, not width, so
   a square mark (960x960) and a wide one (414x250) come out the same visual size
   instead of the wide one ballooning to fill its width. */
@media (max-width: 767.98px) {
  .case-study-head { flex-direction: column-reverse; gap: 1rem; }
  .case-study-logo {
    width: auto;
    height: 3.5rem;
    max-width: 60%;
    padding: 0.375rem;
    border-radius: 0.5rem;
  }
  .case-study-stats { padding: 0 1.25rem 1.25rem; }
  .case-study-stats-stacked { gap: 1.25rem; padding: 1.25rem; }
}
/* Stats box. Grid fallback (no photos): no padding-top, since the row's own g-4
   gutter margin supplies it and the box ends up inset evenly on all four sides. */
.case-study-stats {
  margin: 0;
  padding: 0 1.5rem 1.5rem;
  border: 1px solid rgba(3, 40, 65, 0.1);
  border-radius: 0.75rem;
  background: #fff;
}
/* Beside the slider: one stat per line, filling the slider's height */
.case-study-stats-stacked {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1.75rem;
  height: 100%;
  padding: 1.5rem;
}
.case-study-stats-header {
  font-family: var(--wg-font-display);
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--wg-navy);
  margin: 0 0 0.5rem 0;
  padding-bottom: 0.75rem;
  border-bottom: 2px solid var(--wg-lightgreen);
  text-align: center;
}
/* Case study section headings carry the same marker swipe as the nav panel.
   fit-content keeps the highlight on the words instead of the whole column. */
.case-study-body h2 {
  width: fit-content;
  max-width: 100%;
  padding-inline: 0.15em;
  background: var(--wg-marker);
}

/* ── Placeholder note (visible TBD markers) ───────────── */
.tbd-note {
  border: 2px dashed rgba(3, 40, 65, 0.2);
  background: rgba(255, 255, 255, 0.6);
  border-radius: 0.375rem;
  padding: 1rem;
  font-size: 0.875rem;
  font-weight: 700;
  color: rgba(3, 40, 65, 0.6);
}

/* ── Timeline (how-we-work) ───────────────────────────── */
/* The step indent is a variable because the closing note below the list has to
   line up with the step text. Widened at 768px to open the arrow lane (below). */
:root { --wg-timeline-gutter: 2rem; }
@media (min-width: 768px) {
  :root { --wg-timeline-gutter: 7.5rem; }
}

.timeline {
  position: relative;
  border-left: 2px solid var(--wg-lightgreen);
  padding-left: var(--wg-timeline-gutter);
  list-style: none;
  margin: 0;
}
/* Closing note under the list: indented to the step text so it reads as part of
   the same block rather than a new section. */
.timeline-note { margin-left: var(--wg-timeline-gutter); }
.timeline > li { position: relative; }
.timeline > li + li { margin-top: 2.5rem; }
.timeline .step-num {
  position: absolute;
  left: -45px;
  display: flex;
  height: 2rem;
  width: 2rem;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background-color: var(--wg-primary-deep);
  font-family: var(--wg-font-display);
  font-size: 0.875rem;
  font-weight: 700;
  color: #fff;
}

/* The gold arrows take over the job of connecting the steps once there is a
   margin to draw them in (--wg-timeline-gutter widens above), so the green rule
   stops carrying it. Setting the colour to transparent rather than dropping the
   border keeps the 2px border box, so content does not shift sideways across the
   breakpoint. Narrow screens have no margin to draw in, so they keep the rule. */
@media (min-width: 768px) {
  .timeline { border-left-color: transparent; }
}

/* ── Process arrows (how-we-work timeline) ─────────────── */
/* One small fixed-viewBox SVG per step, absolutely positioned inside its own
   <li>: step heights vary with copy length, so a single SVG spanning the whole
   list could never land its arrowheads on the circles.
   Horizontally: .timeline content starts 7.5rem (120px) past its border box and
   .step-num sits at left:-45px, so the circles occupy content-relative -45..-13
   (box-relative 77..109). left:-7rem puts this box at content-relative -112..-46
   (box-relative 10..76) — entirely in the left margin, clear of the numbers and
   still inside the container.
   Vertically: the arrow lives in the step it points INTO and reaches back up
   over the 2.5rem inter-step gap. Its own circle sits ~21px below the <li> top
   (it follows the phase eyebrow), and the arrowhead is at 92% of a 100px box, so
   top:-70px lands the tip right on that circle.
   These offsets are tuned against rendered step heights — re-check them if the
   eyebrow, the gap, .step-num's size, or the padding above changes. */
.process-arrow {
  position: absolute;
  left: -7rem;
  top: -70px;
  width: 66px;
  height: 100px;
  pointer-events: none;
}

/* Steps reveal one at a time on scroll: the incoming arrow draws, then that
   step's content fades in behind it. The <li> opts out of the global
   [data-reveal] fade so the arrow is not faded along with the text — an arrow
   should draw, not appear. Everything here is gated on .reveal-ready, which
   site.js adds only when it is going to animate (not under reduced motion, not
   without IntersectionObserver), so both of those cases fall through to plain
   visible content and fully drawn arrows. */
.reveal-ready .timeline > li[data-reveal] { opacity: 1; transform: none; }

/* Positive offset, unlike the pricing arrows' negative one: with dashoffset
   +101 the dash is hidden past the end of the path and the visible run grows
   from the path's START, so the line travels tail-to-head and arrives at the
   arrowhead. A negative offset reveals from the end backwards, which reads as
   the head appearing first and the tail chasing it. */
.reveal-ready .timeline > li[data-reveal] .process-arrow path {
  stroke-dasharray: 101;
  stroke-dashoffset: 101;
}
.reveal-ready .timeline > li[data-reveal].is-revealed .process-arrow path {
  animation: wg-arrow-draw 420ms ease-out forwards;
}
/* The two barbs are separate paths starting at the tip. Holding them until the
   line has nearly arrived means the head gets drawn last, instead of sitting at
   the destination waiting for the line to reach it. */
.reveal-ready .timeline > li[data-reveal].is-revealed .process-arrow path + path {
  animation-duration: 150ms;
  animation-delay: 400ms;
}

.reveal-ready .timeline > li[data-reveal] .step-body {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 460ms ease, transform 460ms ease;
}
.reveal-ready .timeline > li[data-reveal].is-revealed .step-body {
  opacity: 1;
  transform: none;
  transition-delay: 580ms; /* hold until the arrow's head has finished drawing */
}
/* First step has no incoming arrow, so there is nothing to wait for. */
.reveal-ready .timeline > li[data-reveal]:first-child.is-revealed .step-body {
  transition-delay: 0ms;
}

/* ── Step watermark icons (how-we-work) ───────────────── */
/* Large faded icons positioned at the top-right of each step, in line with the
   title. Uses the same icons from the "at a glance" section above.
   Hidden on mobile to avoid crowding the narrower layout. */
.step-body { position: relative; }
.step-watermark {
  position: absolute;
  right: 0;
  top: 0;
  font-size: 7rem;
  color: var(--wg-gold);
  opacity: 0.2;
  pointer-events: none;
  z-index: 0;
  line-height: 1;
}
/* Ensure step text stays above the watermark */
.step-body > *:not(.step-watermark) { position: relative; z-index: 1; }

/* ── Guarantee tile (how-we-work) ─────────────────────── */
/* Icon on the left, content fills the remaining width */
.guarantee-tile {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 1.5rem;
}
.guarantee-icon {
  flex: none;
  font-size: 4rem;
  color: var(--wg-gold);
  line-height: 1;
}
.guarantee-content {
  flex: 1 1 auto;
  min-width: 0;
}
/* Mobile: stack icon above content */
@media (max-width: 575.98px) {
  .guarantee-tile { flex-direction: column; gap: 1rem; }
  .guarantee-icon { font-size: 3rem; }
}

/* ── Team cards (About) ───────────────────────────────── */
/* Headshots arrive at assorted sizes, so the photo is cropped to one fixed
   ratio and every card lines up regardless of the source file. */
.team-photo {
  width: 100%;
  /* height:auto is load-bearing. The <img> carries width/height attributes for
     layout stability, and that height is a presentational hint the browser
     treats as a definite value — which makes aspect-ratio a no-op and renders
     each photo at its full natural height. Releasing height lets the ratio win. */
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  object-position: 50% 20%; /* faces sit high in these portraits */
  border-radius: 0.375rem;
  border: 2px solid var(--wg-gold);
  background-color: var(--wg-offwhite);
}
/* Fallback for a member with no headshot yet: same footprint, brand initials. */
.team-photo-initials {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--wg-font-display);
  font-size: 2.5rem;
  font-weight: 700;
  color: #fff;
}

/* ── Lead form ────────────────────────────────────────── */
.lead-form .form-label { margin-bottom: 0.375rem; font-size: 0.875rem; font-weight: 700; color: var(--wg-navy); }
.lead-form .form-control,
.lead-form .form-select {
  border: 1px solid rgba(3, 40, 65, 0.25);
  border-radius: 0.375rem;
}
.lead-form .form-control:focus,
.lead-form .form-select:focus {
  border-color: var(--wg-primary-deep);
  box-shadow: 0 0 0 0.2rem rgba(50, 98, 14, 0.15);
}
.form-error {
  border-radius: 0.375rem;
  background: #fef2f2;
  padding: 0.75rem;
  font-size: 0.875rem;
  font-weight: 700;
  color: #991b1b;
}
.form-success {
  border-radius: 0.375rem;
  border: 1px solid rgba(38, 77, 10, 0.3);
  background: rgba(151, 186, 102, 0.2);
  padding: 1rem;
}

/* ── Booking embed ────────────────────────────────────── */
.booking-embed { scroll-margin-top: 6rem; }
.booking-live {
  position: relative;
  min-height: 560px;
  overflow: hidden;
  border-radius: 0.5rem;
  border: 1px solid rgba(3, 40, 65, 0.1);
  background: #fff;
}
.booking-live iframe { position: absolute; inset: 0; height: 100%; width: 100%; border: 0; }
.booking-placeholder {
  display: flex;
  min-height: 280px;
  align-items: center;
  justify-content: center;
  border-radius: 0.5rem;
  border: 2px dashed rgba(3, 40, 65, 0.2);
  background: rgba(255, 255, 255, 0.6);
  padding: 2rem;
  text-align: center;
}
.map-box-photo {
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(3, 40, 65, 0.15);
  background-size: cover;
  background-position: center;
}
.map-box-photo::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.85));
}
.map-box-photo > div {
  position: relative;
  z-index: 1;
}

/* ── Pill links (404) ─────────────────────────────────── */
.pill-link {
  border-radius: 999px;
  border: 1px solid rgba(3, 40, 65, 0.2);
  background: #fff;
  padding: 0.5rem 1rem;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--wg-navy);
  text-decoration: none;
}
.pill-link:hover { border-color: var(--wg-primary-deep); color: var(--wg-primary-deep); }

/* wg_it_guy() used to be its own white .tile card, but stacked next to the
   other single-panel components around it (a case-study card, a scope
   tile, wg_next_steps's tile) that reads as a wall of near-identical white
   boxes rather than distinct sections. It's a plain section now, like the
   FAQ intro below, so .section-tight needs the same manual padding. */
.it-guy { padding-top: 1.5rem; padding-bottom: 1.5rem; }
@media (min-width: 768px) {
  .it-guy { padding-top: 2.5rem; padding-bottom: 2.5rem; }
}

/* ── FAQ (Bootstrap accordion restyle) ────────────────── */
/* wg_faq() renders its section with .section-tight, which carries no vertical
   padding of its own (see .section-tight above) — callers are expected to add
   spacing utilities, but several FAQ call sites didn't, leaving the accordion
   flush against whatever section follows it. Padding here fixes every FAQ
   section sitewide from one place instead of patching each call site.
   Top padding is small and fixed (not responsive) on purpose: most call
   sites are preceded by a section with its own generous bottom padding
   (e.g. managed-it's scope-boundary tile, a full .section), so a small top
   padding here is enough to avoid ever looking flush without compounding
   into a too-large gap. It only needs to fully carry the gap on its own
   when the preceding section ends on a hairline border with little
   padding of its own (industry pages with no case study, e.g. Non-profit,
   Dining) — 1.5rem still reads as an intentional gap there. */
.faq { padding-top: 1.5rem; padding-bottom: 2.5rem; }
@media (min-width: 768px) {
  .faq { padding-bottom: 3.5rem; }
}
/* wg_next_steps() has the same .section-tight (no padding) problem as .faq
   above: nothing stops its tile from sitting flush against whatever
   section follows it (a cta-band, most of the time). */
.next-steps { padding-bottom: 2.5rem; }
@media (min-width: 768px) {
  .next-steps { padding-bottom: 3.5rem; }
}
.faq .accordion-item { background: transparent; border: 0; border-top: 1px solid rgba(3, 40, 65, 0.1); }
.faq .accordion-item:last-child { border-bottom: 1px solid rgba(3, 40, 65, 0.1); }
.faq .accordion-button {
  background: transparent;
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: 1.125rem;
  color: var(--wg-navy);
  padding: 1rem 0;
}
.faq .accordion-button:not(.collapsed) { color: var(--wg-navy); box-shadow: none; }
.faq .accordion-button:focus { box-shadow: none; }
/* Overrides .prose-site's 65ch cap: now that .faq spans the full
   container (see wg_faq()), a capped answer stopped well short of the
   question row's own right edge, reading as unfinished. */
.faq .accordion-body { padding: 0 0 1rem; max-width: none; color: rgba(3, 40, 65, 0.85); }

/* ── Breadcrumbs ──────────────────────────────────────── */
.wg-breadcrumb { font-size: 0.875rem; color: rgba(3, 40, 65, 0.6); }
.wg-breadcrumb a { font-weight: 700; color: rgba(3, 40, 65, 0.6); text-decoration: none; }
.wg-breadcrumb a:hover { color: var(--wg-navy); }

/* ── Site header ──────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 1030;
  border-bottom: 1px solid rgba(3, 40, 65, 0.1);
  /* Kept slightly translucent with the blur below, so content scrolling under
     the sticky bar still shows through faintly instead of hard-cutting. */
  background-color: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(8px);
  transition: padding 200ms ease;
}
/* NOTE: the <nav> must not carry Bootstrap's py-0 utility (padding !important) */
.site-header .navbar { padding-block: 20px; transition: padding 200ms ease; }
.site-header.is-compact .navbar { padding-block: 8px; }
.brand-logo { display: block; }
/* Logo bleeds into the header padding (negative margin) so it can be large
   without inflating the bar height */
.brand-logo img { display: block; height: 72px; width: auto; margin-block: -10px; transition: height 200ms ease; }
.site-header.is-compact .brand-logo img { height: 54px; margin-block: -6px; }
/* Applied for one frame on load so a restored scroll position snaps the header
   to its compact size instead of animating into it */
.site-header.is-instant,
.site-header.is-instant .navbar,
.site-header.is-instant .brand-logo img { transition: none; }
.brand-wordmark {
  display: inline-flex;
  align-items: baseline;
  gap: 0.25rem;
  font-family: var(--wg-font-display);
  font-size: 1.25rem;
  font-weight: 700;
  text-decoration: none;
}
.brand-wordmark .b-web { color: var(--wg-navy); }
.brand-wordmark .b-it { color: var(--wg-primary-deep); }
.site-header .nav-link { font-weight: 700; font-size: 1.125rem; color: var(--wg-navy); }
.site-header .nav-link:hover, .site-header .nav-link:focus { color: var(--wg-primary-deep); }
/* Kill Bootstrap's light-blue focus ring; the brand outline + circle carry focus */
.site-header .nav-link:focus,
.site-header .nav-link:focus-visible { box-shadow: none; }
.site-header .dropdown-menu {
  border: 1px solid rgba(3, 40, 65, 0.1);
  /* Matches the header: the mega panel hangs flush off its bottom border with
     border-top:0, so the two have to read as one continuous surface. */
  background: #fff;
  border-radius: 0.375rem;
}
.site-header .dropdown-item { font-weight: 700; color: var(--wg-navy); border-radius: 0.25rem; }
.site-header .dropdown-item:hover,
.site-header .dropdown-item:focus { background: rgba(151, 186, 102, 0.25); color: var(--wg-darkgreen); }
/* Kill Bootstrap's blue :active flash on click */
.site-header .dropdown-item:active { background: rgba(151, 186, 102, 0.4); color: var(--wg-darkgreen); }

/* ── Nav hover circle (desktop only) ──────────────────── */
.site-header .nav-link.nav-circle { position: relative; }
.site-header .nav-circle-label { position: relative; z-index: 1; }
.nav-circle-svg {
  position: absolute;
  top: -3px;
  left: -5px;
  width: calc(100% + 10px);
  height: calc(100% + 6px);
  overflow: visible; /* stroke may kiss the box edge when squeezed */
  pointer-events: none;
  display: none; /* mobile default: off */
}
@media (min-width: 992px) {
  .nav-circle-svg { display: block; }
}
.nav-circle-svg path {
  stroke: var(--wg-primary);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 101;
  stroke-dashoffset: -101; /* hidden; negative offset makes the draw run counter-clockwise */
  transition: stroke-dashoffset 260ms ease-in; /* un-draw on leave */
}
/* No :focus-visible here: Bootstrap refocuses the dropdown toggle when the menu
   closes, which kept the Industries circle drawn until the next click. Keyboard
   focus still gets the global navy outline. */
.site-header .nav-circle:hover .nav-circle-svg path,
.site-header .nav-circle.active .nav-circle-svg path {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 420ms ease-out; /* draw on enter */
}
@media (prefers-reduced-motion: reduce) {
  .nav-circle-svg path { transition: none !important; }
}
/* Active state: the circle carries it on desktop, color on mobile */
@media (min-width: 992px) {
  .site-header .navbar-nav .nav-link.active { color: var(--wg-navy); }
}
@media (max-width: 991.98px) {
  .site-header .nav-link.active { color: var(--wg-primary-deep); }

  /* The logo/toggler row is a non-wrapping flex row, so the collapse opened as
     a squeezed third column to the right of the logo. Wrapping drops it onto
     its own full-width line under the bar, left aligned like the logo. */
  .site-header .navbar-bar { flex-wrap: wrap; }
  .site-header .navbar-collapse {
    flex-basis: 100%;
    /* A long menu (with a dropdown open) can outrun a phone screen */
    max-height: calc(100vh - 5.5rem);
    max-height: calc(100dvh - 5.5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* ── Industries mega menu ─────────────────────────────── */
@media (min-width: 992px) {
  /* Static li → the panel positions against .site-header (sticky) */
  .site-header .nav-item.wg-mega { position: static; }
  .site-header .wg-mega-panel {
    position: absolute;
    top: 100%; /* flush under the header's bottom border */
    left: 50%;
    transform: translateX(-50%);
    width: min(720px, 100vw - 2rem);
    margin-top: 0; /* cancel --bs-dropdown-spacer gap */
    padding: 1.75rem;
    border: 1px solid rgba(3, 40, 65, 0.1);
    border-top: 0;
    border-bottom: 3px solid var(--wg-primary); /* grounding accent so the panel reads against the page */
    border-radius: 0 0 0.5rem 0.5rem;
    background: #fff;
    box-shadow: 0 24px 48px -16px rgba(3, 40, 65, 0.4);
  }
  .wg-mega-grid {
    display: grid;
    grid-template-columns: 1fr 1.15fr;
    gap: 1rem 2rem;
    align-items: stretch; /* intro column matches links height so the CTA pins to the bottom */
  }
}
.wg-mega-intro { display: flex; flex-direction: column; }
.wg-mega-heading {
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: 2.05rem;
  line-height: 1.14;
  color: var(--wg-navy);
  margin-bottom: 1rem;
  text-wrap: balance;
}
.wg-mega-text { font-size: 1.08rem; line-height: 1.7; color: rgba(3, 40, 65, 0.72); margin-bottom: 0; text-wrap: pretty; }

/* Accent words in the intro copy */
.wg-gold-text { color: var(--wg-gold); }
.wg-marked {
  /* marker-highlight swipe under the phrase */
  background: var(--wg-marker);
  padding-inline: 0.08em;
}
/* Same marker-swipe effect, gold instead of green, for text sitting on a
   dark background (the light-green marker has poor contrast there). */
.wg-marked-gold {
  background: linear-gradient(transparent 62%, rgba(216, 172, 47, 0.5) 62%, rgba(216, 172, 47, 0.5) 96%, transparent 96%);
  padding-inline: 0.08em;
}

/* Bottom-anchored mini CTA */
.wg-mega-cta {
  margin-top: auto;
  padding-top: 1rem;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--wg-primary-deep);
  text-decoration: none;
}
.wg-mega-cta:hover { color: var(--wg-darkgreen); }
.wg-mega-cta-arrow { display: inline-block; transition: transform 160ms ease; }
.wg-mega-cta:hover .wg-mega-cta-arrow { transform: translateX(4px); }
@media (prefers-reduced-motion: reduce) {
  .wg-mega-cta-arrow { transition: none; }
}
.wg-mega-item {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  white-space: normal;
  border-radius: 0.375rem;
  padding: 0.5rem 0.75rem;
}
.wg-mega-icon { color: var(--wg-primary-deep); width: 1.25rem; text-align: center; margin-top: 0.2rem; flex: none; }
.wg-mega-body { display: block; }
.wg-mega-label { display: block; font-weight: 700; color: var(--wg-navy); }
.wg-mega-desc { display: block; font-weight: 400; color: rgba(3, 40, 65, 0.6); }
/* Collapsed (mobile): degrade to the current plain link list */
@media (max-width: 991.98px) {
  .wg-mega-intro,
  .wg-mega-desc { display: none; }
  .wg-mega-grid { display: block; }
}

/* ── Case study gallery slider ────────────────────────── */
/* Controls and indicators clear the caption band below the photo */
.wg-gallery {
  --wg-gallery-caption-h: 3.5rem;
  /* Width comes from its grid column, which shares the row with the stats card */
  border-radius: 0.5rem;
  overflow: hidden;
  background: #fff;
  border: 1px solid rgba(3, 40, 65, 0.1);
}
.wg-gallery-img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: rgba(3, 40, 65, 0.06);
}
.wg-gallery-caption {
  display: flex;
  align-items: center;
  min-height: var(--wg-gallery-caption-h);
  margin: 0;
  padding: 0.75rem 1rem;
  font-size: 0.9375rem;
  color: rgba(3, 40, 65, 0.7);
}
.wg-gallery .carousel-control-prev,
.wg-gallery .carousel-control-next { bottom: var(--wg-gallery-caption-h); width: 15%; opacity: 1; }
.wg-gallery .carousel-control-prev-icon,
.wg-gallery .carousel-control-next-icon {
  width: 2.5rem;
  height: 2.5rem;
  padding: 0.75rem;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.715);
  background-size: 1rem 1rem;
  transition: background-color 150ms ease;
}
.wg-gallery .carousel-control-prev:hover .carousel-control-prev-icon,
.wg-gallery .carousel-control-next:hover .carousel-control-next-icon { background-color: var(--wg-navy); }
.wg-gallery .carousel-indicators { bottom: calc(var(--wg-gallery-caption-h) + 0.25rem); margin-bottom: 0.5rem; }
.wg-gallery .carousel-indicators [data-bs-target] {
  width: 0.625rem;
  height: 0.625rem;
  border: 0;
  border-radius: 50%;
  background-color: rgba(230, 231, 226, 0.65);
  box-shadow: 0 0 0 1px rgba(3, 40, 65, 0.35);
  opacity: 1;
}
.wg-gallery .carousel-indicators .active { background-color: var(--wg-gold); }
@media (max-width: 575.98px) {
  .wg-gallery { --wg-gallery-caption-h: 5rem; }
  .wg-gallery-img { aspect-ratio: 4 / 3; }
}

/* ── Footer ───────────────────────────────────────────── */
.site-footer { background-color: var(--wg-navy); color: var(--wg-offwhite); }
.site-footer h2 { font-size: 0.875rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--wg-lightgreen); }
.site-footer a { color: rgba(230, 231, 226, 0.8); text-decoration: none; }
.site-footer a:hover { color: var(--wg-offwhite); }
/* The global navy focus ring is invisible against the navy footer */
.site-footer :focus-visible { outline-color: var(--wg-offwhite); }
/* Wordmark logo — the light-color variant of the text-only mark, since the
   footer sits on navy */
.site-footer .footer-logo { display: block; }
.site-footer .footer-logo img { display: block; height: 52px; width: auto; }
/* The ACN badge ships as black artwork on transparent; invert it to read on navy */
.site-footer .footer-acn {
  display: block;
  height: 44px;
  width: auto;
  filter: brightness(0) invert(1);
  opacity: 0.9;
}
.site-footer .footer-bottom {
  border-top: 1px solid rgba(230, 231, 226, 0.15);
  background-color: #000;
  color: var(--wg-offwhite);
}

/* Link columns: the heading is a button so phones can collapse it. Everywhere
   above the phone breakpoint it renders as the plain heading it was. */
.site-footer .footer-col-heading { margin: 0; }
.site-footer .footer-col-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
}
.site-footer .footer-col-chevron { display: none; }
.site-footer .footer-col-list { margin-top: 1rem; }

/* ── Footer accordions (phones) ───────────────────────── */
/* .is-accordion-ready is set by site.js, so without JS every list stays open */
@media (max-width: 767.98px) {
  .site-footer .footer-acn { display: none; }

  .footer-grid.is-accordion-ready .footer-col { border-top: 1px solid rgba(230, 231, 226, 0.15); padding-top: 0.875rem; }
  .footer-grid.is-accordion-ready .footer-col-toggle { cursor: pointer; padding-bottom: 0.125rem; }
  .footer-grid.is-accordion-ready .footer-col-chevron {
    display: block;
    font-size: 0.75rem;
    transition: transform 200ms ease;
  }
  .footer-grid.is-accordion-ready .footer-col.is-open .footer-col-chevron { transform: rotate(180deg); }

  /* 0fr → 1fr animates the height without hard-coding one; visibility keeps the
     collapsed links out of the tab order */
  .footer-grid.is-accordion-ready .footer-col-body {
    display: grid;
    grid-template-rows: 0fr;
    overflow: hidden;
    visibility: hidden;
    transition: grid-template-rows 220ms ease, visibility 0s linear 220ms;
  }
  .footer-grid.is-accordion-ready .footer-col.is-open .footer-col-body {
    grid-template-rows: 1fr;
    visibility: visible;
    transition: grid-template-rows 220ms ease, visibility 0s;
  }
  .footer-grid.is-accordion-ready .footer-col-list {
    min-height: 0;
    overflow: hidden;
    margin-top: 0;
    padding-block: 0.625rem 0.25rem;
  }
}
@media (prefers-reduced-motion: reduce) {
  .footer-col-body, .footer-col-chevron { transition: none !important; }
}

/* ── Skip link ────────────────────────────────────────── */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1050;
}
.skip-link:focus {
  left: 1rem;
  top: 1rem;
  background: var(--wg-navy);
  color: var(--wg-offwhite);
  padding: 0.5rem 1rem;
  border-radius: 0.375rem;
}

/* ── Scroll reveal ────────────────────────────────────── */
.reveal-ready [data-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 500ms ease, transform 500ms ease;
}
.reveal-ready [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── Partner logos carousel ───────────────────────────── */
/* Shows 5 logos at a time, scrolls continuously, loops infinitely.
   The track contains 8 logos duplicated (2x = 16 total) for seamless wrapping. */
/* The whole "Who we work with" section is tinted, so the carousel itself
   no longer needs its own background/border — that would just draw a
   second, redundant panel edge partway down an already-tinted section. */
/* padding-bottom (not margin) on the section itself, so the tint has
   real cushion below the logos to match the ~83px above the heading —
   padding on the section can't collapse through like a margin on the
   full-bleed child would. */
/* Generic offwhite tint, used wherever a section needs texture instead of
   flat white (Proof, Partners). */
.section-offwhite-tint { background-color: var(--wg-offwhite); }
/* Partners-specific: extra bottom padding so the tint has cushion below
   the full-bleed logo carousel (see the padding-imbalance fix history). */
.section-partners-pb { padding-bottom: 2rem; }
.partner-carousel {
  overflow: hidden;
  padding: 1.5rem 0;
  /* Logos sit directly on the section's own texture, no separate ribbon
     band behind them. Logos fade out at each edge instead of clipping
     mid-logo. */
  mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
}
.partner-carousel-track {
  display: flex;
  align-items: center;
  /* Percentages in `transform` resolve against the element's OWN layout
     box, not its scrollable content. A flex row left at its default
     width just fills its container (here, .wg-container's ~1232px)
     while the overflowing logos paint outside it without enlarging that
     box, so a bare translateX(-50%) was only ever traveling half of
     ~1232px — a fraction of the full doubled-up content — before
     snapping back to 0%. width:max-content makes the track's own box
     match its true content width, so -50% (corrected below for the
     margin quirk) actually reaches the halfway point of the real
     content and the loop travels its full, intended distance. */
  width: max-content;
  /* No edge fade: masking .partner-carousel faded its solid offwhite/gold
     band to transparent at the edges too, revealing the plain white page
     behind it as a hazy, unintentional-looking edge instead of a clean
     full-bleed band. Logos just clip at the edge instead, which reads as
     a normal marquee, not a bug. */
  animation: partner-scroll 40s linear infinite;
}
/* Fixed-width 20% columns made the visual gap between logos uneven: a
   narrow square mark (Huntress) centered in its own column next to
   another narrow one (Ubiquiti) left double the whitespace of two wide
   wordmarks sitting almost edge to edge in theirs. Sizing each logo to
   its own content and spacing with a trailing margin instead means the
   gap between any two logos is always the same value, however wide or
   narrow either one renders.
   This is margin-right on every logo (not the track's flex `gap`) on
   purpose: with 12 logos rendered twice for the loop, `gap` sits only
   *between* the 24 items, giving an odd 23 gaps that can't split evenly
   in half. translateX(-50%) then lands half a gap short of the seam
   between the two sets, and the marquee visibly skips there once a
   loop. Putting the spacing on each item's own margin instead makes the
   first 12 logos (plus their trailing margins) an exact, self-contained
   half of the track, so -50% always lands precisely on the duplicate. */
.partner-logo {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  margin-right: 3rem;
}
.partner-logo img {
  /* Sits directly on the carousel's own offwhite ribbon (see
     .partner-carousel), no per-logo card needed for contrast anymore.
     A fixed height (not max-height) so every logo is scaled to exactly
     the same size: max-height only ever shrinks an oversized logo down,
     it never grows an undersized one up, and several of these SVGs have
     small intrinsic dimensions (e.g. Addigy's is 139x37) that rendered
     at their own native size instead of matching the rest. */
  height: 44px;
  max-width: 100%;
  width: auto;
  object-fit: contain;
  filter: grayscale(100%);
  opacity: 0.75;
  transition: filter 200ms ease, opacity 200ms ease;
}
/* A touch bigger than the standard 44px: for a logo whose own mark reads
   smaller than its neighbors at the same height (e.g. Huntress's tighter
   letterforms) even though the sizing itself is no longer a bug. */
.partner-logo img.partner-logo-boost { height: 50px; }
/* A touch smaller than the standard 44px: for a bold/heavy wordmark
   (UniFi's thick lettering) that reads bigger than its neighbors even
   though the pixel height is identical. */
.partner-logo img.partner-logo-shrink { height: 34px; }
.partner-logo img:hover {
  filter: grayscale(0%);
  opacity: 1;
}
/* Credential line under a logo that needs one for context (e.g. Microsoft
   Cloud Solution Provider isn't legible from the plain Microsoft mark
   alone). Muted and small so it reads as a caption, not a second logo. */
.partner-logo-label {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--wg-navy);
  opacity: 0.55;
  text-align: center;
  white-space: nowrap;
}
/* translateX(-50%) here resolves against the track's own box, which
   width:max-content (above) sizes to match its true content width
   (including every item's trailing margin, the last one included) — so
   a plain -50% lands exactly on the seam between the two duplicated
   sets and the loop restarts with no visible skip. */
@keyframes partner-scroll {
  0% { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}
/* Mobile: tighter gap, shorter logos */
@media (max-width: 767.98px) {
  .partner-carousel-track { animation-duration: 26s; }
  .partner-logo { margin-right: 1.75rem; }
  .partner-logo img { height: 36px; }
  .partner-logo img.partner-logo-boost { height: 41px; }
  .partner-logo img.partner-logo-shrink { height: 28px; }
}

/* ── Pricing comparison table ─────────────────────────── */
.pricing-table-wrap {
  overflow-x: auto;
  border-radius: 0.75rem;
  background: #fff;
  border: 1px solid rgba(3, 40, 65, 0.1);
  box-shadow: 0 4px 24px rgba(3, 40, 65, 0.06);
}
.pricing-table {
  width: 100%;
  min-width: 700px;
  border-collapse: collapse;
  font-size: 0.9375rem;
}
.pricing-table th,
.pricing-table td {
  padding: 0.875rem 1rem;
  text-align: center;
  border-bottom: 1px solid rgba(3, 40, 65, 0.08);
  vertical-align: middle;
}
.pricing-table th:first-child,
.pricing-table td:first-child {
  text-align: left;
  padding-left: 1.5rem;
}
/* Header row */
.pricing-table thead tr {
  background: linear-gradient(180deg, rgba(3, 40, 65, 0.04) 0%, rgba(3, 40, 65, 0.02) 100%);
}
.pricing-table .tier-col {
  min-width: 160px;
  padding-top: 1.25rem;
  padding-bottom: 1rem;
}
.pricing-table .tier-label {
  display: block;
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: 1.125rem;
  color: var(--wg-navy);
}
.pricing-table .tier-badge {
  display: block;
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--wg-gold);
  margin-bottom: 0.25rem;
}
/* Featured column (Managed Services) */
.pricing-table .tier-featured {
  background: linear-gradient(180deg, rgba(151, 186, 102, 0.12) 0%, rgba(151, 186, 102, 0.06) 100%);
  border-left: 2px solid var(--wg-lightgreen);
  border-right: 2px solid var(--wg-lightgreen);
}
.pricing-table thead .tier-featured {
  border-top: 2px solid var(--wg-lightgreen);
  border-top-left-radius: 0.5rem;
  border-top-right-radius: 0.5rem;
}
.pricing-table tbody tr:last-child .tier-featured {
  border-bottom: 2px solid var(--wg-lightgreen);
  border-bottom-left-radius: 0.5rem;
  border-bottom-right-radius: 0.5rem;
}
/* Price row */
.pricing-table .tier-price-row td {
  padding-top: 0.5rem;
  padding-bottom: 1.25rem;
  border-bottom: 2px solid rgba(3, 40, 65, 0.1);
}
.pricing-table .tier-price {
  vertical-align: top;
}
.pricing-table .price-amount {
  display: block;
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: 2rem;
  color: var(--wg-darkgreen);
  line-height: 1.1;
}
.pricing-table .price-unit {
  display: block;
  font-size: 0.8125rem;
  color: rgba(3, 40, 65, 0.6);
  margin-top: 0.25rem;
}
/* Feature label column */
.pricing-table .feature-label {
  font-weight: 600;
  color: rgba(3, 40, 65, 0.8);
}
/* Spacer row */
.pricing-table .feature-spacer td {
  padding: 0.5rem;
  border-bottom: 2px solid rgba(3, 40, 65, 0.1);
  background: rgba(230, 231, 226, 0.4);
}
/* Checkmarks and dashes */
.pricing-table .check-yes {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  background: var(--wg-primary-deep);
  color: #fff;
  font-weight: 700;
  font-size: 0.875rem;
}
.pricing-table .check-no {
  display: inline-block;
  color: rgba(3, 40, 65, 0.3);
  font-size: 1.25rem;
  font-weight: 300;
}
.pricing-table .check-optional {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--wg-gold);
  background: rgba(216, 172, 47, 0.15);
  padding: 0.25rem 0.5rem;
  border-radius: 0.25rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
/* Alternating row colors */
.pricing-table tbody tr:nth-child(even):not(.tier-price-row):not(.feature-spacer) {
  background: rgba(230, 231, 226, 0.25);
}
.pricing-table tbody tr:nth-child(even):not(.tier-price-row):not(.feature-spacer) .tier-featured {
  background: linear-gradient(180deg, rgba(151, 186, 102, 0.18) 0%, rgba(151, 186, 102, 0.1) 100%);
}
/* Mobile adjustments */
@media (max-width: 767.98px) {
  .pricing-table { font-size: 0.8125rem; }
  .pricing-table th,
  .pricing-table td { padding: 0.625rem 0.5rem; }
  .pricing-table th:first-child,
  .pricing-table td:first-child { padding-left: 0.75rem; }
  .pricing-table .price-amount { font-size: 1.5rem; }
  .pricing-table .tier-col { min-width: 120px; }
}
/* Below ~576px the 700px-min-width table (above) forced horizontal
   scrolling on every phone — table-layout:fixed with percentage columns
   that sum to 100% makes the table always fit the viewport instead, with
   long feature labels and the "paid add-on" badge wrapping to a second
   line rather than pushing the table wider than the screen. */
@media (max-width: 575.98px) {
  .pricing-table-wrap { overflow-x: visible; }
  .pricing-table {
    min-width: 0;
    width: 100%;
    table-layout: fixed;
    font-size: 0.6875rem;
  }
  .pricing-table th,
  .pricing-table td { padding: 0.5rem 0.3rem; overflow-wrap: break-word; }
  .pricing-table th:first-child,
  .pricing-table td:first-child { width: 34%; padding-left: 0.4rem; }
  .pricing-table .tier-col,
  .pricing-table td:not(:first-child) { width: 22%; min-width: 0; }
  .pricing-table .tier-label { font-size: 0.8125rem; }
  .pricing-table .tier-badge { font-size: 0.5625rem; }
  .pricing-table .price-amount { font-size: 1.15rem; }
  .pricing-table .price-unit { font-size: 0.625rem; }
  .pricing-table .check-yes { width: 1.25rem; height: 1.25rem; font-size: 0.75rem; }
  .pricing-table .check-no { font-size: 1rem; }
  .pricing-table .check-optional { font-size: 0.5625rem; padding: 0.2rem 0.3rem; }
}

/* ── SLA tooltip (pricing comparison table) ───────────── */
/* Bootstrap's default tooltip caps at 200px and is plain black — both make the
   SLA table cramped and flat. This widens it to a comfortable reading measure,
   swaps the fill for brand navy (with a matching arrow), and color-codes each
   priority row so P1/P2/P3 are told apart at a glance instead of by reading
   every cell. */
.tooltip.sla-tooltip {
  --bs-tooltip-max-width: 26rem;
  --bs-tooltip-bg: var(--wg-navy);
  /* Bootstrap fades the whole tooltip element in at 90% opacity by default
     (--bs-tooltip-opacity), which lets the page show through the navy fill
     faintly. Forcing both the variable and the property to 1 makes it fully
     solid. */
  --bs-tooltip-opacity: 1;
  opacity: 1;
}
.tooltip.sla-tooltip .tooltip-inner {
  max-width: 26rem;
  text-align: left;
  padding: 1rem 1.125rem;
  background-color: var(--wg-navy);
  box-shadow: 0 16px 40px rgba(3, 40, 65, 0.35);
}
.tooltip.sla-tooltip .tooltip-arrow::before {
  border-top-color: var(--wg-navy) !important;
  border-bottom-color: var(--wg-navy) !important;
}
.sla-tooltip-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  font-size: 0.8125rem;
}
.sla-tooltip-table th,
.sla-tooltip-table td {
  padding: 0.5rem 0.625rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid rgba(230, 231, 226, 0.15);
}
.sla-tooltip-table thead th {
  font-weight: 700;
  text-transform: uppercase;
  font-size: 0.6875rem;
  letter-spacing: 0.05em;
  color: var(--wg-lightgreen);
  padding-bottom: 0.625rem;
  border-bottom: 2px solid rgba(151, 186, 102, 0.4);
}
.sla-tooltip-table tbody tr:last-child th,
.sla-tooltip-table tbody tr:last-child td { border-bottom: 0; }
.sla-tooltip-table tbody tr:nth-child(even) td { background: rgba(230, 231, 226, 0.05); }
.sla-tooltip-table td:not(:first-child) { color: rgba(230, 231, 226, 0.85); }
/* Priority badge chip: distinct brand color per row so P1 (most urgent) reads
   hottest and P3 (least urgent) reads coolest, without introducing a color
   outside the existing palette. */
.sla-tier-badge {
  display: inline-block;
  min-width: 1.75rem;
  margin-right: 0.4rem;
  padding: 0.05rem 0.375rem;
  border-radius: 0.25rem;
  font-weight: 700;
  font-size: 0.6875rem;
  text-align: center;
  color: var(--wg-darkgreen);
}
.sla-row-p1 .sla-tier-badge { background: var(--wg-gold); }
.sla-row-p2 .sla-tier-badge { background: var(--wg-lightgreen); }
.sla-row-p3 .sla-tier-badge { background: var(--wg-accent-green); color: #fff; }
.sla-row-p1 td:first-child { border-left: 3px solid var(--wg-gold); }
.sla-row-p2 td:first-child { border-left: 3px solid var(--wg-lightgreen); }
.sla-row-p3 td:first-child { border-left: 3px solid var(--wg-accent-green); }
.sla-tooltip-note {
  margin: 0.75rem 0 0;
  padding: 0.625rem 0.75rem 0;
  border-top: 1px solid rgba(230, 231, 226, 0.2);
  font-size: 0.75rem;
  color: rgba(230, 231, 226, 0.85);
}
/* Default (tooltip) rendering of a time cell: "Remote: 1 hr" on its own
   line, matching the plain-text "Remote: 1 hr<br>On-site: 4 hrs" this
   replaced. .sla-table-wrap below restyles these same spans into a
   label-over-stat layout for the static section; the tooltip never
   opts into that, so it keeps reading as compact prose. */
.sla-time { display: block; }
/* Only the label half of a real "label: value" pair gets the colon — the
   lone "Same, any time" cell (P3 after hours) has no value span. */
.sla-time-label:has(+ .sla-time-val)::after { content: ": "; }
@media (max-width: 575.98px) {
  .tooltip.sla-tooltip { --bs-tooltip-max-width: 18rem; }
  .tooltip.sla-tooltip .tooltip-inner { max-width: 18rem; }
}

/* ══════════════════════════════════════════════════════════
   How We Run (Core Values) Page
   ══════════════════════════════════════════════════════════ */

/* Hero: Navy band with frog mascot */
.hwr-hero {
  background-color: var(--wg-navy);
  padding-block: 4rem 3rem;
}
@media (min-width: 768px) {
  .hwr-hero { padding-block: 5rem 4rem; }
}
.hwr-hero-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  align-items: center;
}
@media (min-width: 768px) {
  .hwr-hero-grid { grid-template-columns: 1fr auto; }
}
.hwr-hero h1 {
  color: var(--wg-offwhite);
  margin: 0;
}
.hwr-hero-subhead {
  color: rgba(230, 231, 226, 0.85);
  font-size: 1.125rem;
  margin-top: 1rem;
  max-width: 36rem;
}
.hwr-mascot {
  width: clamp(160px, 22vw, 260px);
  height: auto;
  display: block;
  margin-inline: auto;
}
@media (max-width: 479.98px) {
  .hwr-mascot { display: none; }
}

/* EOS Section: two columns */
.hwr-eos {
  background: #fff;
  padding-block: 4rem;
}
@media (min-width: 768px) { .hwr-eos { padding-block: 5rem; } }
.hwr-eos-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
}
@media (min-width: 900px) {
  .hwr-eos-grid { grid-template-columns: 1.2fr 1fr; gap: 3rem; }
}
.hwr-eos-questions {
  list-style: none;
  margin: 0;
  padding: 0;
}
.hwr-eos-questions li {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid rgba(3, 40, 65, 0.1);
  font-weight: 600;
  color: var(--wg-navy);
}
.hwr-eos-questions li:last-child { border-bottom: 0; }
.hwr-eos-questions .hwr-q-icon {
  flex: none;
  color: var(--wg-accent-green);
  margin-top: 0.15rem;
}

/* Purpose Section: light grey pull quote */
.hwr-purpose {
  background-color: var(--wg-offwhite);
  padding-block: 4rem;
}
@media (min-width: 768px) { .hwr-purpose { padding-block: 5rem; } }
.hwr-purpose-quote {
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  line-height: 1.3;
  color: var(--wg-primary);
  text-align: center;
  max-width: 48rem;
  margin-inline: auto;
  padding-inline: 1rem;
}
.hwr-purpose-note {
  text-align: center;
  color: rgba(3, 40, 65, 0.7);
  margin-top: 2rem;
  max-width: 42rem;
  margin-inline: auto;
}

/* Core Values: stacked cards with left border */
.hwr-values {
  background: #fff;
  padding-block: 4rem;
}
@media (min-width: 768px) { .hwr-values { padding-block: 5rem; } }

/* Value card wrapper with TOUCH letter */
.hwr-value-row {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: 1.5rem;
}
.hwr-value-row:last-child { margin-bottom: 0; }

/* Large TOUCH mnemonic letter */
.hwr-touch-letter {
  flex: none;
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: clamp(3rem, 8vw, 5rem);
  line-height: 1;
  color: var(--wg-accent-green);
  opacity: 0.25;
  width: 3.5rem;
  text-align: center;
  padding-top: 0.5rem;
  display: none;
}
@media (min-width: 768px) {
  .hwr-touch-letter {
    display: block;
    width: 4.5rem;
  }
}
/* Gold letter for Unselfish Generosity */
.hwr-touch-letter--gold {
  color: var(--wg-gold);
}

.hwr-value-card {
  flex: 1;
  min-width: 0;
  background: #fff;
  border-left: 4px solid var(--wg-accent-green);
  padding: 1.5rem 1.5rem 1.5rem 1.75rem;
  /* No border-radius per spec */
}
.hwr-value-card:last-child { margin-bottom: 0; }
.hwr-value-card h3 {
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: 1.375rem;
  color: var(--wg-navy);
  margin: 0 0 0.25rem 0;
}
.hwr-value-card .hwr-value-tagline {
  font-weight: 700;
  color: var(--wg-accent-green);
  font-size: 0.9375rem;
  margin-bottom: 1rem;
}
.hwr-value-card p {
  color: rgba(3, 40, 65, 0.85);
  margin: 0 0 1rem 0;
}
.hwr-value-card p:last-child { margin-bottom: 0; }
.hwr-value-card ul {
  margin: 1rem 0 0 0;
  padding-left: 1.25rem;
  color: rgba(3, 40, 65, 0.85);
}
.hwr-value-card li { margin-top: 0.5rem; }

/* Generosity card: gold accent, larger */
.hwr-value-card--featured {
  border-left-color: var(--wg-gold);
  padding: 2rem 2rem 2rem 2.25rem;
}
.hwr-value-card--featured h3 {
  font-size: 1.625rem;
}
.hwr-value-card--featured .hwr-value-tagline {
  color: var(--wg-gold);
}

/* WebGuy Touch Section */
.hwr-touch {
  background-color: var(--wg-offwhite);
  padding-block: 4rem;
}
@media (min-width: 768px) { .hwr-touch { padding-block: 5rem; } }
.hwr-touch-content {
  max-width: 48rem;
  margin-inline: auto;
}
.hwr-touch-intro {
  text-align: center;
  margin-bottom: 2.5rem;
}
.hwr-touch-intro p {
  color: rgba(3, 40, 65, 0.85);
  max-width: 40rem;
  margin-inline: auto;
}

/* Convergence graphic */
.hwr-convergence {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
}
@media (min-width: 640px) {
  .hwr-convergence {
    flex-direction: row;
    justify-content: center;
    gap: 1rem;
  }
}
.hwr-pills {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}
@media (min-width: 640px) {
  .hwr-pills {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem;
  }
}
.hwr-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem 1rem;
  border-radius: 999px;
  font-size: 0.8125rem;
  font-weight: 700;
  white-space: nowrap;
}
.hwr-pill--green {
  background: var(--wg-accent-green);
  color: #fff;
}
.hwr-pill--gold {
  background: var(--wg-gold);
  color: var(--wg-darkgreen);
}
.hwr-convergence-arrow {
  font-size: 2rem;
  color: var(--wg-navy);
  transform: rotate(90deg);
}
@media (min-width: 640px) {
  .hwr-convergence-arrow { transform: rotate(0deg); }
}
.hwr-result-pill {
  padding: 0.75rem 1.5rem;
  font-size: 1rem;
}

/* Touch list */
.hwr-touch-list {
  list-style: none;
  margin: 2.5rem 0 0 0;
  padding: 0;
  max-width: 36rem;
  margin-inline: auto;
}
.hwr-touch-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.625rem 0;
  color: rgba(3, 40, 65, 0.85);
}
.hwr-touch-list strong {
  color: var(--wg-navy);
}
.hwr-touch-list .hwr-touch-icon {
  flex: none;
  color: var(--wg-accent-green);
  margin-top: 0.2rem;
}

/* Who We Serve: commitment cards */
.hwr-serve {
  background: #fff;
  padding-block: 4rem;
}
@media (min-width: 768px) { .hwr-serve { padding-block: 5rem; } }
.hwr-serve-quote {
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--wg-primary);
  text-align: center;
  max-width: 42rem;
  margin: 0 auto 2.5rem auto;
  padding: 1.5rem;
  background: rgba(151, 186, 102, 0.1);
  border-radius: 0.5rem;
}
.hwr-commit-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}
@media (min-width: 480px) {
  .hwr-commit-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 768px) {
  .hwr-commit-grid { grid-template-columns: repeat(4, 1fr); }
}
.hwr-commit-card {
  text-align: center;
  padding: 1.5rem 1rem;
}
.hwr-commit-icon {
  font-size: 1.5rem;
  color: var(--wg-accent-green);
  margin-bottom: 0.75rem;
}
.hwr-commit-card h4 {
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: 1rem;
  color: var(--wg-navy);
  margin: 0 0 0.5rem 0;
}
.hwr-commit-card p {
  font-size: 0.9375rem;
  color: rgba(3, 40, 65, 0.7);
  margin: 0;
}

/* CTA: gold button variant */
.btn-gold {
  background-color: var(--wg-gold);
  color: var(--wg-darkgreen);
  border: 2px solid var(--wg-gold);
  font-weight: 700;
}
.btn-gold:hover, .btn-gold:focus {
  background-color: #c49a28;
  border-color: #c49a28;
  color: var(--wg-darkgreen);
}

/* About page: "How We Run" section — five value cards in a single row,
   read left to right as T-O-U-C-H, each anchored by its own colored badge.
   Built on the same .tile component as the team grid above it, so the two
   sections read as one visual system instead of two different card styles
   stacked on top of each other. */
.hwr-value-card { text-align: center; align-items: center; }
.hwr-value-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: 1.25rem;
  color: #fff;
}
.hwr-value-card--t .hwr-value-badge { background-color: var(--wg-navy); }
.hwr-value-card--o .hwr-value-badge { background-color: var(--wg-accent-green); }
.hwr-value-card--u .hwr-value-badge { background-color: var(--wg-gold); color: var(--wg-darkgreen); }
.hwr-value-card--c .hwr-value-badge { background-color: var(--wg-lightgreen); color: var(--wg-darkgreen); }
.hwr-value-card--h .hwr-value-badge { background-color: var(--wg-darkgreen); }
/* A thin top edge in the same color continues the T-O-U-C-H color story
   across the row even once the badges are out of the eye's direct line. */
.hwr-value-card { border-top-width: 3px; border-top-style: solid; }
.hwr-value-card--t { border-top-color: var(--wg-navy); }
.hwr-value-card--o { border-top-color: var(--wg-accent-green); }
.hwr-value-card--u { border-top-color: var(--wg-gold); }
.hwr-value-card--c { border-top-color: var(--wg-lightgreen); }
.hwr-value-card--h { border-top-color: var(--wg-darkgreen); }
/* Five into a 2-across grid (sm–md) leaves the last card alone on its line;
   a lone flex item with margin:auto centers itself in that remaining line
   instead of hugging the left edge like a mistake. Full width below sm,
   where the grid is already single-column and every card is "alone". */
@media (min-width: 576px) and (max-width: 991.98px) {
  .hwr-value-grid > .col:last-child { margin-inline: auto; }
}

.hwr-about-touch {
  background: rgba(3, 40, 65, 0.04);
  border-radius: 0.5rem;
  padding: 1rem 1.25rem;
}
.hwr-about-touch-inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: 36rem;
  margin-inline: auto;
}
.hwr-about-touch-icon {
  flex: none;
  font-size: 1.5rem;
  color: var(--wg-gold);
}

/* About page: origin-story timeline (hero) */
.about-story { list-style: none; margin: 0; padding: 0; }
.about-story-item { display: flex; gap: 1.25rem; }
.about-story-rail {
  flex: none;
  width: 5.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.about-story-year {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2rem;
  padding: 0.25rem 0.65rem;
  border-radius: 999px;
  background-color: var(--wg-navy);
  color: #fff;
  font-family: var(--wg-font-display);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-align: center;
  white-space: nowrap;
}
.about-story-year--now { background-color: var(--wg-gold); color: var(--wg-darkgreen); }
.about-story-line {
  flex: 1 1 auto;
  width: 2px;
  min-height: 2rem;
  margin: 0.5rem 0;
  background-color: var(--wg-lightgreen);
}
.about-story-body { padding-bottom: 2rem; }
.about-story-item:last-child .about-story-body { padding-bottom: 0; }
.about-story-quote {
  margin: 1rem 0 0;
  padding: 0.25rem 0 0.25rem 1.1rem;
  border-left: 3px solid var(--wg-gold);
  font-family: var(--wg-font-display);
  font-style: italic;
  font-size: 1.2rem;
  color: var(--wg-navy);
}
@media (max-width: 575.98px) {
  .about-story-rail { width: 3.5rem; }
  .about-story-year { font-size: 0.6875rem; padding: 0.2rem 0.4rem; }
}

/* ── Homepage "How We Work" step badges ──────────────────── */
/* A circular icon badge per step with a connecting line behind them,
   turning five plain numbered columns into a visible path. The line only
   shows at the lg breakpoint where the row is a single line of 5 — below
   that the grid wraps to 2 columns and a straight line would cut across
   unrelated steps. */
.home-process-wrap { position: relative; }
/* Zigzag connector (mobile/tablet, staircase layout): an SVG sibling of
   the <ol> rather than a child of it (an <ol> may only contain <li>), so
   .home-process-wrap positions both it and the list in the same box.
   viewBox 0-100 on both axes + preserveAspectRatio="none" means the
   path's points (measured badge centers, in percent) land correctly
   regardless of the wrap's actual pixel size. Hidden at lg, where
   .home-process-list::before draws the single straight line instead.

   A straight line badge-to-badge left each badge heading immediately
   sideways, cutting right through that step's own heading/paragraph
   (centered under its badge) on the way out. Each leg is a cubic bezier
   instead, with both control points pinned to the vertical midpoint —
   x unchanged from each endpoint — so the curve leaves and arrives
   travelling straight up/down and only swings sideways once it has
   cleared the text column, tracing a smooth S instead of a diagonal
   through the words. */
.home-process-zigzag {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}
.home-process-zigzag path {
  fill: none;
  stroke: var(--wg-gold);
  stroke-width: 2;
  opacity: 0.4;
  vector-effect: non-scaling-stroke;
}
@media (min-width: 992px) {
  .home-process-zigzag { display: none; }
}
.home-process-list { position: relative; z-index: 1; }
/* Staircase (below lg, single column): each step is narrower than the
   row and alternates flush left/right, so every one sits strictly lower
   *and* to a different side than the one before it — instead of two
   steps ever sharing a row, the way row-cols-2 had them. */
@media (max-width: 991.98px) {
  .home-process-step {
    flex: 0 0 64%;
    max-width: 64%;
  }
  .home-process-step:nth-child(odd) { margin-right: auto; }
  .home-process-step:nth-child(even) { margin-left: auto; }
}
@media (min-width: 992px) {
  .home-process-list::before {
    content: "";
    position: absolute;
    /* Badge center sits 2.75rem below the list's top edge (row gutter
       padding + half the badge's own 3.5rem height), measured directly
       rather than guessed. */
    top: 2.75rem;
    /* Badges are centered in 5 equal columns (row-cols-lg-5), so their
       centers land at exactly 10/30/50/70/90% — a 10% inset on each side
       reaches the first and last badge exactly, at any container width. */
    left: 10%;
    right: 10%;
    height: 2px;
    background: linear-gradient(90deg, var(--wg-gold) 0%, var(--wg-gold) 100%);
    opacity: 0.35;
    z-index: 0;
  }
}
.home-process-badge {
  position: relative;
  z-index: 1;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  background: var(--wg-gold);
  color: var(--wg-darkgreen);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  box-shadow: 0 4px 10px rgba(32, 45, 16, 0.18);
}

/* Breaks .partner-carousel out of .wg-container's max-width so the logo
   marquee spans the full viewport width instead of stopping at the
   content column. Standard "full-bleed" trick: center via left:50% +
   negative margin instead of plain width:100vw, so it isn't thrown off
   by a vertical scrollbar's width. */
.partner-carousel-full-bleed {
  position: relative;
  left: 50%;
  right: 50%;
  width: 100vw;
  margin-left: -50vw;
  margin-right: -50vw;
  border-radius: 0;
}

/* ── Homepage About/WebGuy Touch panel ───────────────────── */
/* Same bubble treatment as .cross-platform-panel below: rounded box,
   full-width text, no max-width cap. Combines with .about-watermark-wrap
   (top/bottom padding + the oversized background watermark text), this
   rule only adds the side padding, background, and corners. */
.about-touch-panel {
  background: linear-gradient(135deg, var(--wg-darkgreen) 0%, var(--wg-primary) 100%);
  border-radius: 0.75rem;
  padding-left: 2rem;
  padding-right: 2rem;
}
@media (min-width: 768px) {
  .about-touch-panel { padding-left: 3rem; padding-right: 3rem; }
}
/* .about-watermark's right:0 sits flush with the panel's outer edge
   instead of insetting by the panel's own padding, so the oversized text
   was crowding the rounded corner. Pull it in to match. */
.about-touch-panel .about-watermark { right: 2rem; }
@media (min-width: 768px) {
  .about-touch-panel .about-watermark { right: 3rem; }
}

/* ── Homepage cross-platform panel ───────────────────────── */
/* Layout and values copied from the old site's "Need IT Support?" banner
   (.support-cta): circle icon badge + text + white pill button in one
   row, pulled via computed-style inspection of the live old site. */
.cross-platform-panel {
  background: var(--wg-navy);
  border-radius: 0.75rem;
  padding: 1.5rem 2rem;
}
@media (min-width: 768px) { .cross-platform-panel { padding: 1.75rem 2.5rem; } }
.cp-cta-content {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
}
@media (min-width: 768px) { .cp-cta-content { flex-wrap: nowrap; gap: 2.5rem; } }
.cp-cta-icon {
  flex: none;
  width: 4.5rem;
  height: 4.5rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.15);
  border: 2px solid rgba(255, 255, 255, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  color: #fff;
  font-size: 2.5rem;
}
.cp-cta-text { flex: 1 1 320px; min-width: 0; }
.cp-cta-heading {
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: 1.5rem;
  color: var(--wg-offwhite);
  margin: 0.25rem 0 0.25rem;
}
.cp-cta-body { color: rgba(230, 231, 226, 0.85); font-size: 1.05rem; margin: 0; }
.cp-cta-action { flex: none; width: 100%; }
@media (min-width: 768px) { .cp-cta-action { width: auto; } }
.btn-cp-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  width: 100%;
  background: #fff;
  color: var(--wg-darkgreen);
  font-weight: 700;
  font-size: 1.05rem;
  border-radius: 50px;
  padding: 0.85rem 1.75rem;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 150ms ease;
  /* Big-red-button treatment: a slow breathing scale + an outward ring
     of the button's own color, so it reads as "press me" without
     actually being red (this sits on the navy cross-platform panel, so
     white/offwhite carries the effect instead). Paused on hover/focus so
     it holds still the moment someone is actually about to click it. */
  animation: wg-cta-pulse 2.2s ease-in-out infinite;
}
@media (min-width: 768px) { .btn-cp-cta { width: auto; } }
.btn-cp-cta:hover, .btn-cp-cta:focus-visible {
  background: var(--wg-offwhite);
  color: var(--wg-darkgreen);
  animation-play-state: paused;
}
@keyframes wg-cta-pulse {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.55);
  }
  50% {
    transform: scale(1.045);
    box-shadow: 0 0 0 10px rgba(255, 255, 255, 0);
  }
}

/* ── SLA surfacing ────────────────────────────────────── */
/* The response-time table moved out of a tooltip and onto /pricing/#sla as a
   real section; it reuses .sla-tooltip-table, which was sized for a tooltip
   on a dark navy bubble (see .tooltip.sla-tooltip above) — near-white
   borders/body text that read fine on that navy background but are
   effectively invisible on this section's light background, which is why
   the times themselves didn't show up here. Re-themed dark-on-light for
   this context; the tooltip usage elsewhere is untouched. */
.sla-table-wrap { overflow-x: auto; }
.sla-table-wrap .sla-tooltip-table { width: 100%; min-width: 34rem; }
.sla-table-wrap .sla-tooltip-table th,
.sla-table-wrap .sla-tooltip-table td { border-bottom-color: rgba(3, 40, 65, 0.12); }
.sla-table-wrap .sla-tooltip-table thead th { color: var(--wg-primary-deep); border-bottom-color: rgba(151, 186, 102, 0.4); }
.sla-table-wrap .sla-tooltip-table td:not(:first-child) { color: var(--wg-navy); }
.sla-table-wrap .sla-tooltip-note { margin: 1.25rem 0 1.5rem; color: rgba(3, 40, 65, 0.7); border-top-color: rgba(3, 40, 65, 0.12); }

/* The static section turns the three rows into color-coded tier "cards"
   instead of plain striped table rows — border-spacing (not collapse)
   is what makes a <table> render with a real gap between rows, so each
   tr can carry its own tinted background and rounded ends. The tooltip
   keeps border-collapse from .sla-tooltip-table's base rule untouched. */
.sla-table-wrap .sla-tooltip-table {
  border-collapse: separate;
  border-spacing: 0 0.75rem;
  margin-top: -0.75rem;
}
.sla-table-wrap .sla-tooltip-table thead th { padding-bottom: 0.5rem; }
.sla-table-wrap .sla-tooltip-table tbody tr:nth-child(even) td { background: none; }
.sla-table-wrap .sla-tooltip-table tbody td {
  padding: 1.25rem 1.5rem;
  border-bottom: 0;
  vertical-align: middle;
}
.sla-table-wrap .sla-row-p1 td { background: rgba(216, 172, 47, 0.1); }
.sla-table-wrap .sla-row-p2 td { background: rgba(151, 186, 102, 0.16); }
.sla-table-wrap .sla-row-p3 td { background: rgba(52, 144, 74, 0.1); }
.sla-table-wrap .sla-tooltip-table tbody td:first-child { border-radius: 0.85rem 0 0 0.85rem; }
.sla-table-wrap .sla-tooltip-table tbody td:last-child { border-radius: 0 0.85rem 0.85rem 0; }
.sla-table-wrap .sla-row-p1 td:first-child { border-left: 4px solid var(--wg-gold); }
.sla-table-wrap .sla-row-p2 td:first-child { border-left: 4px solid var(--wg-lightgreen); }
.sla-table-wrap .sla-row-p3 td:first-child { border-left: 4px solid var(--wg-accent-green); }

/* Bigger tier chip, since each row now has the room a proper card affords
   instead of squeezing next to a bootstrap-table label. */
.sla-table-wrap .sla-tier-badge {
  display: block;
  width: 2.25rem;
  height: 2.25rem;
  line-height: 2.25rem;
  min-width: 0;
  margin: 0 0 0.5rem;
  border-radius: 50%;
  font-family: var(--wg-font-display);
  font-size: 0.8125rem;
}
.sla-table-wrap .sla-tooltip-table tbody td:first-child { font-weight: 700; color: var(--wg-navy); }

/* Response times as stats — a small muted label over a bold display-font
   number, the way the rest of the site shows a stat (see .tile-arrow's
   sibling stat blocks on case-study cards) instead of plain sentence
   fragments in a table cell. The colon .sla-time-label normally adds
   (for the tooltip's compact prose) isn't needed once label and value
   are visually separated like this. */
.sla-table-wrap .sla-time:not(:last-child) { margin-bottom: 0.625rem; }
.sla-table-wrap .sla-time-label::after { content: ""; }
.sla-table-wrap .sla-time-label {
  display: block;
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: rgba(3, 40, 65, 0.55);
}
.sla-table-wrap .sla-time-val {
  display: block;
  font-family: var(--wg-font-display);
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--wg-navy);
}
@media (max-width: 575.98px) {
  /* The desktop -0.75rem margin-top exists to cancel the gap
     border-spacing puts above the first row (see above); it no longer
     applies once display:table is gone below, and left uncancelled it
     pulled the first (P1) card up tight against the intro paragraph
     while P2/P3 kept their normal gap — the "inconsistent start". */
  .sla-table-wrap .sla-tooltip-table { margin-top: 0; }
  .sla-table-wrap .sla-tooltip-table thead { display: none; }
  .sla-table-wrap .sla-tooltip-table,
  .sla-table-wrap .sla-tooltip-table tbody,
  .sla-table-wrap .sla-tooltip-table tr,
  .sla-table-wrap .sla-tooltip-table td { display: block; width: auto; min-width: 0; }
  .sla-table-wrap .sla-tooltip-table tr { margin-bottom: 0.75rem; }
  .sla-table-wrap .sla-tooltip-table tbody td:first-child,
  .sla-table-wrap .sla-tooltip-table tbody td:last-child { border-radius: 0.85rem 0.85rem 0 0; }
  .sla-table-wrap .sla-tooltip-table tbody td + td { border-radius: 0; }
  .sla-table-wrap .sla-tooltip-table tbody td:last-child { border-radius: 0 0 0.85rem 0.85rem; }
  .sla-table-wrap .sla-row-p1 td:first-child { border-left: 4px solid var(--wg-gold); border-top: 4px solid var(--wg-gold); }
  .sla-table-wrap .sla-row-p2 td:first-child { border-left: 4px solid var(--wg-lightgreen); border-top: 4px solid var(--wg-lightgreen); }
  .sla-table-wrap .sla-row-p3 td:first-child { border-left: 4px solid var(--wg-accent-green); border-top: 4px solid var(--wg-accent-green); }
  .sla-table-wrap .sla-tooltip-table tbody td { padding: 1rem 1.25rem; }
  .sla-table-wrap .sla-tier-badge { display: inline-flex; align-items: center; justify-content: center; margin: 0 0.5rem 0 0; }
  .sla-table-wrap .sla-tooltip-table tbody td:first-child { display: flex; align-items: center; }
  /* The thead is hidden on mobile (each row is its own stacked card), so
     the Business/After hours distinction the header normally carries
     would otherwise disappear — reinject it per cell from data-label. */
  .sla-table-wrap .sla-tooltip-table td[data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 0.5rem;
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--wg-primary-deep);
  }
}

/* SLA line under the CTA-band buttons and the hero action pair. */
.cta-sla { max-width: 44rem; }
.cta-link-inline { color: inherit; text-decoration: underline; }
.hero-cta-sla { max-width: 44rem; }

/* Trust-strip entry that links through to the full SLA terms. */
.trust-strip-link { color: inherit; text-decoration: none; }
.trust-strip-link:hover, .trust-strip-link:focus { text-decoration: underline; }

/* Case-study eyebrow that links through to its industry page. Keeps the
   eyebrow's size/letterspacing, adds an affordance that it is a link. */
.eyebrow.eyebrow-link {
  display: inline-block;
  color: var(--wg-darkgreen);
  text-decoration: none;
  border-bottom: 1px solid rgba(3, 40, 65, 0.25);
}
.eyebrow.eyebrow-link:hover,
.eyebrow.eyebrow-link:focus-visible { border-bottom-color: currentColor; }

/* ── Mac Support page (/mac-support/) — Apple-flavored treatment ────────
   Scoped entirely to .mac-* classes and descendants of .mac-hero, so it
   never touches .tile, .btn, .section-white, etc. used by every other
   page. Same brand fonts/colors as the rest of the site, but leans into
   what actually reads as "Apple" without them: a glass badge and pill
   buttons in the hero, squircle icon tiles instead of plain cards, and a
   soft two-tone mesh behind the feature grid instead of a flat fill. */
.mac-badge {
  display: inline-flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(12px) saturate(160%);
  -webkit-backdrop-filter: blur(12px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.65);
  border-radius: 999px;
  padding: 0.625rem 1.375rem;
  box-shadow: 0 8px 24px rgba(3, 40, 65, 0.14);
}
.mac-badge img { display: block; height: 28px; width: auto; }

/* Pill, frosted "liquid glass" CTAs, only inside this page's hero — the
   shared .btn styling (solid fill, square-ish corners) is untouched
   everywhere else it's used. A translucent tinted fill (not solid) plus a
   blur is what actually reads as glass rather than just "a rounded
   button"; the inset top highlight is the specular sheen, the bottom
   inset shades it back to the base tint so it still reads as a lens
   rather than a flat wash. */
.mac-hero .hero-cta .btn {
  position: relative;
  border-radius: 999px;
  border-width: 1px;
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.5),
    inset 0 -8px 12px -8px rgba(3, 40, 65, 0.25),
    0 10px 28px -8px rgba(3, 40, 65, 0.35);
  transition: transform 160ms ease, box-shadow 160ms ease, background-color 160ms ease, border-color 160ms ease;
}
.mac-hero .hero-cta .btn:hover,
.mac-hero .hero-cta .btn:focus-visible {
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.6),
    inset 0 -8px 12px -8px rgba(3, 40, 65, 0.3),
    0 14px 32px -8px rgba(3, 40, 65, 0.4);
}
.mac-hero .hero-cta .btn:active { transform: translateY(0); }
.mac-hero .hero-cta .btn-brand {
  background-color: rgba(38, 77, 10, 0.55);
  border-color: rgba(255, 255, 255, 0.4);
}
.mac-hero .hero-cta .btn-brand:hover,
.mac-hero .hero-cta .btn-brand:focus-visible {
  background-color: rgba(32, 45, 16, 0.6);
  border-color: rgba(255, 255, 255, 0.5);
}
.mac-hero .hero-cta .btn-outline-navy {
  background-color: rgba(255, 255, 255, 0.35);
  border-color: rgba(255, 255, 255, 0.6);
  color: var(--wg-navy);
}
.mac-hero .hero-cta .btn-outline-navy:hover,
.mac-hero .hero-cta .btn-outline-navy:focus-visible {
  background-color: rgba(255, 255, 255, 0.55);
  border-color: rgba(255, 255, 255, 0.75);
  color: var(--wg-navy);
}

/* Soft mesh instead of a flat white fill: two large, low-opacity radial
   washes in the brand's own gold/navy, the way an Apple product page
   uses a barely-there gradient behind a feature grid instead of solid
   white. Fixed decorative layer, so it never affects layout/scroll.
   Shared by every section on this page that should read as one
   continuous glass "table" rather than separate flat-white blocks —
   the feature grid and "Who this fits" both carry it, with no border
   between them, so the glass cards/panels look like they're floating
   over one atmosphere instead of two stacked white boxes. */
.mac-mesh-bg {
  position: relative;
  overflow: hidden;
  background: #fff;
}
.mac-mesh-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  /* Negative, not 0: this class is applied both to sections with a
     separate child .wg-container (feature grid, "Who this fits") and
     directly to wg_faq()'s own section (which has no such child, since
     the section itself is the .wg-container). A negative z-index paints
     behind ALL of this element's normal-flow content either way, so it
     works for both without needing the content to opt into z-index:1. */
  z-index: -1;
  background:
    radial-gradient(55% 55% at 12% 0%, rgba(216, 172, 47, 0.10), transparent 60%),
    radial-gradient(50% 60% at 100% 25%, rgba(3, 40, 65, 0.07), transparent 65%);
  pointer-events: none;
}

.mac-feature-card {
  height: 100%;
  padding: 2rem;
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: 1.5rem;
  box-shadow: 0 24px 48px -28px rgba(3, 40, 65, 0.22), 0 2px 8px rgba(3, 40, 65, 0.06);
  transition: transform 220ms ease, box-shadow 220ms ease, opacity 500ms ease, transform 500ms ease;
}
.mac-feature-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 32px 56px -24px rgba(3, 40, 65, 0.28), 0 4px 10px rgba(3, 40, 65, 0.08);
}
/* Staggered entrance: each card sets --mac-delay inline, so the four
   tiles settle in one after another instead of all at once. */
.reveal-ready .mac-feature-card[data-reveal] { transition-delay: var(--mac-delay, 0ms); }

.mac-feature-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  color: var(--wg-primary-deep);
  font-size: 2.25rem;
}
/* Addigy's mark sits in the same badge as the other three cards' icons —
   inline SVG with fill="currentColor" (not an <img>, which can't inherit
   CSS color) so it renders in the exact same navy-green as the Apple,
   Microsoft, and fingerprint glyphs beside it, not its own brand cyan. */
.mac-feature-icon-img {
  width: 2.5rem;
  height: auto;
  color: var(--wg-primary-deep);
}

/* "Who this fits" checklist: the same frosted material as the feature
   cards above (blur + translucency, not a flat tint), so the two
   sections read as one continuous glass surface, not a card followed by
   a plain tinted box. */
.mac-fits-panel {
  background: rgba(255, 255, 255, 0.6);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: 1.5rem;
  padding: 1.75rem 2rem;
  box-shadow: 0 24px 48px -28px rgba(3, 40, 65, 0.18), 0 2px 8px rgba(3, 40, 65, 0.05);
}
@media (max-width: 575.98px) {
  .mac-fits-panel { padding: 1.5rem; }
}

/* FAQ: the accordion becomes one glass "grouped list" card (the
   visionOS/iOS list-with-inset-material look) instead of plain rows on
   the page background. Each question is still its own accordion-item,
   just re-skinned as a glass row inside a single rounded container. */
.mac-glass-faq .accordion {
  background: rgba(255, 255, 255, 0.6);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: 1.5rem;
  box-shadow: 0 24px 48px -28px rgba(3, 40, 65, 0.18), 0 2px 8px rgba(3, 40, 65, 0.05);
  padding: 0 1.5rem;
  overflow: hidden;
}
.mac-glass-faq .accordion-item { background: transparent; border: 0; border-top: 1px solid rgba(3, 40, 65, 0.08); }
.mac-glass-faq .accordion-item:first-child { border-top: 0; }
.mac-glass-faq .accordion-button { padding: 1.25rem 0; }
.mac-glass-faq .accordion-body { padding: 0 0 1.25rem; }

/* wg_next_steps()'s tile, re-skinned to the same glass material via the
   tileClass option rather than forking the component. */
.mac-glass-tile {
  background: rgba(255, 255, 255, 0.65) !important;
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.8) !important;
  box-shadow: 0 24px 48px -28px rgba(3, 40, 65, 0.18), 0 2px 8px rgba(3, 40, 65, 0.05);
}

/* Closing CTA band: same liquid-glass button language as the hero, this
   time a light glass on the dark navy fill instead of buttons floating
   on a photo. */
.mac-glass-cta .btn-on-dark {
  background-color: rgba(255, 255, 255, 0.14);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border-color: rgba(255, 255, 255, 0.35);
  color: var(--wg-offwhite);
  border-radius: 999px;
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.25), 0 10px 28px -8px rgba(0, 0, 0, 0.35);
  transition: transform 160ms ease, box-shadow 160ms ease, background-color 160ms ease;
}
.mac-glass-cta .btn-on-dark:hover,
.mac-glass-cta .btn-on-dark:focus-visible {
  background-color: rgba(255, 255, 255, 0.22);
  border-color: rgba(255, 255, 255, 0.5);
  color: #fff;
  transform: translateY(-2px);
}
