/* ==================================================================
   C-TECH SOLUTIONS — CORE STYLESHEET

   Structure:
     1.  Design tokens
     2.  Base / reset-ish
     3.  Accessibility
     4.  Typography scale
     5.  Spacing scale
     6.  Backgrounds & section bands
     7.  Buttons
     8.  Icons
     9.  Header / navigation
     10. Hero
     11. Section titles
     12. Text blocks & content boxes
     13. Cards (services, features, tech)
     14. Testimonials
     15. Forms / project inquiry
     16. FAQ, breadcrumb, work
     17. Footer
     18. Motion
   ================================================================== */


/* ==================================================================
   1. DESIGN TOKENS

   One purple family, one neutral family. Every colour on the public
   site resolves to something below, so the brand stays consistent
   without a second palette creeping in.
   ================================================================== */

:root {
  /* Brand purple — 600 is the established C-Tech purple. */
  --brand-700: #372c7a;
  --brand-600: #473996;
  --brand-500: #5744b6;
  --brand-100: #e6e0fa;
  --brand-050: #f1eefc;
  --brand-025: #f8f6ff;
  --brand-line: #e3ddf6;

  /* Type ladder. Five tiers, so supporting copy can never drift into a
     one-off size again — the previous pass had fourteen. --fs-body and
     --fs-secondary each step up one notch on desktop, which is the only
     place responsive type sizing happens outside the s-* clamps. */
  --fs-body:      1.0625rem;  /* 17px — default reading size           */
  --fs-body-lg:   1.125rem;   /* 18px — leads, testimonial quotes      */
  --fs-secondary: 1.0625rem;  /* 17px — supporting copy, hints, footer */
  --fs-meta:      1rem;       /* 16px — captions, counters, tags       */
  --fs-eyebrow:   .8125rem;   /* 13px — uppercase labels               */

  /* One card padding value, so every card in the system matches. */
  --pad-card: 30px;

  /* Neutrals */
  --ink-900: #23283a;   /* headings */
  --ink-700: #3b4356;
  --ink-600: #4e5566;   /* body copy */
  --ink-500: #626a7d;   /* metadata, captions — 4.61:1 on the bg--04
                          wash, 5.42:1 on white. #6a7285 cleared AA on
                          white but only reached 4.10:1 on the wash. */
  --line: #e5e7ef;
  --surface: #ffffff;
  --danger: #c93c3c;   /* AA on white for error text */

  /* Elevation. Deliberately shallow — this is a consultancy, not a
     dashboard demo. */
  --shadow-xs: 0 1px 2px rgba(35, 40, 58, .05);
  --shadow-sm: 0 2px 8px rgba(35, 40, 58, .05);
  --shadow-md: 0 6px 22px rgba(35, 40, 58, .07);
  --shadow-lg: 0 16px 44px rgba(35, 40, 58, .10);

  --ease: cubic-bezier(.22, .61, .36, 1);

  /* Vertical rhythm. --section-y is the padding on ONE side of a
     section, so the gap between two neighbours is twice it. Sections
     that carry their own background band override it (see §6) so the
     band has presence rather than looking cramped.

     Desktop junctions: plain-to-plain 96px, plain-to-band 108px,
     band-to-band 120px — every one inside the intended 80-120px range,
     against the 200px the page used to leave between every section. */
  --section-y: 48px;
  --section-y-band: 60px;

  /* The fixed header overlays the top of the page, so the breadcrumb
     and the home hero both measure their clearance against this. The
     nav is single-line at every width where it is shown, so one value
     covers all of them (measured 114px at 1000-1920). */
  --header-h: 108px;
}

/* menu.css swaps the desktop nav for the off-canvas menu at
   max-width: 992px, so the mobile clearance has to reach 992 too or the
   single pixel at exactly 992 gets desktop clearance under a mobile
   header. The old 176px override for 992-1199 assumed the nav wrapped
   onto a second line there; it does not (it is one line down to 993px),
   and it was leaving 82px of dead space above the breadcrumb instead of
   38px on every inner page. */
@media (max-width: 992px) {
  :root { --header-h: 80px; }
}

@media (max-width: 991px) {
  :root { --section-y: 40px; --section-y-band: 48px; }
}

@media (max-width: 767px) {
  :root { --section-y: 34px; --section-y-band: 40px; }
}


/* ==================================================================
   2. BASE
   ================================================================== */

/* One root size at every breakpoint. The old stylesheet moved this
   between 87.5% and 115.6% per breakpoint, which silently rescaled
   every rem-based padding, icon and heading and is why the page read
   as "zoomed out" on tablet. The type scale in §4 handles responsive
   sizing explicitly instead. */
html {
  font-size: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

body {
  overflow-x: clip; /* modern, safer than hidden */
  font-family: 'Plus Jakarta Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-size: var(--fs-body);
  color: var(--ink-600);
  line-height: 1.65;
  font-weight: 400;
  background-color: var(--surface);
}

@media (min-width: 1200px) {
  :root {
    --fs-body:      1.125rem;    /* 18px */
    --fs-body-lg:   1.1875rem;   /* 19px */
    /* --fs-secondary and --fs-meta stay flat across breakpoints; they
       already read comfortably at 17 and 16 on a large screen. */
  }
}

h1, h2, h3, h4, h5, h6,
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
  color: var(--ink-900);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-bottom: 0;
}

/* Only affects the last line of a paragraph, pulling a word down to
   avoid an orphan. Ignored by engines that do not support it, and it
   does not rebalance earlier lines, so no approved wrap point moves.
   Deliberately not using text-wrap: balance on headings, which would
   change existing headline breaks. */
p { font-size: inherit; text-wrap: pretty; }

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

a {
  color: var(--brand-600);
  text-decoration: none;
  transition: color 200ms var(--ease), background-color 200ms var(--ease),
              border-color 200ms var(--ease);
}

a:hover { color: var(--brand-500); }

::selection { background-color: var(--brand-600); color: #fff; }
::-moz-selection { background-color: var(--brand-600); color: #fff; }

/* Clips the horizontal bleed some template sections still have. It has to
   be `clip` rather than `hidden`: `hidden` makes this a scroll container,
   which silently disables `position: sticky` for everything inside it —
   that is what stopped the privacy policy's contents sidebar from
   sticking. `clip` does the same clipping without the scroll container.
   Same reasoning as `overflow-x: clip` on body above. */
#page { overflow-x: clip; }

.rel,
section,
.container {
  position: relative !important;
  z-index: 3;
}

hr.divider {
  width: 100%;
  height: 1px;
  background-color: transparent;
  background-image: linear-gradient(90deg, rgba(206,211,246,0) 0, #bbb 38%, #bbb 64%, rgba(206,211,246,0) 99%);
  opacity: .4;
  border: none;
  margin: 0;
}


/* ==================================================================
   3. ACCESSIBILITY

   :focus-visible only fires for keyboard/assistive navigation, so
   mouse users never see an outline. This replaces the blanket
   `outline: none` that removed the focus indicator site-wide.
   ================================================================== */

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--brand-600);
  outline-offset: 2px;
  border-radius: 3px;
}

/* On dark or brand-coloured backgrounds the purple outline disappears.

   footer.bg--02 used to be in this list, but this footer is the light
   variant (bg-02.jpg is a pale wash carrying dark text), so a white
   ring on it was effectively invisible to keyboard users. It now takes
   the default purple ring above. */
.bg--theme a:focus-visible,
.bg--theme button:focus-visible,
.btn--theme:focus-visible {
  outline-color: #ffffff;
  box-shadow: 0 0 0 5px rgba(71, 57, 150, .55);
}

/* Skip link: off-screen until it receives keyboard focus. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100000;
  padding: 12px 20px;
  background: var(--brand-600);
  color: #fff !important;
  font-weight: 600;
  border-radius: 0 0 4px 0;
}

.skip-link:focus { left: 0; }


/* ==================================================================
   4. TYPOGRAPHY SCALE

   The s-* utilities are the site's type scale. They are now fluid, so
   each one lands at a deliberate size on mobile, tablet and desktop
   instead of being re-declared in eight breakpoint blocks with
   rem values tuned against a moving root size.

   clamp(min, preferred, max): min holds at ~360px, max is reached at
   ~1400px, and the vw term interpolates between them.
   ================================================================== */

/* Display / H1 */
.s-60 { font-size: clamp(2.125rem, 1.05rem + 3.4vw, 3.5rem); line-height: 1.12; }

/* Major section heading */
.s-52 { font-size: clamp(1.9375rem, 1.15rem + 2.5vw, 2.875rem); line-height: 1.16; }

/* Standard section heading */
.s-46 { font-size: clamp(1.75rem, 1.15rem + 1.9vw, 2.5rem); line-height: 1.2; }
.s-44 { font-size: clamp(1.6875rem, 1.13rem + 1.75vw, 2.375rem); line-height: 1.2; }
.s-42 { font-size: clamp(1.625rem, 1.11rem + 1.6vw, 2.25rem); line-height: 1.2; }

/* Sub-heading / lead-in */
.s-26 { font-size: clamp(1.1875rem, 1.05rem + .42vw, 1.4375rem); line-height: 1.4; }
.s-24 { font-size: clamp(1.1875rem, 1.06rem + .36vw, 1.375rem); line-height: 1.42; }
.s-22 { font-size: clamp(1.125rem, 1.03rem + .3vw, 1.3125rem); line-height: 1.42; }
.s-20 { font-size: clamp(1.0625rem, 1rem + .25vw, 1.1875rem); line-height: 1.55; }

/* Body-adjacent */
.s-19 { font-size: clamp(1.0625rem, 1rem + .18vw, 1.125rem); }
.s-18 { font-size: clamp(1.0625rem, 1rem + .18vw, 1.125rem); }
.s-17 { font-size: 1.0625rem; }
.s-12 { font-size: .875rem; }

p.p-lg { font-size: clamp(1.0625rem, 1rem + .25vw, 1.1875rem); }
p.p-sm { font-size: 1rem; }

.w-500 { font-weight: 500; }
.w-700 { font-weight: 700; }

/* Jakarta needs slightly tighter leading on display sizes than the
   1.65 body value. */
.font--jakarta h1,
.font--jakarta h2,
.font--jakarta h3,
.font--jakarta h4,
.font--jakarta h5,
.font--jakarta h6 {
  font-family: 'Plus Jakarta Sans', sans-serif;
  line-height: 1.3;
}

.font--jakarta h1,
.font--jakarta h2 { line-height: 1.16; }

/* Eyebrow / preheading */
.section-id {
  display: block;
  font-size: var(--fs-eyebrow);
  line-height: 1;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--brand-600);
  margin-bottom: 20px;
}

.font--jakarta .section-id { font-family: 'Plus Jakarta Sans', sans-serif; }

/* Colour helpers */
.color--white,
.color--white h1, .color--white h2, .color--white h3,
.color--white h4, .color--white h5, .color--white h6,
.color--white p, .color--white a, .color--white li,
.color--white i, .color--white span { color: #fff; }

.color--black,
.color--black h1, .color--black h2, .color--black h3,
.color--black h4, .color--black h5, .color--black h6,
.color--black p, .color--black a, .color--black li,
.color--black i, .color--black span { color: var(--ink-900); }

.color--grey,
.color--grey h1, .color--grey h2, .color--grey h3,
.color--grey h4, .color--grey h5, .color--grey h6,
.color--grey p, .color--grey a, .color--grey li,
.color--grey i, .color--grey span,
.color--white .color--grey { color: var(--ink-500); }

.color--theme,
.color--theme h1, .color--theme h2, .color--theme h3,
.color--theme h4, .color--theme h5, .color--theme h6,
.color--theme p, .color--theme a, .color--theme li,
.color--theme i, .color--theme span,
.color--white .color--theme { color: var(--brand-600) !important; }


/* ==================================================================
   5. SPACING SCALE

   The py-* / pt-* / pb-* class names are kept so no markup had to
   change, but they now resolve through --section-y rather than being
   hard-coded and then overridden per breakpoint.
   ================================================================== */

.py-100 { padding-top: var(--section-y); padding-bottom: var(--section-y); }
.py-80  { padding-top: calc(var(--section-y) * .9); padding-bottom: calc(var(--section-y) * .9); }
.py-60  { padding-top: calc(var(--section-y) * .78); padding-bottom: calc(var(--section-y) * .78); }

.pt-90  { padding-top: var(--section-y); }
.pt-80  { padding-top: calc(var(--section-y) * .9); }
.pt-40  { padding-top: calc(var(--section-y) * .55); }
.pt-20  { padding-top: 18px; }

.pb-100 { padding-bottom: var(--section-y); }
.pb-80  { padding-bottom: calc(var(--section-y) * .9); }
.pb-60  { padding-bottom: calc(var(--section-y) * .78); }
.pb-50  { padding-bottom: calc(var(--section-y) * .66); }
.pb-40  { padding-bottom: calc(var(--section-y) * .55); }

.mt-10 { margin-top: 10px; }
.mt-25 { margin-top: 22px; }
.mt-30 { margin-top: 26px; }
.mt-40 { margin-top: 32px; }
.mt-50 { margin-top: 38px; }
.mt-60 { margin-top: 42px; }

.mb-20 { margin-bottom: 20px; }
.mb-30 { margin-bottom: 26px; }
.mb-40 { margin-bottom: 32px; }
.mb-50 { margin-bottom: 38px; }
.mb-60 { margin-bottom: 42px; }
.mb-70 { margin-bottom: 44px; }
.mb-80 { margin-bottom: 48px; }

.r-04 { border-radius: 6px; }
.r-08 { border-radius: 10px; }
.r-12 { border-radius: 14px; }
.r-16 { border-radius: 18px; }


/* ==================================================================
   6. BACKGROUNDS & SECTION BANDS

   The soft purple decoration is brand, but repeating the identical
   photographic wash on every second section flattens the page. So:

     .bg--04         the full decorative wash — reserved for the two
                     sections that carry the most weight
     .section--tint  a flat purple tint, no image
     .section--panel white, framed by hairlines

   Same palette, three intensities, so the eye can tell sections apart.
   ================================================================== */

.bg--white-100 { background-color: #fff; }

.gr--whitesmoke {
  background-image: linear-gradient(180deg, var(--brand-025) 0%, rgba(248, 246, 255, 0) 100%);
}

.shape--white-400:after { background-color: #f4f4f9; }

.bg--02, .bg--04 {
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
}

.bg--fixed {
  width: 100%;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
  background-attachment: scroll !important;
}

.bg--02 { background-image: url(../images/bg-02.jpg); }
.bg--04 { background-image: url(../images/bg-04.jpg); }

/* Flat tint: the same purple, no texture. */
.section--tint {
  background-color: var(--brand-025);
  border-top: 1px solid var(--brand-line);
  border-bottom: 1px solid var(--brand-line);
}

/* Slightly stronger, with a soft top-down fade so consecutive bands
   never look like the same block repeated. */
.section--tint-deep {
  background-image: linear-gradient(180deg, var(--brand-050) 0%, var(--brand-025) 100%);
  border-top: 1px solid var(--brand-line);
  border-bottom: 1px solid var(--brand-line);
}

/* White, but framed, so it reads as a deliberate section rather than
   an absence of one. */
.section--panel {
  background-color: var(--surface);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

/* Any section carrying its own background band gets more internal
   room than a plain white one. */
.bg--04, .bg--02,
.section--tint,
.section--tint-deep,
.section--panel { --section-y: var(--section-y-band); }

.bg--theme { background-color: var(--brand-600); }


/* ==================================================================
   7. BUTTONS
   ================================================================== */

.btn {
  display: inline-block;
  background-color: transparent;
  font-size: 1.0625rem;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.005em;
  padding: 0.95rem 1.85rem;
  border: 2px solid transparent;
  border-radius: 6px;
  transition: transform 180ms var(--ease), box-shadow 220ms var(--ease),
              background-color 220ms var(--ease), border-color 220ms var(--ease),
              color 220ms var(--ease);
}

.btn--lg {
  font-size: 1.125rem;
  padding: 1.075rem 2.15rem;
}

.btn--theme,
.hover--theme--dark:hover {
  color: #fff !important;
  border-color: var(--brand-600) !important;
  background-color: var(--brand-600) !important;
}

.btn--theme { box-shadow: 0 6px 18px rgba(71, 57, 150, .22); }

.hover--theme:hover,
.white-scroll .scroll .hover--theme:hover {
  color: #fff !important;
  border-color: var(--brand-500) !important;
  background-color: var(--brand-500) !important;
}

/* Micro-interaction: a 1px lift, nothing more. */
.btn--theme:hover { transform: translateY(-1px); box-shadow: 0 10px 26px rgba(71, 57, 150, .28); }
.btn--theme:active { transform: translateY(0); box-shadow: 0 4px 12px rgba(71, 57, 150, .22); }

/* The border is the whole affordance on this tier, and at #cfd3de it
   scored 1.27:1 against the purple CTA wash and 1.43:1 on the hero
   gradient — under the 3:1 WCAG 1.4.11 asks of a UI boundary. #7f879f
   clears 3:1 on the wash, the gradient and plain white, and still reads
   clearly below a filled, shadowed primary. */
.btn--tra-black {
  color: var(--ink-900) !important;
  background-color: transparent !important;
  border-color: #7f879f !important;
}

/* All three properties are declared together on purpose. The earlier
   .hover--theme--dark:hover rule forces color:#fff !important, and with
   only background and border set here the resolved hover was white text
   on a 4% dark tint over a light background — 1.26:1. A purple-tinted
   fill with purple text and a purple border keeps the outlined identity
   and stays readable. */
.btn--tra-black:hover {
  color: var(--brand-700) !important;
  background-color: var(--brand-050) !important;
  border-color: var(--brand-600) !important;
}

/* --- Tier 2: soft.
   A real button that is unmistakably subordinate to the filled primary.
   For useful section actions that are not the page's conversion goal. */
.btn--soft {
  color: var(--brand-600) !important;
  background-color: var(--brand-050) !important;
  border-color: var(--brand-100) !important;
  box-shadow: none;
}

.btn--soft:hover {
  color: var(--brand-700) !important;
  background-color: var(--brand-100) !important;
  border-color: var(--brand-line) !important;
}

/* Secondary CTA used only beneath the How We Work process steps. */
.btn--process-secondary {
  color: var(--brand-600) !important;
  background-color: var(--brand-025) !important;
  border-color: var(--brand-500) !important;
  box-shadow: none;
}

.btn--process-secondary:hover {
  color: var(--brand-700) !important;
  background-color: var(--brand-100) !important;
  border-color: var(--brand-700) !important;
  box-shadow: none;
}

/* --- Tier 3: navigational text link.
   Read-more actions. Deliberately not a button, so it cannot compete
   with a conversion CTA sharing the same viewport. Named .link-cta
   because Bootstrap already defines .btn-link. --- */
.link-cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border: 0;
  background: none;
  font-size: var(--fs-body);
  font-weight: 600;
  line-height: 1.4;
  color: var(--brand-600);
}

.link-cta:after {
  content: "";
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-top: 2px solid currentColor;
  border-right: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 200ms var(--ease);
}

.link-cta:hover {
  color: var(--brand-500);
  text-decoration: underline;
  text-underline-offset: 5px;
}

.link-cta:hover:after { transform: rotate(45deg) translate(2px, -2px); }

/* The 8px vertical padding means a default outline sits a long way off
   the text, so the ring is pulled back in. */
.link-cta:focus-visible {
  outline: 3px solid var(--brand-600);
  outline-offset: 0;
  border-radius: 4px;
}

/* Links inside a sentence. Underlined everywhere so a text link never
   depends on colour alone to be recognisable (WCAG 1.4.1). */
.txt-block p a,
.section-title p a,
.hero-trust-desc a,
.faq-answer p a,
.review-txt p a {
  color: var(--brand-600);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.txt-block p a:hover,
.section-title p a:hover,
.hero-trust-desc a:hover,
.faq-answer p a:hover,
.review-txt p a:hover {
  color: var(--brand-500);
  text-decoration-thickness: 2px;
}

/* Contact affordances in the inquiry column: a leading icon rather than
   a trailing chevron, but the same colour, weight and timing. */
.inquiry-direct-links a { font-size: var(--fs-body); }

/* Contact page: the links follow the column heading directly, and the
   reason list follows them. */
#contacts-1 .inquiry-direct-links { margin-top: 18px; flex-direction: column; gap: 12px; }

/* A clearer break between how to reach us and what to expect. */
#contacts-1 .inquiry-reasons { margin-top: 40px; }

/* Side by side, the left column starts at the column edge while the form
   heading starts inside the card padding, so the two headings sat ~40px
   apart. Offsetting the left column by the card padding lines them up and
   the two columns read as one section. Only above 992px, where they are
   actually side by side. */
@media (min-width: 1200px) {
  #contacts-1 .col-lg-5 > .section-title { padding-top: 40px; }
}

@media (min-width: 992px) and (max-width: 1199px) {
  #contacts-1 .col-lg-5 > .section-title { padding-top: 32px; }
}

.txt-block .link-cta { margin-top: 20px; }

.btn:focus { box-shadow: none; }
.btn--tra-black:focus { color: var(--ink-900); box-shadow: none; }

.btns-group {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

/* .section-title centres its own text without carrying .text-center, so
   it needs the flex equivalent stated explicitly. */
.text-center .btns-group,
.section-title .btns-group { justify-content: center; }

.section-title--start .btns-group { justify-content: flex-start; }

.btns-group .btn:first-child { margin-right: 0; }

/* A .btns-group holding text links rather than buttons. Buttons carry
   their own padding, so 14px between them reads as a clear gap; two
   bare .link-cta labels sitting 14px apart read as one wrapped
   sentence, so the column gap opens up while the row gap stays tight
   for when they stack. */
.btns-group.link-row { gap: 4px 32px; }

/* Small reassurance line that sits under a CTA. */
.btn-note {
  font-size: var(--fs-secondary);
  color: var(--ink-500);
  margin: 12px 0 0;
}


/* ==================================================================
   8. ICONS
   ================================================================== */

.ico-5  [class*="flaticon-"]:before, .ico-5[class*="flaticon-"]:after   { font-size: 8px; }
.ico-10 [class*="flaticon-"]:before, .ico-10 [class*="flaticon-"]:after { font-size: 13px; }
.ico-15 [class*="flaticon-"]:before, .ico-15 [class*="flaticon-"]:after { font-size: 15px; }
.ico-25 [class*="flaticon-"]:before, .ico-25 [class*="flaticon-"]:after { font-size: 25px; }
.ico-50 [class*="flaticon-"]:before, .ico-50 [class*="flaticon-"]:after { font-size: 46px; }
.ico-55 [class*="flaticon-"]:before, .ico-55 [class*="flaticon-"]:after { font-size: 52px; }
.ico-65 [class*="flaticon-"]:before, .ico-65 [class*="flaticon-"]:after { font-size: 58px; }

.shape-ico {
  position: relative;
  display: inline-block;
  margin: 0 auto;
}

.shape-ico span { position: relative; z-index: 2; }
.shape-ico svg  { position: absolute; z-index: 1; }

.ico-50 .shape-ico svg { width: 112px; height: 112px; top: -32px; left: calc(50% - 52px); }
.fbox-11 .ico-50 .shape-ico svg { top: -30px; left: calc(50% - 56px); }
.ico-55 .shape-ico svg { width: 120px; height: 120px; top: -30px; left: calc(50% - 55px); }

.shape-ico.color--theme path { fill: var(--brand-050); }

.ico-65 img { width: 65px; height: 65px; }
.ico-55 img { width: 55px; height: 55px; }
.ico-50 img { width: 50px; height: 50px; }
.ico-25 img { width: 25px; height: 25px; }

.fbox-ico { margin-bottom: 18px; }


/* ==================================================================
   9. HEADER / NAVIGATION
   ================================================================== */

#header {
  width: 100%;
  display: block;
  padding-top: 0;
}

.header-wrapper {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 1030;
}

.wsmainfull {
  width: 100%;
  height: auto;
  z-index: 1031;
  transition: padding 300ms var(--ease), background-color 300ms var(--ease),
              box-shadow 300ms var(--ease);
}

.tra-menu .wsmainfull {
  padding: 22px 0;
  background-color: transparent !important;
  box-shadow: none;
}

/* The header container was locked to 1140px while section containers
   grow to 1320px, so the logo sat ~90px inside the content edge on
   large screens. Match Bootstrap's container widths instead. */
.wsmainwp { max-width: 1140px; }

@media (min-width: 1400px) {
  .wsmainwp { max-width: 1320px; }
}

.desktoplogo img {
  width: auto;
  max-width: inherit;
  max-height: 62px;
  transition: max-height 300ms var(--ease);
}

.scroll .desktoplogo img { max-height: 48px; }

/* --- Top-level links ------------------------------------------------
   Bumped from 15px to 17px and given real breathing room between
   items. The underline indicator is drawn on a pseudo-element so
   hover, focus and the current page all use one mechanism. */
.wsmenu > .wsmenu-list > li > a {
  font-family: 'Plus Jakarta Sans', sans-serif;
  display: block;
  font-size: 1.0625rem;
  line-height: 42px;
  font-weight: 600;
  letter-spacing: -0.005em;
  text-decoration: none;
  margin: 0 2px;
  padding: 8px 16px;
}

.navbar-dark .wsmenu > .wsmenu-list > li > a.h-link { color: var(--ink-700); }

.wsmenu > .wsmenu-list > li > a.h-link {
  position: relative;
}

.wsmenu > .wsmenu-list > li > a.h-link:after {
  content: "";
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 4px;
  height: 2px;
  border-radius: 2px;
  background-color: var(--brand-600);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 220ms var(--ease);
}

.navbar-dark .wsmenu-list > li > a.h-link:hover,
.navbar-dark .wsmenu-list > li:hover > a.h-link {
  color: var(--brand-600) !important;
}

.wsmenu > .wsmenu-list > li > a.h-link:hover:after,
.wsmenu > .wsmenu-list > li:hover > a.h-link:after {
  transform: scaleX(1);
}

/* Current page. Set from header.php via aria-current. */
.navbar-dark .wsmenu-list > li > a.h-link[aria-current="page"] { color: var(--brand-600); }
.wsmenu > .wsmenu-list > li > a.h-link[aria-current="page"]:after { transform: scaleX(1); }

/* The Get Started button is the header's only conversion target, so
   it is the only filled element in the bar. */
.wsmenu > .wsmenu-list > li > a.h-link.last-link { padding: 8px 0; margin: 0; }
.wsmenu > .wsmenu-list > li > a.h-link.last-link:after { display: none; }

.wsmenu > .wsmenu-list > li.reg-fst-link > a { margin-left: 18px; }

.wsmenu > .wsmenu-list > li a.btn {
  font-size: 1rem;
  line-height: 1.2;
  font-weight: 600;
  text-transform: none;
  letter-spacing: -0.005em;
  margin-top: 5px;
  padding: 12px 26px;
  border-radius: 6px;
  margin-left: 25px;
}

.wsmenu > .wsmenu-list > li > a .wsarrow:after {
  border-left: 4px solid rgba(0, 0, 0, 0);
  border-right: 4px solid rgba(0, 0, 0, 0);
  border-top: 4px solid;
  content: "";
  float: right;
  right: 0;
  height: 0;
  margin: 0 0 0 12px;
  position: absolute;
  text-align: right;
  top: 30px;
  width: 0;
}

/* --- Dropdown ------------------------------------------------------ */
.wsmenu > .wsmenu-list > li > ul.sub-menu,
.wsmenu > .wsmenu-list > li > .wsmegamenu {
  width: auto;
  min-width: 268px;
  top: 60px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow-lg);
}

.wsmenu > .wsmenu-list > li > .wsmegamenu { padding: 12px 0; }

.wsmenu > .wsmenu-list > li > ul.sub-menu > li > a {
  background-color: transparent;
  font-family: 'Plus Jakarta Sans', sans-serif;
  color: var(--ink-700);
  font-size: 1rem;
  font-weight: 600;
  padding: 11px 14px;
  border-radius: 8px;
  transition: all 200ms var(--ease);
}

.wsmenu > .wsmenu-list > li > ul.sub-menu > li > a:hover,
.wsmenu > .wsmenu-list.nav-theme > li > ul.sub-menu > li > a:hover {
  background-color: var(--brand-025);
  color: var(--brand-600) !important;
  padding: 11px 14px;
}

.wsmenu > .wsmenu-list > li > .wsmegamenu .title {
  color: var(--ink-500);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: .8125rem;
  line-height: 1;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  margin: 10px 0 15px 13px;
}

/* --- Scrolled state ------------------------------------------------ */
.tra-menu.white-scroll .wsmainfull.scroll {
  padding: 8px 0;
  background-color: rgba(255, 255, 255, .88) !important;
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 4px 20px rgba(35, 40, 58, .06);
}

.tra-menu.navbar-dark.white-scroll .scroll .wsmenu > .wsmenu-list > li > a.h-link {
  color: var(--ink-700);
}

.logo-black { display: block; }


/* ==================================================================
   10. HERO
   ================================================================== */

.hero-section,
.hero-section .container {
  position: relative;
  z-index: 3;
}

.hero-section h2 { margin-bottom: 26px; }
.hero-section p.p-sm { padding: 0 !important; }
.hero-section p.p-lg { margin-bottom: 30px; }

.hero-section p.s-20,
.hero-section p.s-22,
.hero-section p.s-24 { margin-bottom: 30px; }

.hero-section p.p-lg span {
  font-weight: 600;
  letter-spacing: -0.02em;
}

#hero-27 .hero-overlay {
  background-image: url(../images/hero-27.png);
  background-position: top center;
  padding-top: calc(var(--header-h) + 20px);
}

/* The inner-pages variant used to sit 16px tighter under the header.
   Now that every inner page carries its breadcrumb inside the hero,
   that difference showed up as the trail starting at a different height
   per page, so both variants share one clearance. */
#hero-27.hero-inner-pages .hero-overlay { padding-top: calc(var(--header-h) + 44px); }

.hero-27-txt h1,
.hero-27-txt h2 { margin-bottom: 22px !important; }

/* Measure control. A 60px headline across a 960px column reads as a
   banner; capping the line length is most of what makes it read as
   considered rather than stretched. */
.hero-27-txt h1 {
  max-width: 20ch;
  margin-left: auto;
  margin-right: auto;
}

/* .s-19 is included because two hero descriptions are written with it
   rather than .s-20, and without the cap they ran to ~107 characters a
   line while every other hero sat at ~62. */
.hero-27-txt p.s-20,
.hero-27-txt p.s-19 {
  max-width: 62ch;
  margin: 0 auto 30px !important;
  padding: 0;
  color: var(--ink-600);
  line-height: 1.6;
}

.hero-27-txt .btns-group { margin-bottom: 0; }

/* --- CTA reassurance ------------------------------------------------
   The three short promises that used to float loose beside the hero.
   They belong with the buttons, at metadata weight, on one line. */
.hero-assurance {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 6px 18px;
  margin: 24px 0 0;
  padding: 0;
  font-size: var(--fs-secondary);
  color: var(--ink-500);
}

.hero-assurance li {
  display: flex;
  align-items: center;
  gap: 16px;
}

.hero-assurance li + li:before {
  content: "";
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background-color: #c4c8d4;
}

/* --- Trust strip ---------------------------------------------------
   Credibility directly below the hero. Every item is drawn from
   content already on the site or counted from the reviews data — no
   invented figures. */
.hero-trust {
  margin-top: 46px;
  padding-top: 34px;
  border-top: 1px solid var(--brand-line);
}

.hero-trust-list {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 28px 32px;
  margin: 0;
  padding: 0;
  text-align: left;
}

.hero-trust-list > li {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}

.hero-trust-ico {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background-color: var(--brand-050);
  color: var(--brand-600);
}

.hero-trust-ico [class*="flaticon-"]:before { font-size: 16px; line-height: 1; }

.hero-trust-title {
  display: block;
  font-size: var(--fs-secondary);
  font-weight: 700;
  color: var(--ink-900);
  margin: 1px 0 4px;
  line-height: 1.35;
}

.hero-trust-desc {
  display: block;
  font-size: var(--fs-secondary);
  line-height: 1.6;
  color: var(--ink-500);
  margin: 0;
}

.hero-trust-desc a { text-decoration: underline; }

@media (max-width: 991px) {
  .hero-trust { margin-top: 36px; padding-top: 28px; }
  .hero-trust-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
}

@media (max-width: 575px) {
  .hero-trust-list { grid-template-columns: 1fr; gap: 18px; }
  .hero-trust-ico { width: 34px; height: 34px; border-radius: 9px; }
}


/* ==================================================================
   11. SECTION TITLES
   ================================================================== */

.section-title { text-align: center; }

.section-title h2 { margin-bottom: 0; }
.section-title h2.w-700 { letter-spacing: -0.02em; }

/* Centred intros need a measure or they run to 100+ characters on a
   1320px container. */
.section-title p {
  max-width: 68ch;
  margin-left: auto;
  margin-right: auto;
}

.section-title p.p-lg,
.section-title p.s-20 {
  margin-top: 16px;
  margin-bottom: 0;
  padding: 0;
}

.section-title p.s-24 { margin-top: 12px; }

.section-title .btns-group .btn { margin-top: 0; }
.section-title .advantages { margin-top: 20px; }

/* Left-aligned variant, used by the split contact section. */
.section-title--start { text-align: left; }
.section-title--start p { margin-left: 0; margin-right: 0; }


/* ==================================================================
   12. TEXT BLOCKS & CONTENT BOXES
   ================================================================== */

/* A heading and its description are one unit, so the gap between them
   is smaller than the gap from the description to whatever follows. */
.txt-block h2,
.txt-block h3 { margin-bottom: 16px; }

.txt-block h5 { margin-bottom: 16px; }

/* --- Two-column hero (services hub) --------------------------------
   The row is align-items-center, so the illustration and the copy sit
   on a shared optical centre instead of the image hanging from the top
   of a taller text column. Only the heading rhythm needs stating; the
   eyebrow, paragraph and benefit list all use the shared components. */
.hero-split .txt-block h1 { margin-bottom: 18px; }

/* The split holds to 992px, not 768px. Between those two widths each
   column was only 336px wide while the h1 clamp was still scaling up
   toward its desktop size, which pushed the headline onto four lines —
   worse than it sets at 375px. Stacked, the copy gets the full
   container and the illustration is capped so it does not dominate the
   fold before the heading is read. */
@media (max-width: 991.98px) {
  .hero-split .img-block { margin-bottom: 34px; }
  /* min() so the cap never overrides .img-fluid's 100% on a narrow
     phone — a plain 420px let the illustration run wider than the
     column and get clipped by #page rather than scaling down. */
  .hero-split .img-block img { max-width: min(100%, 420px); }
}

.txt-block > p { max-width: 62ch; margin-bottom: 18px; }

.txt-block > p:last-of-type { margin-bottom: 0; }

.txt-block .btn { margin-top: 28px; }

.img-block { text-align: center; }

.ct-01 .img-block { margin-left: 24px; }

/* --- cbox-1: check-marked list ------------------------------------- */
.cbox-1,
.cbox-2 {
  display: flex;
  position: relative;
  flex-flow: row wrap;
  align-items: stretch !important;
  justify-content: flex-start;
}

.cbox-1 {
  flex-wrap: nowrap;
  align-items: flex-start !important;
  gap: 12px;
  margin-bottom: 14px;
}

.cbox-1:last-of-type { margin-bottom: 0; }

/* A paragraph that introduces a list needs to read as separate from it.
   .txt-block > p:last-of-type zeroes the bottom margin (the list items
   are not > p children), which left these touching at 0px. */
.txt-block > p + .cbox-1,
.txt-block > p + .ctech-values { margin-top: 26px; }

/* Fixed, non-shrinking bullet column. The glyph is centred on the first
   line of text rather than nudged with position:relative, so the bullet
   sits on the container's left edge — level with the paragraph above —
   and wrapped lines align under the text, not under the bullet. */
.cbox-1 .ico-wrap {
  flex: 0 0 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 1.6em;
  margin-left: 0;
}

.cbox-1 .cbox-1-ico,
.cbox-1 .ico-wrap span { line-height: 1; }

/* Neutralise the old nudges. */
.cbox-1.ico-5 span,
.cbox-1.ico-10 span,
.cbox-1.ico-15 span { position: static; top: auto; right: auto; }

.cbox-1.ico-10 [class*="flaticon-"]:before,
.cbox-1.ico-10 [class*="flaticon-"]:after { font-size: 11px; }

.cbox-1.ico-15 [class*="flaticon-"]:before,
.cbox-1.ico-15 [class*="flaticon-"]:after { font-size: 13px; }

.cbox-1-txt,
.cbox-2-txt {
  overflow: hidden;
  flex: 1;
  max-width: 100%;
}

.cbox-1-txt p { margin-bottom: 0; line-height: 1.6; }

/* --- Hero benefit list (services hub) ------------------------------
   Three scannable points between the intro paragraph and the CTA. The
   group owns its own spacing so the items breathe a little more than a
   dense in-body .cbox-1 list, and so the block sits clear of both the
   paragraph above and the button below. */
.hero-benefits {
  margin-top: 26px;
  /* No bottom margin: the CTA below already carries the shared
     `.txt-block .btn { margin-top: 28px }`, and doubling the two left a
     gap wider than the one above the list. */
  margin-bottom: 0;
}

.hero-benefits .cbox-1 { margin-bottom: 12px; }
.hero-benefits .cbox-1:last-child { margin-bottom: 0; }
.hero-benefits .cbox-1-txt p { line-height: 1.65; }

/* --- Service pages: "What's included" ------------------------------
   The grid column runs to ~1100px, which set the point descriptions at
   roughly 117 characters to the line. Capping the block keeps the whole
   section — heading, list and the "Best for" line — on one comfortable
   measure. Single column rather than two: five items with titles and
   multi-line copy split 3/2, leaving an orphan cell and breaking a list
   that reads as one sequence. */
.service-includes {
  /* 720px puts the description text — which starts 26px in, past the
     check column — at roughly 72 characters to the line. Measured, not
     guessed: the average glyph is 9.58px at this size. */
  max-width: 720px;
  margin-left: auto;
  margin-right: auto;
}

/* Titled items need more separation than the 14px a plain .cbox-1
   bullet list uses, or the title of the next point crowds the previous
   description. 22px is the settled value: enough that each point reads
   as its own block, small enough that a four-item list does not leave
   the section feeling half empty. */
.service-point { margin-bottom: 22px; }
.service-point:last-of-type { margin-bottom: 0; }
.service-point .cbox-1-txt h3 { margin-bottom: 6px; }
.service-point .cbox-1-txt p { line-height: 1.7; }

/* The shared .cbox-1 centres its bullet on a 1.6em line box, which is
   right when the first line is body copy. Here the first line is the
   h3, whose line box is shorter, so the check was sitting 2px below the
   title's optical centre on every item. Matching the wrap to the title
   line puts it level. */
.service-point .ico-wrap { min-height: 1.35em; }

/* "Best for" — a rule and a tint, restrained on purpose. It has to
   stop reading as one more paragraph at the foot of the list without
   turning into a promotional panel. */
.service-bestfor {
  margin-top: 30px;
  margin-bottom: 0;
  padding: 16px 20px;
  border-left: 3px solid var(--brand-500);
  border-radius: 0 6px 6px 0;
  background: var(--brand-025);
  color: var(--ink-700);
  font-size: var(--fs-secondary);
  line-height: 1.65;
}

.service-bestfor-label {
  font-weight: 700;
  color: var(--ink-900);
}

/* --- cbox-2: numbered process steps ------------------------------- */
.cbox-2 .ico-wrap {
  position: relative;
  margin-right: 22px;
}

.cbox-2-ico {
  position: relative;
  width: 48px;
  height: 48px;
  text-align: center;
  border-radius: 100%;
  font-size: 1.1875rem;
  font-weight: 700;
  line-height: 44px;
  box-shadow: 0 4px 12px rgba(71, 57, 150, .22);
  border: 2px solid transparent;
  transition: all 300ms var(--ease);
}

.cbox-2-line {
  position: absolute;
  bottom: 18px;
  left: 50%;
  width: 2px;
  background-color: var(--brand-line);
  height: calc(100% - 78px);
  transform: translateX(-50%);
}

.cbox-2:hover .cbox-2-ico {
  background-color: transparent;
  transform: scale(1.06);
}

.cbox-2:hover .cbox-2-ico.bg--theme {
  color: var(--brand-600);
  border-color: var(--brand-600);
}

/* --- Compact numbered step (service pages) -------------------------
   The How We Work badge at a smaller size, with no connector line and
   no hover animation: on the service pages these four steps are a
   summary sitting in a two-column grid, not a vertical timeline, so a
   line between them would connect items that do not follow each other
   down the page. Same circle, colour and weight, so the two pages
   clearly show the same process. */
.cbox-2--sm { align-items: flex-start !important; }

.cbox-2--sm .ico-wrap { margin-right: 16px; }

.cbox-2--sm .cbox-2-ico {
  width: 34px;
  height: 34px;
  font-size: var(--fs-meta);
  line-height: 32px;
  box-shadow: 0 2px 8px rgba(71, 57, 150, .18);
}

.cbox-2--sm:hover .cbox-2-ico { transform: none; }

.cbox-2--sm .cbox-2-txt { margin-bottom: 0; padding-top: 4px; }
.cbox-2--sm .cbox-2-txt h3 { margin-bottom: 8px; }
.cbox-2--sm .cbox-2-txt p { line-height: 1.7; }

/* The grid gap sets the space between steps; row-gap a little wider
   than the column gap so a wrapped description never sits as close to
   the step below it as it does to its neighbour. */
.step-grid { row-gap: 28px; }

.cbox-2-txt { margin-bottom: 28px; padding-top: 3px; }
.cbox-2:last-child .cbox-2-txt { margin-bottom: 0; }
.cbox-2-txt h3,
.cbox-2-txt h5 { margin-bottom: 6px; }
/* Scoped to .cbox-2 .cbox-2-txt, not .cbox-2-txt alone: the <=480 block
   in responsive.css sets .txt-block p { margin-bottom: .85rem } at equal
   specificity and loads later. That reached the two step paragraphs
   without an mb-0 utility and left the steps unevenly spaced (39/39/25)
   on phones. */
.cbox-2 .cbox-2-txt p { margin-bottom: 0; line-height: 1.6; }

/* --- Inline advantages list (non-hero pages) ---------------------- */
/* Reassurance line under a CTA. Same role as the homepage
   .hero-assurance, so it takes the same secondary tier and muted
   colour rather than sitting at full body weight. */
.advantages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 22px;
  margin-top: 20px;
  padding: 0;
  font-size: var(--fs-secondary);
  color: var(--ink-500);
}

.text-center .advantages { margin-top: 22px; }

.advantages li {
  display: flex !important;
  align-items: center;
  gap: 22px;
  width: auto !important;
  clear: none !important;
}

/* The separator is generated, so it cannot wrap onto its own line the
   way the old <li> pipe could. */
.advantages li + li:before {
  content: "";
  flex: 0 0 auto;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background-color: var(--brand-500);
  opacity: .45;
}

.advantages li p { display: block; float: none; margin-bottom: 0; }
.advantages.ico-15 li p span { position: relative; top: 2px; right: -1px; }
.advantages.ico-15 [class*="flaticon-"]:before,
.advantages.ico-15 [class*="flaticon-"]:after { font-size: 12px; }
.advantages li p a { font-weight: 400; text-decoration: underline; }

/* Accordion radius helpers (inner pages) */
.txt-block .accordion-item.r-04:first-of-type { border-top-left-radius: 6px; border-top-right-radius: 6px; }
.txt-block .accordion-item.r-08:first-of-type { border-top-left-radius: 10px; border-top-right-radius: 10px; }
.txt-block .accordion-item.r-12:first-of-type { border-top-left-radius: 14px; border-top-right-radius: 14px; }
.txt-block .accordion-item.r-16:first-of-type { border-top-left-radius: 18px; border-top-right-radius: 18px; }
.txt-block .accordion-item.r-04:last-of-type { border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; }
.txt-block .accordion-item.r-08:last-of-type { border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; }
.txt-block .accordion-item.r-12:last-of-type { border-bottom-right-radius: 14px; border-bottom-left-radius: 14px; }
.txt-block .accordion-item.r-16:last-of-type { border-bottom-right-radius: 18px; border-bottom-left-radius: 18px; }


/* ==================================================================
   13. CARDS

   One card recipe: white surface, 1px hairline, shallow shadow, 14px
   radius, generous internal padding, and a hover that lifts by 3px.
   Used by the service cards, the differentiator boxes and the tech
   boxes so they read as one family.
   ================================================================== */

.block-shadow { box-shadow: var(--shadow-sm); }

/* --- fbox-11: service cards --------------------------------------- */
.fbox-11 {
  display: flex;
  position: relative;
  flex-flow: row wrap;
  align-items: flex-start !important;
  justify-content: flex-start;
  height: 100%;
  gap: 22px;
  padding: var(--pad-card);
  background-color: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow-xs);
  /* The decorative blob behind the icon is deliberately larger than
     the glyph, so it is clipped to the card rather than bleeding over
     the border. */
  overflow: hidden;
  transition: transform 240ms var(--ease), box-shadow 240ms var(--ease),
              border-color 240ms var(--ease);
}

.fbox-11:hover {
  transform: translateY(-3px);
  border-color: var(--brand-line);
  box-shadow: var(--shadow-md);
}

.fbox-ico-wrap {
  position: relative;
  margin-right: 26px;
}

/* Fixed icon column, so the four service cards align to the same text
   edge regardless of how wide each glyph happens to draw. */
.fbox-11 .fbox-ico-wrap {
  flex: 0 0 54px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  margin-right: 0;
}

.fbox-11 .fbox-ico { margin-top: 2px; margin-bottom: 0; }

.fbox-11 .fbox-txt {
  overflow: hidden;
  flex: 1;
  max-width: 100%;
}

.fbox-11 .fbox-txt h3 { margin-bottom: 8px; line-height: 1.35; }

.fbox-11 .fbox-txt p { line-height: 1.6; }

.fbox-11 .fbox-txt h3 a {
  color: var(--ink-900);
  transition: color 200ms var(--ease);
}

.fbox-11:hover .fbox-txt h3 a { color: var(--brand-600); }

.fbox-11 .fbox-txt p { margin-bottom: 0; }

/* --- Cards that carry a secondary action ---------------------------
   One implementation for both card types that use it: the service
   cards on the /services hub (.fbox-11) and the related-service cards
   on the individual service pages (.fbox-12). `.card--linked` marks the
   card; `.card-link` is the action inside it. The homepage keeps plain
   cards, where a linked title is enough.

   The element that holds the copy has to stretch, or the margin-top:auto
   below has nothing to push against. On .fbox-11 that is .fbox-txt,
   because the card itself is a row holding the icon column beside it;
   on .fbox-12 the card is the column. */

.fbox-11--linked .fbox-txt {
  display: flex;
  flex-direction: column;
  /* The card sets align-items: flex-start, so without this the text
     column would be only as tall as its own content. */
  align-self: stretch;
}

.fbox-12.card--linked {
  display: flex;
  flex-direction: column;
}

/* margin-top:auto pins the action to the bottom of the card, so the
   links sit on one line across a row of unequal-length summaries
   rather than each floating under its own paragraph. */
.card-link {
  margin-top: auto;
  padding-top: 18px;
  padding-bottom: 0;
  align-self: flex-start;
}

/* The title and the action target the same page. Hovering either one
   lights both, so the pair reads as a single destination without the
   whole card pretending to be clickable — only the two links are. */
.card--linked:hover .card-link { color: var(--brand-500); }

.card--linked:hover .card-link:after { transform: rotate(45deg) translate(2px, -2px); }

/* Pointing at the link itself is a stronger signal than being anywhere
   over the card, so it gets a stronger response: the lighter purple, a
   thicker underline, and the arrow travelling twice as far. Keyboard
   focus gets exactly the same treatment on top of the shared focus
   ring, so tabbing through the cards reads like hovering them.

   Both selectors carry the .card--linked prefix to outweigh the
   card-hover pair above — hovering the link triggers that too, and at
   equal specificity the later rule is what decides the arrow. Still a
   text link: no background, no border, no box. */
.card--linked .card-link:hover,
.card--linked .card-link:focus-visible {
  color: var(--brand-500);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 5px;
}

.card--linked .card-link:hover:after,
.card--linked .card-link:focus-visible:after {
  transform: rotate(45deg) translate(4px, -4px);
}

/* Keyboard parity with :hover. The card lifts when either link inside
   it takes focus, so a keyboard user gets the same grouping cue a
   mouse user gets. The links keep their own focus ring. */
.card--linked:focus-within {
  border-color: var(--brand-line);
  box-shadow: var(--shadow-md);
}

/* The template used .rows-3 margins to space these; the grid gap and
   equal-height cards handle it now. */
.rows-3 .fb-1, .rows-3 .fb-2,
.rows-3 .fb-3, .rows-3 .fb-4 { margin-bottom: 0; }

.fbox-wrapper p { margin-bottom: 0; }

/* --- fbox-12: differentiator boxes -------------------------------- */
.fbox-12-wrapper { padding-left: 40px; }

/* These four sit beside the section heading, paragraph and CTA. They
   are supporting evidence, so their type sits one tier below the
   service cards and their icon is smaller. */
.fbox-12 {
  padding: var(--pad-card);
  background-color: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow-xs);
  overflow: hidden;
  transition: transform 240ms var(--ease), box-shadow 240ms var(--ease),
              border-color 240ms var(--ease);
}

.fbox-12:hover {
  transform: translateY(-3px);
  border-color: var(--brand-line);
  box-shadow: var(--shadow-md);
}

.fbox-12 h3,
.fbox-12 h5 {
  font-size: var(--fs-body-lg);
  margin-top: 14px;
  margin-bottom: 6px;
  line-height: 1.35;
}

.fbox-12 p {
  margin-bottom: 0;
  font-size: var(--fs-secondary);
  line-height: 1.6;
  color: var(--ink-500);
}

.fbox-12 .fbox-ico [class*="flaticon-"]:before { font-size: 34px; }
.fbox-12 .ico-50 .shape-ico svg { width: 84px; height: 84px; top: -23px; left: calc(50% - 39px); }

/* --- fbox-5 (inner pages) ----------------------------------------- */
.fbox-5 { padding: 44px 40px; }
.fbox-5 h5 { margin-bottom: 14px; }

/* --- tech boxes (technologies page) -------------------------------
   These are filled tiles rather than white cards, but they get the same
   hairline so the family reads as one system and the hover has an edge
   to act on. */
.fbox-5.tech-box {
  border: 1px solid var(--brand-line);
  transition: transform 240ms var(--ease), box-shadow 240ms var(--ease),
              border-color 240ms var(--ease);
}

.tech-box:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: var(--brand-line);
}

.tech-box .ico-55 [class*="flaticon-"]:before { transition: color 240ms var(--ease); }
.tech-box:hover .ico-55 [class*="flaticon-"]:before { color: var(--brand-600); }


/* ==================================================================
   14. TESTIMONIALS

   The client's words are the visual element, so the quote is set at
   body size (not smaller), the cards are equal height, and nothing is
   truncated. Three fit on a desktop row; the rest are reachable by
   scrolling the rail or with the arrows.
   ================================================================== */

.reviews-rail {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: thin;
  scrollbar-color: var(--brand-line) transparent;
  /* Room for the hover lift and the focus ring. */
  padding: 6px 2px 18px;
  margin: 0 -2px;
}

.reviews-rail::-webkit-scrollbar { height: 6px; }
.reviews-rail::-webkit-scrollbar-track { background: transparent; }
.reviews-rail::-webkit-scrollbar-thumb {
  background: var(--brand-line);
  border-radius: 3px;
}

.reviews-track {
  display: flex;
  /* Cards size to their own content. Stretching them to a common
     height meant the single longest review set the height of all 16,
     leaving ~300px of blank card between the quote and the attribution
     on the short ones. Top-aligned in a scroll rail reads as intended;
     a 300px hole does not. */
  align-items: flex-start;
  gap: 24px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.reviews-item {
  flex: 0 0 calc((100% - 48px) / 3);
  scroll-snap-align: start;
  display: flex;
}

@media (max-width: 991px) {
  .reviews-item { flex-basis: calc((100% - 24px) / 2); }
  .reviews-track { gap: 24px; }
}

@media (max-width: 767px) {
  .reviews-item { flex-basis: 88%; }
  .reviews-track { gap: 16px; }
}

.review-1 {
  display: flex;
  flex-direction: column;
  width: 100%;
  margin: 0;
  padding: var(--pad-card);
  background-color: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow-xs);
  transition: transform 240ms var(--ease), box-shadow 240ms var(--ease),
              border-color 240ms var(--ease);
}

.review-1:hover {
  transform: translateY(-3px);
  border-color: var(--brand-line);
  box-shadow: var(--shadow-md);
}

/* A small purple mark, not a 65px watermark behind the text. */
.review-ico {
  margin: 0 0 16px;
  opacity: 1;
  color: var(--brand-100);
  line-height: 1;
}

.review-ico [class*="flaticon-"]:before { font-size: 30px; line-height: 1; }

.review-txt {
  position: static;
  margin: 0;
  flex: 1 1 auto;
}

/* The quote was clamped to four lines at ~15px. Full text, body size. */
.review-txt p {
  display: block;
  overflow: visible;
  font-size: var(--fs-body-lg);
  line-height: 1.7;
  color: var(--ink-700);
  margin: 0;
}

.review-1 .author-data {
  margin-top: 26px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}

.review-author {
  position: relative;
  display: block;
  padding: 0;
  text-align: left;
}

.review-author p { line-height: 1.45; font-weight: 400; margin-bottom: 0; }

.review-author .review-name {
  font-size: var(--fs-body);
  font-weight: 700;
  color: var(--ink-900);
  margin-bottom: 2px;
}

.review-author .review-meta {
  font-size: var(--fs-meta);
  color: var(--ink-500);
}

/* --- Rail controls ------------------------------------------------- */
.reviews-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 26px;
}

.reviews-section .reviews-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 1px solid var(--brand-line);
  border-radius: 50%;
  background-color: var(--surface);
  color: var(--brand-600);
  transition: all 200ms var(--ease);
}

.reviews-section .reviews-btn:hover:not(:disabled) {
  background-color: var(--brand-600);
  border-color: var(--brand-600);
  color: #fff;
}

.reviews-section .reviews-btn:disabled { opacity: .35; cursor: default; }

.reviews-btn svg { width: 17px; height: 17px; }

.reviews-progress {
  font-size: var(--fs-meta);
  color: var(--ink-500);
  margin: 0;
  min-width: 9ch;
  text-align: center;
}

/* The template flattened every button in this section to a 16px tap
   target for the old carousel arrows. */
.reviews-section button { background-color: transparent; border: none; }


/* ==================================================================
   15. FORMS / PROJECT INQUIRY
   ================================================================== */

/* The form sits in an elevated card so it reads as the destination of
   the section rather than a list of inputs on the page background. */
.inquiry-card {
  background-color: var(--surface);
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: var(--shadow-lg);
  padding: 40px 40px 30px;
}

@media (max-width: 991px) { .inquiry-card { padding: 30px 24px 22px; } }

.inquiry-card-title {
  margin: 0 0 26px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--line);
}

.inquiry-card-title h3 { margin-bottom: 4px; }
.inquiry-card-title p { margin: 0; font-size: var(--fs-secondary); color: var(--ink-500); }

/* --- Reasons list on the left column ------------------------------ */
.inquiry-reasons {
  margin: 32px 0 0;
  padding: 0;
  display: grid;
  gap: 22px;
}

.inquiry-reasons > li {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}

/* Same tile as .hero-trust-ico — kept dimensionally identical so the
   two lists read as one component drawn twice. */
.inquiry-reasons .inquiry-reason-ico {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background-color: var(--brand-050);
  color: var(--brand-600);
}

.inquiry-reasons .inquiry-reason-ico [class*="flaticon-"]:before { font-size: 16px; line-height: 1; }

.inquiry-reasons h3 {
  font-size: var(--fs-body);
  font-weight: 700;
  line-height: 1.4;
  margin: 1px 0 4px;
}

.inquiry-reasons p { margin: 0; font-size: var(--fs-secondary); line-height: 1.6; color: var(--ink-500); }

/* Direct contact options, so someone who does not want a form still
   has a route. */
.inquiry-direct {
  margin-top: 32px;
  padding-top: 26px;
  border-top: 1px solid var(--brand-line);
}

.inquiry-direct p { margin: 0 0 12px; font-size: var(--fs-secondary); color: var(--ink-500); }

.inquiry-direct-links {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  margin: 0;
  padding: 0;
}

.inquiry-direct-links a {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 600;
  color: var(--brand-600);
}

.inquiry-direct-links a:hover { text-decoration: underline; }
.inquiry-direct-links [class*="flaticon-"]:before { font-size: 15px; }

/* --- Fields -------------------------------------------------------- */
.contact-form label,
.ctech-form .contact-form label {
  display: block;
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink-900);
  margin-bottom: 8px;
}

/* Helper text under a label. */
.ctech-form .contact-form .field-hint,
.ctech-form .contact-form .col-md-12 span.field-hint {
  display: block;
  font-size: var(--fs-secondary);
  line-height: 1.6;
  font-weight: 400;
  color: var(--ink-500);
  margin-bottom: 12px;
  padding-left: 0;
}

.contact-form .form-control,
.contact-form .form-select {
  height: 58px;
  background-color: #fbfbfd;
  border: 1px solid var(--line);
  box-shadow: none;
  color: var(--ink-900);
  font-size: 1.0625rem;
  font-weight: 400;
  padding: 0 16px;
  margin-bottom: 0;
  border-radius: 10px;
  transition: border-color 180ms var(--ease), background-color 180ms var(--ease),
              box-shadow 180ms var(--ease);
}

.contact-form .form-select {
  display: inline-block;
  width: 100%;
  color: var(--ink-900);
  box-shadow: none;
  border-radius: 10px;
}

.contact-form textarea { min-height: 190px; }
.contact-form textarea.form-control { height: auto; padding: 16px; line-height: 1.6; }

.contact-form .form-control::placeholder { color: #9aa0ae; }

.contact-form .form-control:focus,
.contact-form .form-select:focus {
  outline: 0;
  background-color: var(--surface);
  border-color: var(--brand-500);
  box-shadow: 0 0 0 4px rgba(87, 68, 182, .12);
}

.contact-form .loading {
  color: var(--brand-600);
  font-size: 1.0625rem;
  line-height: 1;
  font-weight: 600;
  padding-left: 15px;
}

.contact-form .error {
  color: var(--danger);
  font-size: var(--fs-secondary);
  line-height: 1.45;
  font-weight: 500;
  margin-bottom: 10px;
}

/* The template hid these with a negative margin tuned to the old
   30px field margin; the grid gutter handles spacing now. */
.form-select + .invalid-feedback,
.form-control + .invalid-feedback {
  margin-top: 7px;
  font-size: var(--fs-secondary);
  font-weight: 500;
  color: var(--danger);
  display: none;
}

.form-select.is-invalid + .invalid-feedback,
.form-control.is-invalid + .invalid-feedback { display: block; }

.contact-form .form-control.is-invalid,
.contact-form .form-select.is-invalid { border-color: #d64545; }

.inquiry-submit {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 20px;
  margin-top: 8px;
}

.inquiry-submit .btn { margin-top: 0; }

.inquiry-submit small {
  font-size: var(--fs-secondary);
  color: var(--ink-500);
  line-height: 1.5;
}


/* ==================================================================
   16. FAQ, BREADCRUMB, WORK
   ================================================================== */

/* FAQ list built on <details>/<summary>: keyboard accessible,
   announced correctly, and the answers stay in the accessibility tree
   when collapsed. */
.faq-item {
  border-bottom: 1px solid var(--line);
  padding: 6px 0;
  /* Lets the answer's height animate to and from `auto` below. */
  interpolate-size: allow-keywords;
}

.faq-item:first-child { border-top: 1px solid var(--line); }

/* The padding moved from the row onto the summary so the whole tap
   target is the clickable element, not a 22px dead strip around it.
   18px top and bottom on a 1.42 line keeps every row past the 44px
   minimum touch target at both breakpoints. */
.faq-question {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  padding: 18px 0;
  cursor: pointer;
  list-style: none;
  transition: color .2s var(--ease);
}

.faq-question::-webkit-details-marker { display: none; }
.faq-question::marker { content: ""; }
.faq-question h3 {
  margin: 0;
  color: var(--ink-900);
  transition: color .2s var(--ease);
}

.faq-question:hover h3 { color: var(--brand-600); }

/* The summary is the focusable element, so the ring belongs on it and
   not on the row. Pulled in tight against the text. */
.faq-question:focus-visible {
  outline: 3px solid var(--brand-600);
  outline-offset: -2px;
  border-radius: 4px;
}

.faq-question::after {
  content: "";
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  /* Centres the chevron on the first line of the question rather than
     on the row, so it stays level with the text when a long question
     wraps to two lines. */
  margin-top: .45em;
  border-right: 2px solid var(--brand-600);
  border-bottom: 2px solid var(--brand-600);
  transform: rotate(45deg);
  transition: transform .25s var(--ease);
}

/* Open state: a heavier question in brand purple and the chevron
   flipped. No background block — the accordion stays a list. */
.faq-item[open] > .faq-question h3 { color: var(--brand-600); }
.faq-item[open] > .faq-question::after { transform: rotate(-135deg); }

/* ::details-content is the box the browser wraps everything after the
   <summary> in, so the whole panel animates with no JavaScript.
   `transition-behavior: allow-discrete` keeps the panel painted while
   it collapses. Engines without ::details-content toggle instantly,
   which is the behaviour they have today. */
.faq-item::details-content {
  height: 0;
  overflow: hidden;
  opacity: 0;
  transition: height .3s var(--ease), opacity .25s ease, content-visibility .3s;
  transition-behavior: allow-discrete;
}

.faq-item[open]::details-content { height: auto; opacity: 1; }

/* Bottom padding rather than the row's, so a collapsed item closes flush
   to its divider and an open one keeps air above the next question. */
.faq-answer {
  padding-top: 4px;
  padding-bottom: 20px;
  max-width: 68ch;
}

.faq-answer p { margin-bottom: 0; line-height: 1.7; }

/* Legacy accordion (inner pages) */
.faqs-section .accordion-item {
  background-color: transparent !important;
  border: none;
  border-bottom: 1px solid var(--line);
}

#faqs-2.faqs-section .accordion-item { border-bottom: 1px solid var(--line); }

/* Tightens the hand-off from the FAQ into the closing CTA by 12px. The
   FAQ's own bottom padding gives way rather than the CTA's top, so the
   CTA band keeps its full internal breathing room. */
#faqs-2.faqs-section { padding-bottom: calc(var(--section-y) - 12px); }
#faqs-2 .inner-page-title { margin-bottom: 48px; }

.accordion-panel { margin: 0; padding: 0 0 15px 0; display: none; }
#faqs-2 .accordion-panel { padding: 26px 0 15px 0; }

.question h5 { margin-bottom: 18px; }
.question h5 span { margin-right: 5px; }
.question p a,
.accordion-panel p a { font-weight: 500; text-decoration: underline; }

/* --- Breadcrumb ----------------------------------------------------
   Sits inside the hero container, so the hero-overlay supplies the
   fixed-header clearance and this only needs a gap to the headline. */
.breadcrumb-bar {
  margin-bottom: 22px;
  font-size: var(--fs-secondary);
}

/* The hero container is centred; the trail reads better ranged left,
   which is also where it sat before it moved inside. */
.hero-section .breadcrumb-bar { text-align: left; }

.breadcrumb-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.breadcrumb-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--ink-500);
}

.breadcrumb-list li + li::before { content: "/"; color: #b9bcc7; }
.breadcrumb-list a { color: var(--ink-500); }
.breadcrumb-list a:hover { color: var(--brand-600) !important; text-decoration: underline; }
.breadcrumb-list [aria-current="page"] { color: var(--ink-900); font-weight: 600; }

/* --- Work / case studies ------------------------------------------ */
.work-stack {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.work-stack li {
  padding: 6px 14px;
  border: 1px solid var(--brand-line);
  border-radius: 100px;
  background: var(--brand-025);
  color: var(--brand-600);
  font-size: var(--fs-meta);
}

/* --- Legal pages (privacy policy) ---------------------------------
   A long document to be read, not a marketing page: one measure-limited
   column, a quiet sticky table of contents beside it on desktop, and no
   background bands or cards between sections. Section rhythm carries the
   structure instead.

   Body copy runs a notch larger and looser than the marketing pages —
   19px on a 1.75 leading rather than 17-18px on 1.65 — because this is
   the one page people read top to bottom rather than scan.
   ------------------------------------------------------------------ */

/* Anchors land clear of the fixed header. --header-h is 108px and the
   header measures 114px in practice, so +32px leaves real air above a
   heading arrived at from the contents rather than tucking it under the
   nav. One value drives the sticky offset and the anchor offset both. */
.legal-content {
  --legal-anchor-offset: calc(var(--header-h) + 32px);

  /* Smooth scrolling for contents clicks. The global reduced-motion
     block at the end of this file already forces scroll-behavior back
     to auto, so this is opt-out safe. */
  scroll-behavior: smooth;
}

.legal-content .legal-section,
.legal-content .legal-section h2,
.legal-content .legal-section h3 { scroll-margin-top: var(--legal-anchor-offset); }

/* The measure. The grid column is ~990px wide at desktop, which is well
   past a comfortable line length for paragraph-heavy copy, so the body
   caps itself and the sidebar keeps the space that frees up. 800px is
   the top of the range this page was signed off against. */
.legal-content .legal-body {
  font-size: clamp(1.125rem, 1.09rem + .18vw, 1.1875rem); /* 18 -> 19px */
  line-height: 1.75;
}

.legal-content .legal-section + .legal-section { margin-top: 64px; }

.legal-content .legal-section h2 {
  /* Between .s-24 and .s-42 on the scale: enough to open a section
     without shouting the way a marketing section title does. */
  font-size: clamp(1.4375rem, 1.14rem + .9vw, 1.75rem);
  font-weight: 700;
  color: var(--ink-900);
  line-height: 1.3;
  letter-spacing: -.01em;
  margin: 0 0 16px;
}

.legal-content .legal-section h3 {
  font-size: clamp(1.0625rem, 1rem + .25vw, 1.1875rem); /* .s-20 */
  font-weight: 700;
  color: var(--ink-900);
  line-height: 1.45;
  margin: 40px 0 12px;
}

.legal-content .legal-section > h3:first-of-type { margin-top: 28px; }

.legal-content .legal-section p { margin-bottom: 20px; }
.legal-content .legal-section p:last-child { margin-bottom: 0; }

/* --- Inline links ---------------------------------------------------
   Dense legal copy needs links that read as links without stabbing the
   line. --brand-600 on white clears AA comfortably; the underline sits
   low and thin until hover, when it thickens in place rather than
   moving the text. */

.legal-content .legal-section a,
.legal-content .legal-table a {
  color: var(--brand-600);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(71, 57, 150, .45);
  text-underline-offset: 3px;
  transition: color .2s var(--ease), text-decoration-color .2s var(--ease);
}

.legal-content .legal-section a:hover,
.legal-content .legal-table a:hover {
  color: var(--brand-700) !important;
  text-decoration-thickness: 2px;
  text-decoration-color: currentColor;
}

.legal-content .legal-section a:visited,
.legal-content .legal-table a:visited { color: var(--brand-700); }

/* --- Lists ---------------------------------------------------------- */

.legal-content .legal-list {
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
}

.legal-content .legal-list li {
  position: relative;
  padding-left: 24px;
  margin-bottom: 12px;
}

.legal-content .legal-list li:last-child { margin-bottom: 0; }

.legal-content .legal-list li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: .72em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brand-500);
}

/* --- "Does not sell" callout ---------------------------------------
   A rule and a tint, no icon and no fill strong enough to read as a
   promo banner. The point is emphasis, not decoration. */
.legal-content .legal-callout {
  border-left: 3px solid var(--brand-500);
  background: var(--brand-025);
  border-radius: 0 6px 6px 0;
  padding: 18px 22px;
  margin-bottom: 26px;
  color: var(--ink-700);
}

/* --- Third-party services table ------------------------------------ */

.legal-content .legal-table-wrap {
  overflow-x: auto;
  margin: 0 0 26px;
}

.legal-content .legal-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-meta);
  line-height: 1.65;
}

.legal-content .legal-table caption {
  caption-side: top;
  text-align: left;
  color: var(--ink-500);
  font-size: var(--fs-eyebrow);
  line-height: 1.5;
  padding-bottom: 12px;
}

.legal-content .legal-table th,
.legal-content .legal-table td {
  text-align: left;
  vertical-align: top;
  padding: 16px 18px;
  border-bottom: 1px solid var(--line);
}

/* The header row is the only tinted surface in the table — enough to
   separate it from the data without the table reading as a UI panel. */
.legal-content .legal-table thead th {
  color: var(--ink-900);
  font-weight: 700;
  font-size: var(--fs-eyebrow);
  text-transform: uppercase;
  letter-spacing: .05em;
  background: var(--brand-025);
  border-bottom: 2px solid var(--brand-line);
  white-space: nowrap;
}

.legal-content .legal-table tbody th { color: var(--ink-900); font-weight: 700; }
.legal-content .legal-table tbody tr:last-child th,
.legal-content .legal-table tbody tr:last-child td { border-bottom: 0; }

/* --- Table of contents ---------------------------------------------
   Desktop: sticky, borderless, hung off a single left rule so it reads as
   a margin note rather than a panel. Mobile: the same list inside a
   <details>, which needs no script to open. */

.legal-content .legal-toc { display: none; }
.legal-content .legal-toc-mobile { display: block; }

.legal-content .legal-toc-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.legal-content .legal-toc-list li { margin: 0; }

/* The rail is drawn on every item rather than only the active one, so
   the highlight changes colour in place instead of the list shifting
   sideways as you scroll. */
.legal-content .legal-toc-list a {
  display: block;
  padding: 9px 4px 9px 16px;
  color: var(--ink-500);
  font-size: var(--fs-meta);
  line-height: 1.5;
  text-decoration: none;
  border-left: 2px solid var(--line);
  transition: color .2s var(--ease), border-color .2s var(--ease);
}

.legal-content .legal-toc-list a:hover {
  color: var(--brand-600) !important;
  border-left-color: var(--brand-500);
}

/* Set by the scrollspy in js/reveal.js. Three cues carry the state at
   once — colour, weight and the left indicator — plus aria-current for
   assistive tech, so it never rests on colour alone. Without script the
   contents still navigate; only the highlight is missing. */
.legal-content .legal-toc-list a[aria-current="true"] {
  color: var(--brand-600);
  font-weight: 600;
  border-left-color: var(--brand-500);
  border-left-width: 3px;
  padding-left: 15px;
}

.legal-content .legal-toc-mobile {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--brand-025);
  margin-bottom: 40px;
}

.legal-content .legal-toc-mobile > summary {
  cursor: pointer;
  padding: 14px 18px;
  font-weight: 700;
  color: var(--ink-900);
  list-style-position: inside;
  border-radius: 8px;
}

.legal-content .legal-toc-mobile[open] > summary {
  border-bottom: 1px solid var(--line);
  border-radius: 8px 8px 0 0;
}

.legal-content .legal-toc-mobile > nav { padding: 8px 18px 14px; }
.legal-content .legal-toc-mobile .legal-toc-list a { padding-top: 8px; padding-bottom: 8px; }

/* The markup splits the row at the md breakpoint, but a quarter-width
   sidebar at 768-991px is too narrow to read and the sticky sidebar is
   a desktop-only pattern. Both columns go full width below 992px so the
   <details> control sits above the policy instead. Kept in CSS so the
   markup stays one layout. */
@media (max-width: 991.98px) {
  .legal-content .legal-aside,
  .legal-content .legal-body {
    flex: 0 0 100%;
    max-width: 100%;
    width: 100%;
  }
}

@media (min-width: 992px) {
  .legal-content .legal-toc { display: block; }
  .legal-content .legal-toc-mobile { display: none; }

  /* Sticky, not fixed, and on the nav rather than on .legal-aside: the
     column is a stretched flex item as tall as the row, and a sticky
     element that already fills its containing block has nowhere to
     travel, so it would never move. Sticking the short nav inside the
     tall column is what produces the effect. The sidebar travels with
     the policy and comes to rest at the end of the row, which is above
     the footer. It cannot overlap the footer or the body column, and it
     adds no horizontal overflow because it never leaves its column.

     No max-height or overflow here by design: the list scrolls with the
     page rather than inside its own box. */
  .legal-content .legal-toc {
    position: sticky;
    top: var(--legal-anchor-offset);
    padding-left: 4px;
  }

  .legal-content .legal-toc-title {
    font-size: var(--fs-eyebrow);
    text-transform: uppercase;
    letter-spacing: .06em;
    font-weight: 700;
    color: var(--ink-500);
    margin: 0 0 12px 16px;
  }
}

@media (max-width: 767px) {
  .legal-content .legal-section + .legal-section { margin-top: 48px; }
}

/* Below the sidebar breakpoint the table stops being a grid and becomes
   one labelled block per service, so nothing has to scroll sideways.
   This tracks the layout breakpoint rather than 768px: once the sidebar
   has gone full width the body column is ~720px, and four columns there
   left the widest cell wrapping to six lines and the table overflowing
   its wrapper by a few pixels — a scrollbar earning nothing. */
@media (max-width: 991.98px) {
  .legal-content .legal-table,
  .legal-content .legal-table tbody,
  .legal-content .legal-table tr,
  .legal-content .legal-table th,
  .legal-content .legal-table td { display: block; width: 100%; }

  .legal-content .legal-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .legal-content .legal-table tbody tr {
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 8px 0;
    margin-bottom: 16px;
  }

  .legal-content .legal-table tbody tr:last-child { margin-bottom: 0; }

  .legal-content .legal-table th,
  .legal-content .legal-table td { border-bottom: 0; padding: 9px 18px; }

  .legal-content .legal-table td::before {
    content: attr(data-label);
    display: block;
    font-size: var(--fs-eyebrow);
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--ink-500);
    margin-bottom: 2px;
  }
}

/* --- Founder links (about page) ----------------------------------- */
#loading {
  height: 100%;
  width: 100%;
  position: fixed;
  margin-top: 0;
  top: 0;
  z-index: 99999999;
  background-color: #efeffc;
}


/* ==================================================================
   17. FOOTER
   Scoped to #footer-3 so the template's other footer variants are
   untouched.
   ================================================================== */

.footer {
  padding-bottom: 0;
  color: var(--ink-600);
}

.footer a { color: var(--ink-600); }
.footer a:hover { color: var(--brand-600) !important; }

.footer hr { margin-top: 30px; margin-bottom: 0; opacity: .1; }

/* The row already carries a gy-5 gutter, so this second gap was adding
   36px of dead space under every column on desktop and stacking on top
   of the gutter on mobile. */
.footer-info,
.footer-links { margin-bottom: 0; }

img.footer-logo { width: auto; max-width: inherit; max-height: 62px; }

#footer-3 .footer-info p {
  max-width: 38ch;
  font-size: var(--fs-secondary);
  line-height: 1.65;
}

/* Inline <a> collapsed to a 19px box around the logo image. */
#footer-3 .footer-logo-link { display: inline-block; line-height: 0; }

/* Column headings: uppercase eyebrow weight, one consistent gap to
   the first item below. */
#footer-3 .footer-links h2 {
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-500);
  margin-bottom: 20px;
}

.footer h6 { line-height: 1; margin-bottom: 22px; color: var(--ink-900); }

/* The <li> inherited the body size while the <a> inside was 14px, so
   the line box pushed links 39px apart while sitting 20px below their
   heading. Both are now 16px on a matched line-height. */
#footer-3 .foo-links li {
  font-size: var(--fs-secondary);
  line-height: 1.55;
  margin-bottom: 6px;
}

#footer-3 .foo-links li:last-child { margin-bottom: 0; }

/* Vertical padding lifts the link box to >=24px so it meets the
   minimum target size (WCAG 2.5.8) without changing the rhythm. */
#footer-3 .foo-links li a {
  display: inline-block;
  padding: 5px 0;
  color: var(--ink-600);
}

.foo-links li {
  width: auto !important;
  display: block !important;
  vertical-align: top;
  clear: none !important;
  margin: 0;
  padding: 0;
}

.foo-links.ico-10 li span { position: relative; top: 1.5px; right: 3px; }
.foo-links.ico-15 [class*="flaticon-"]:before,
.foo-links.ico-15 [class*="flaticon-"]:after { font-size: 13px; }

.footer .foo-links li p { font-weight: 400; margin-bottom: 10px; }
.footer .foo-links li:last-child p { margin-bottom: 0; }

.footer .footer-mail-link { margin-left: 3px; margin-bottom: 0; }
.footer-mail-link { font-size: var(--fs-secondary); }
.footer-mail-link a { font-weight: 600; color: var(--ink-900); }
.footer-mail-link a:hover { color: var(--brand-600) !important; }
.footer-mail-link span { position: relative; top: 4px; right: 3px; }

#footer-3 .footer-links .footer-mail-link { margin-left: 0; margin-bottom: 16px; }

#footer-3 .footer-location {
  color: var(--ink-500);
  font-size: var(--fs-secondary);
  line-height: 1.65;
}

/* Socials sit below the contact details so the column reads
   primary-contact first and the icons close the block. */
.footer-socials { margin: 0; display: inline-block; }

#footer-3 .footer-socials {
  display: flex;
  gap: 12px;
  margin-top: 22px;
  padding: 0;
  list-style: none;
}

.footer-socials li {
  float: left;
  width: auto !important;
  display: inline-block !important;
  vertical-align: top;
  clear: none !important;
  margin: 0;
}

#footer-3 .footer-socials li { float: none; margin: 0; }

.footer-socials a { display: block; margin-right: 15px; }
.footer-socials.ico-25 a { margin-right: 16px; }
.footer-socials.ico-25 [class*="flaticon-"]:before,
.footer-socials.ico-25 [class*="flaticon-"]:after { font-size: 20px; }

#footer-3 .footer-socials a {
  margin: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 10px;
  background: var(--brand-050);
  color: var(--brand-600);
  transition: background-color .2s var(--ease), color .2s var(--ease);
}

/* The icon font has no descent, so the glyph's inline box carries ~8px
   of empty descender space and the mark rides high in the tile. Laying
   the glyph out as a block of exactly 1em drops that space, and flex
   centring then lands it dead centre. */
#footer-3 .footer-socials a span { display: block; line-height: 1; }
#footer-3 .footer-socials a span:before { display: block; line-height: 1 !important; }

#footer-3 .footer-socials a:hover,
#footer-3 .footer-socials a:focus-visible {
  background: var(--brand-600);
  color: #fff !important;
}

/* --- Sub-footer: copyright left, legal links right ---------------- */
#footer-3 .bottom-footer {
  margin-top: 40px;
  padding: 24px 0 30px;
  border-top: 1px solid rgba(36, 32, 72, .12);
}

#footer-3 .footer-copyright-text { font-size: var(--fs-secondary); color: var(--ink-500); }

#footer-3 .footer-legal-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px 24px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-secondary);
}

#footer-3 .footer-legal-links a { display: inline-block; padding: 4px 0; }

/* Same convention as the main nav: the visible current state hangs off
   aria-current, so it can never disagree with what is announced. */
#footer-3 .footer-legal-links a[aria-current="page"] {
  color: var(--ink-900);
  font-weight: 600;
}

@media (max-width: 767px) {
  #footer-3 .footer-copyright-text,
  #footer-3 .footer-legal-links {
    text-align: center;
    justify-content: center;
  }
  #footer-3 .footer-socials { margin-top: 18px; justify-content: center; }
}


/* ==================================================================
   18. MOTION

   Entrance motion lives in animate.css. Everything here is the
   catch-all: honour a reduced-motion preference across the whole site.
   ================================================================== */

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


/* ==================================================================
   19. TECHNOLOGY GRID  (technologies page)

   Eight capability cards. Two things were making them read as a long
   repetitive block: a 90px icon well before any content, and the
   photographic bg--04 wash repeated eight times, which is a lot of
   texture for a card that is mostly a list. The wash is now a flat
   brand tint with a hairline, and the vertical space inside each card
   is roughly 18% tighter.

   There are no third-party technology logo assets in this project, so
   named tools are distinguished from engineering capabilities with
   text chips (.tech-chips) rather than logos: the chips carry the
   product names, the checkmark list carries the work. Cards with no
   named product simply have no chip row.

   Equal height per row comes from flex (col + h-100), not a min-height,
   so a short card is never padded out to match a tall one beyond what
   the row itself requires.
   ================================================================== */

/* White card on the tinted band, exactly as the homepage services grid
   does it. height:100% inside a d-flex column makes the two cards in a
   row match; rows are independent, so a row is only ever as tall as its
   own taller card. On one column each card is alone in its row and so
   takes its natural height. */
.fbox-5.tech-box {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  padding: 24px 26px 22px;
  background-color: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  transition: border-color 200ms var(--ease), box-shadow 200ms var(--ease);
}

/* These cards carry no link, so hover must not imply they are
   clickable: a border tint and a hairline shadow, no lift, no scale. */
.tech-box:hover {
  border-color: var(--brand-line);
  box-shadow: var(--shadow-xs);
}

/* One fixed icon block so the eight glyphs sit on a common baseline
   however wide each one draws.

   .shape-ico carries `margin: 0 auto` from the shared icon component,
   and auto margins on a flex item beat justify-content — which is why
   the glyph sat centred while the heading and list below it were ranged
   left. Zeroing the margin is what actually left-aligns it. */
.tech-box .fbox-ico {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  height: 46px;
  margin-bottom: 8px;
}

.tech-box .fbox-ico .shape-ico { margin: 0; }

.tech-box .ico-55 [class*="flaticon-"]:before { font-size: 34px; line-height: 1; }
.tech-box .ico-55 .shape-ico svg { width: 76px; height: 76px; top: -21px; left: calc(50% - 36px); }

/* Reading order runs icon -> title -> description -> tools/work, all
   ranged left so the eye returns to one edge. */
.tech-box .fbox-txt {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  text-align: left;
}

.tech-box .fbox-txt h3 {
  margin-bottom: 6px;
  line-height: 1.35;
}

.tech-box .fbox-txt > p {
  font-size: var(--fs-secondary);
  line-height: 1.55;
  color: var(--ink-500);
  margin-bottom: 14px;
}

/* --- Technology chips ---------------------------------------------
   Compact, monochrome, on the card surface. Deliberately quiet: they
   are for recognition, not decoration. */
.tech-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 16px;
  padding: 0;
  list-style: none;
}

.tech-chips li {
  font-size: var(--fs-meta);
  font-weight: 600;
  line-height: 1.3;
  color: var(--brand-700);
  background-color: var(--brand-050);
  border: 1px solid var(--brand-line);
  border-radius: 6px;
  padding: 7px 11px;
}

/* --- Capability list ----------------------------------------------- */
.tech-box .cbox-1 { margin-bottom: 8px; }
.tech-box .cbox-1:last-child { margin-bottom: 0; }
.tech-box .cbox-1-txt p { font-size: var(--fs-secondary); line-height: 1.5; }

/* A chip row followed by the list needs a touch more separation than
   two list rows. */
.tech-chips + .cbox-1 { margin-top: 2px; }

/* The grid and the CTA read as one move, so the band closes 12px
   tighter than a standalone section would. Scales with --section-y so
   the proportion holds at every breakpoint. */
#our-stack { padding-bottom: calc(var(--section-y) - 12px); }

@media (max-width: 991px) {
  .fbox-5.tech-box { padding: 24px 22px 22px; }
}

@media (max-width: 767px) {
  .fbox-5.tech-box { padding: 20px 18px 18px; }
  .tech-box .fbox-ico { height: 42px; margin-bottom: 6px; }
  .tech-box .ico-55 [class*="flaticon-"]:before { font-size: 31px; }
  .tech-box .ico-55 .shape-ico svg { width: 70px; height: 70px; top: -19px; left: calc(50% - 33px); }
}

/* ==================================================================
   20. ABOUT PAGE

   No new components: the values list and the founder block reuse
   .cbox-1 and .img-block, and the CTA pair uses the same .btns-group
   and button tiers as the homepage hero. What is here is the small
   amount of arrangement those shared parts need on this page.
   ================================================================== */

/* --- Values: "Clarity", "Collaboration", ... ----------------------
   Editorial list, not cards. The value name was set at weight 500,
   which is lighter than the surrounding body text and so read as less
   important than its own sentence. It is now the heaviest thing on the
   line, and each value gets real separation from the next. */
.ctech-values .cbox-1 { margin-bottom: 18px; }
.ctech-values .cbox-1:last-of-type { margin-bottom: 0; }

.ctech-values .cbox-1-txt p { line-height: 1.6; }

.ctech-values .cbox-1-txt strong {
  font-weight: 700;
  color: var(--ink-900);
}

/* The dash after each name is drawn rather than typed, so the markup
   carries the name and the sentence and nothing else. */
.ctech-values .cbox-1-txt strong:after {
  content: " — ";
  font-weight: 400;
  color: var(--ink-500);
}

/* --- Founder ------------------------------------------------------
   The portrait sits in a narrower column than the biography now, so it
   supports the text instead of competing with it. */
.founder-media { margin-left: 0 !important; }

/* The biography read as one block because the gap between paragraphs
   (18px) was smaller than the gap between lines inside them (29.7px),
   so nothing signalled where one paragraph ended. Separation now beats
   the leading, the leading is a little looser than default body copy,
   and the measure is capped short of the column so lines stop running
   to ~82 characters. */
/* Scoped to .txt-block.founder-bio, not .founder-bio alone: the <=480
   block in responsive.css sets .txt-block p { margin-bottom: .85rem }
   at equal specificity and loads later, which collapsed these gaps to
   14px on phones against a ~27px leading — the dense block all over
   again, just at mobile. */
.txt-block.founder-bio > p {
  max-width: 42rem;
  line-height: 1.72;
  margin-bottom: 32px;
}

.txt-block.founder-bio > p:last-of-type {
  margin-top: 38px;
  margin-bottom: 0;
}

.founder-media img { max-width: 100%; height: auto; }

.founder-connect {
  margin-top: 22px;
  text-align: center;
}

.founder-connect-label {
  font-size: var(--fs-meta);
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-500);
  margin: 0 0 12px;
}

/* The mark is the thing; the box around it was reading as a button and
   competing with the biography. The 44px hit area stays, it is just no
   longer painted. */
.founder-icons {
  display: flex;
  justify-content: center;
  gap: 18px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.founder-icons li { margin: 0; }

.founder-icons a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin: 0;
  border: 0;
  background: none;
}

.founder-icons a img {
  width: 40px;
  height: 40px;
  opacity: .82;
  transition: opacity 200ms var(--ease), transform 200ms var(--ease);
}

.founder-icons a:hover img {
  opacity: 1;
  transform: scale(1.08);
}

/* The hit area is invisible, so the ring is drawn around it rather than
   around the mark, and follows the same radius. */
.founder-icons a:focus-visible {
  border-radius: 10px;
  outline-offset: 2px;
}

/* --- Philosophy / What We Actually Do -----------------------------
   Two text columns side by side. Capping the measure keeps both
   readable and stops the left column running noticeably longer than
   the right purely because its lines are wider. */
#about-3 .txt-block > p { max-width: 54ch; }

/* Below 992px the founder columns stack, so the portrait is capped
   rather than running the full container width. The biography reads
   badly in a 324px column, which is what a 50/50 split gave at tablet. */
@media (max-width: 991px) {
  .founder-media img { max-width: 420px; }
}

@media (max-width: 767px) {
  /* The row gutter handles the stack gap now. */
  #a3-1 { margin-bottom: 0; }
  .founder-connect { margin-top: 18px; }
  .founder-media img { max-width: 320px; }
}


/* ==================================================================
   21. HOW WE WORK PAGE

   No new components: the process steps are .cbox-2, the expectation
   list is .cbox-1, and the CTAs use the same three button tiers as the
   other pages. What is here is the arrangement those shared parts need.
   ================================================================== */

/* Balance the line lengths of a heading that would otherwise break with
   a two-word orphan on the last line. Applied per heading rather than to
   all h2s, so no already-approved heading break moves. */
.txt-balance { text-wrap: balance; }

/* --- Expectation list: "Clear Communication", "No Surprises", ... ----
   Each point is a title plus a sentence, so it needs more separation
   from the next point than a single-line bullet does, and the title has
   to out-weigh its own description. The Bootstrap mb-2 that used to sit
   on every row carried !important and held them 8px apart against the
   14px the rest of the site uses. */
.expect-list .cbox-1 { margin-bottom: 20px; }
.expect-list .cbox-1:last-of-type { margin-bottom: 0; }

.expect-list .expect-title {
  font-weight: 700;
  color: var(--ink-900);
  line-height: 1.4;
  margin-bottom: 4px;
}

.expect-list .cbox-1-txt p + p {
  line-height: 1.55;
  margin-bottom: 0;
}

/* Both sections stack below 992px because the step and expectation
   descriptions ran ~33-36 characters per line in a two-up md layout.
   Stacked, the illustrations are capped rather than running the full
   container width. */
@media (max-width: 991px) {
  #our-process .img-block img,
  .ct-01 .img-block img { max-width: 460px; }
}

@media (max-width: 767px) {
  .expect-list .cbox-1 { margin-bottom: 18px; }
  #our-process .img-block img,
  .ct-01 .img-block img { max-width: 330px; }
}
