/*
Theme Name:   ComplyRakshak
Theme URI:    https://complyrakshak.com
Description:  Child theme of Hello Elementor for ComplyRakshak — corporate compliance and advisory. All layout is built in Elementor; this theme carries only enqueues and small global overrides.
Author:       ComplyRakshak
Author URI:   https://complyrakshak.com
Template:     hello-elementor
Version:      0.1.0
Requires PHP: 7.4
License:      GNU General Public License v2 or later
License URI:  https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  complyrakshak
Tags:         elementor, child-theme
*/

/* -------------------------------------------------------------------------
   DESIGN TOKENS — INTENTIONALLY EMPTY AT THIS STAGE.

   Elementor Globals are the single source of truth for colour and type.
   Nothing is hardcoded here until the tokens have been verified against
   comply_rakshak_logo.webp and registered as Elementor Globals (Phase 2.1).

   Do not add hex values to this file without also updating the Elementor
   Global that owns them, or the two will drift.
   ------------------------------------------------------------------------- */

/* ===========================================================================
   HEADER — sticky behaviour
   Elementor Pro adds .elementor-sticky--effects to the sticky container once
   the scroll passes sticky_effects_offset (60px). Everything below keys off
   that class; the sticky mechanics themselves are Elementor's, not ours.
   =========================================================================== */

/* COMPACT STICKY STATE — revision batch 2, item 1 (D-113).

   ⚠ THE HEADER'S LAYOUT BOX NEVER CHANGES. Read js/cr-header.js first.

   The old rules here animated max-height and padding inside a fixed header.
   Every child moved while they ran, which is layout shift: 0.013-0.032 CLS per
   scroll, measured. They also ADDED 9px of padding to the bar, so the "shrunk"
   bar was taller than the resting one (182px vs 164px at 1440).

   Now the compact state uses only transform and clip-path, which the Layout
   Instability API does not count:
     - the header slides up by --cr-hdr-shift, taking the utility bar and the
       top of the bar out of the viewport;
     - clip-path trims everything below a band around the bar's centre line
       (clipped regions also stop receiving clicks);
     - logo and CTA scale about their centre lines.
   The nav keeps its size: its 47px targets fit the 64px band, and shrinking the
   text would cost legibility for no height.

   The custom properties are measured and set by js/cr-header.js. If that script
   has not run (data-cr-compact absent), nothing below applies and the sticky
   header stays full height — degraded, never broken. */

.cr-header {
  transition: transform .22s ease, clip-path .22s ease;
}

.cr-header .cr-utility {
  transition: visibility 0s linear .22s;
}

/* The utility text is two single lines; the theme's paragraph margin added
   14px beneath each and made the bar 51px for 21px of text (D-118). */
.cr-header .cr-utility p {
  margin: 0;
}

/* clip-path MUST have an interpolable resting value. `none` -> `inset(...)`
   cannot animate, so the clip SNAPPED to the compact band while the transform
   was still sliding: for 0.22s the band sat up to 100px down the screen with
   bare page above it (D-118). The bottom inset is negative so the open
   Services submenu, which hangs below the header box, is never clipped. */
.cr-header[data-cr-compact="ready"] {
  clip-path: inset(0 0 -100vh 0);
}

/* The LINK scales, not the image: the anchor carries the focus ring, and an
   unscaled 132px anchor round a 48px image drew its ring far outside the band
   (measured: ring -40..104px against a 0..64px band). */
.cr-header .elementor-widget-theme-site-logo a {
  transform-origin: left center;
  transition: transform .22s ease;
}

.cr-header .cr-header-cta .elementor-button {
  transform-origin: right center;
  transition: transform .22s ease, border-color .15s ease;
}

.cr-header[data-cr-compact="ready"].elementor-sticky--effects {
  transform: translateY(var(--cr-hdr-shift, 0px));
  clip-path: inset(var(--cr-hdr-clip-top, 0px) 0 var(--cr-hdr-clip-bottom, 0px) 0);
}

/* Off-screen links must not stay in the tab order. visibility is not layout. */
.cr-header[data-cr-compact="ready"].elementor-sticky--effects .cr-utility {
  visibility: hidden;
  transition-delay: 0s;
}

.cr-header[data-cr-compact="ready"].elementor-sticky--effects .elementor-widget-theme-site-logo a {
  transform: scale(var(--cr-hdr-logo-scale, 1));
}

.cr-header[data-cr-compact="ready"].elementor-sticky--effects .cr-header-cta .elementor-button {
  transform: scale(var(--cr-hdr-cta-scale, 1));
}

/* The bottom rule of the compact bar. A box-shadow on the header would be
   clipped away, so the line is drawn at the band's lower edge, inside the clip.
   crruleonlite, bound to the Global (D-12). */
.cr-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--cr-hdr-band-bottom, 0px) - 1px);
  height: 1px;
  background: var(--e-global-color-crruleonlite);
  opacity: 0;
  pointer-events: none;
  transition: opacity .22s ease;
}

.cr-header[data-cr-compact="ready"].elementor-sticky--effects::after {
  opacity: 1;
}

/* Content that legitimately extends below the band must not be clipped:
   the open mobile drawer, and the desktop Services submenu.

   Keyed to the OPEN STATE, not to :hover or :focus-within — those fired while
   the submenu was still closed and unclipped the empty lower half of the bar,
   so the header visibly grew on focus. SmartMenus marks an open parent with
   `.highlighted` and aria-expanded="true". */
.cr-header[data-cr-compact="ready"].elementor-sticky--effects:has(.elementor-menu-toggle.elementor-active),
.cr-header[data-cr-compact="ready"].elementor-sticky--effects:has(.elementor-nav-menu--main a.has-submenu.highlighted),
.cr-header[data-cr-compact="ready"].elementor-sticky--effects:has(.elementor-nav-menu--main a.has-submenu[aria-expanded="true"]) {
  clip-path: inset(var(--cr-hdr-clip-top, 0px) 0 -100vh 0);
  transition: transform .22s ease;
}

/* Measuring must see the resting geometry. Applied and removed inside one
   synchronous task, so it is never painted. */
.cr-header.cr-header-measuring,
.cr-header.cr-header-measuring .elementor-widget-theme-site-logo a,
.cr-header.cr-header-measuring .cr-header-cta .elementor-button {
  transform: none !important;
  transition: none !important;
}

/* Anyone who has asked for less motion gets the same states with no animation. */
@media (prefers-reduced-motion: reduce) {
  .cr-header,
  .cr-header .cr-utility,
  .cr-header::after,
  .cr-header .elementor-widget-theme-site-logo a,
  .cr-header .cr-header-cta .elementor-button {
    transition: none !important;
  }
}

/* ---------------------------------------------------------------------------
   Navigation
   --------------------------------------------------------------------------- */

/* The CTA in the mobile drawer should read as a button, not a seventh link. */
.cr-nav .cr-nav-cta > a.elementor-item {
  background-color: var(--e-global-color-accent);
  color: var(--e-global-color-primary) !important;
  border-radius: 3px;
  padding: 10px 18px !important;
}

/* Visible focus states — blueprint §9 accessibility.

   A FOCUS RING IS A NON-TEXT UI COMPONENT judged at 3:1 against what surrounds
   it (WCAG 1.4.11, and 2.4.11 for the indicator itself). Brand gold `accent`
   #B98A2E is 4.59:1 on green-deep but only 2.91:1 on ivory — so a single ring
   colour cannot serve both grounds. This is the SAME three-golds problem as
   D-31, and it gets the same answer: pick the gold that suits the ground.

     dark ground  (utility bar, footer) -> crgoldtext  #C99D3D  5.71:1
     light ground (header bar, 404)     -> crgolddeep  #896622  4.92:1

   check-contrast.php enforces both pairs at a 3.0 threshold. */
.cr-header .cr-utility a:focus-visible,
.cr-footer a:focus-visible {
  outline: 2px solid var(--e-global-color-crgoldtext);
  outline-offset: 3px;
}

.cr-header .cr-headerbar a:focus-visible,
.cr-404 a:focus-visible {
  outline: 2px solid var(--e-global-color-crgolddeep);
  outline-offset: 3px;
}

/* ---------------------------------------------------------------------------
   Footer
   --------------------------------------------------------------------------- */

.cr-footer a {
  text-decoration: none;
}

.cr-footer a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* The logo is a dark-ground exception: the mark's navy and green disappear on
   dark green (D-22), so on the footer it sits on a small ivory plate rather
   than being dropped onto the band directly. */
.cr-footer .cr-footer-logo img {
  background-color: var(--e-global-color-crivory);
  padding: 10px 12px;
  border-radius: 3px;
}

/* ===========================================================================
   LIFT — one interaction vocabulary, three consumers.

   .cr-pcard    practice-area cards (template 57)  — links, so focusable
   .cr-whycard  "Why ComplyRakshak" cards (§07)    — not links, decorative
   .cr-mvblock  mission / vision blocks (§06)      — not links, decorative

   Deliberately ONE rule set rather than three: the page should have a single
   hover language, and a second vocabulary is how that drifts.

   Structure, colour and radius come from Elementor Globals. Only the shadow,
   the transitions and the arrow behaviour live here — a box-shadow cannot bind
   to a Global (D-30), and doing it in CSS with var() keeps the hex count at
   zero rather than adding another hardcoded exception.
   =========================================================================== */

.cr-pcard,
.cr-whycard,
.cr-engcard,
.cr-officecard,
.cr-mvblock {
  /* Soft, single-layer resting shadow derived from a Global, not a raw hex. */
  box-shadow: 0 2px 10px color-mix(in srgb, var(--e-global-color-crmutedonlite) 14%, transparent);
  transition:
    transform    200ms ease-out,
    box-shadow   200ms ease-out,
    border-color 200ms ease-out;
  will-change: transform;
}

/* Only the practice cards are links. Kill the inherited underline; the other
   two are plain containers and must NOT imply clickability. */
.cr-pcard {
  text-decoration: none;
}

/* --- The lift ------------------------------------------------------------ */

.cr-pcard:hover,
.cr-pcard:focus-visible,
.cr-pcard:focus-within,
.cr-whycard:hover,
.cr-engcard:hover,
.cr-officecard:hover,
.cr-mvblock:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 24px color-mix(in srgb, var(--e-global-color-crmutedonlite) 26%, transparent);
  border-color: var(--e-global-color-crgolddeep) !important;
}

/* Mission/vision is the quietest of the three — decorative only, so it gets the
   same movement but a lighter shadow and keeps its hairline border rather than
   pulling gold. It should read as responsive, not as clickable. */
.cr-mvblock:hover {
  box-shadow: 0 8px 18px color-mix(in srgb, var(--e-global-color-crmutedonlite) 18%, transparent);
  border-color: var(--e-global-color-crruleonlite) !important;
}

/* --- Arrow affordance (practice cards only) ------------------------------ */

.cr-pcard .cr-pcard-arrow {
  margin-top: auto;
  padding-top: 6px;
  transition: transform 200ms ease-out;
}

.cr-pcard:hover .cr-pcard-arrow,
.cr-pcard:focus-visible .cr-pcard-arrow,
.cr-pcard:focus-within .cr-pcard-arrow {
  transform: translateX(4px);
}

/* --- Focus ---------------------------------------------------------------
   Only on the real link. A lift alone is not a focus indicator, so the ring is
   in addition to it, never instead of it. .cr-whycard and .cr-mvblock are not
   interactive and deliberately have no focus styling and no cursor change. */

.cr-pcard:focus-visible {
  outline: 2px solid var(--e-global-color-crgolddeep);
  outline-offset: 3px;
}

/* ===========================================================================
   SECTION RHYTHM — no white strips between bands (batch 2 item 3, D-117)

   A Template widget placed at the top level of a page has no `.e-con`
   ancestor, so Elementor's
       .elementor-widget:not(:last-child) { margin-block-end: var(--kit-widget-spacing, 20px) }
   gives it a 20px bottom margin. The margin is transparent: the page's white
   background showed through as a strip between colour bands, 16 times on 11
   pages. tpl() stamps `cr-tpl` on every such widget (see the note there on why
   the old `_margin` setting never reached this element).

   0,3,0 beats Elementor's 0,2,0 on specificity, not on stylesheet order.
   =========================================================================== */

.elementor-widget.elementor-widget-template.cr-tpl {
  margin-block-end: 0;
}

/* ===========================================================================
   SLIDER — the ONE slider component (revision batch 2, items 8 and 11; D-114)

   Consumers: template 57 (.cr-slider--4, practice areas, slides are links) and
   the service pages' scope block (.cr-slider--3.cr-slider--wide-only, D-121,
   slides are not links). Template 232 (why ComplyRakshak) WAS one; it became a
   plain 3x2 grid in D-125.
   Markup: cr_slider_track() in lib-elementor-grid.php. Behaviour: js/cr-slider.js.

   The base layer is a native horizontal scroller with scroll-snap: it swipes
   on touch and works with no JavaScript at all. Slide widths come from the
   per-view count, so cards are never cut mid-card at rest.

   Never height:100vh, never transforms to move slides: every card stays a real
   element in document order, which is what keeps Tab order honest.
   =========================================================================== */

.cr-slider-track {
  --cr-slider-gap: 20px;
  --cr-slider-per: 1;
  --cr-slider-bleed: 8px;   /* room for focus rings and the -4px hover lift */
  display: flex !important;
  flex-wrap: nowrap !important;
  gap: var(--cr-slider-gap) !important;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* The bleed is padding inside the scroller, cancelled by a negative margin, so
     rings and lifts are not clipped by the overflow while the cards still line up
     with the section heading.

     The padding ADDS the bleed to Elementor's own child-container padding
     (--padding-*, 10px by default) rather than replacing it. Replacing it put
     the cards 10px left of the heading they sit under — measured, 120 vs 130. */
  padding:
    calc(var(--padding-top, 10px) + var(--cr-slider-bleed))
    calc(var(--padding-right, 10px) + var(--cr-slider-bleed))
    calc(var(--padding-bottom, 10px) + var(--cr-slider-bleed))
    calc(var(--padding-left, 10px) + var(--cr-slider-bleed)) !important;
  margin: calc(var(--cr-slider-bleed) * -1) !important;
  width: calc(100% + var(--cr-slider-bleed) * 2) !important;
  max-width: none !important;
  scroll-padding-inline: calc(var(--padding-left, 10px) + var(--cr-slider-bleed));
  scrollbar-width: none;
}

.cr-slider-track::-webkit-scrollbar {
  display: none;   /* the buttons and swipe are the affordance; see controls */
}

/* Slide width: (track - gaps) / per-view. Elementor gives child containers a
   width through its own custom properties, so the size is pinned explicitly. */
.cr-slider-track > .e-con,
.cr-slider-track > a.e-con {
  flex: 0 0 calc((100% - (var(--cr-slider-per) - 1) * var(--cr-slider-gap)) / var(--cr-slider-per)) !important;
  width: auto !important;
  max-width: none !important;
  min-width: 0 !important;
  scroll-snap-align: start;
}

.cr-slider--4 { --cr-slider-per: 4; }
.cr-slider--3 { --cr-slider-per: 3; }

@media (max-width: 1024px) {
  .cr-slider--4,
  .cr-slider--3 { --cr-slider-per: 2; }
}

/* Mobile: one card per view. The next card is NOT peeked in — one card means
   one card — so the buttons and the position readout carry the "there is more"
   signal. */
@media (max-width: 767px) {
  .cr-slider--4,
  .cr-slider--3 { --cr-slider-per: 1; }
}

/* NO VISIBLE COUNT on "Where We Come In" (D-132). Its readout said "1–3 of
   8", which stated the number of practice areas — and the site states no service
   count anywhere (D-106). The arrows and the peeking card carry "there is more".
   The readout is already aria-hidden; the separate screen-reader announcement
   after a button press is unchanged. Other sliders keep their readout. */
.cr-slider--peek + .cr-slider-controls .cr-slider-status {
  display: none;
}

/* PEEK (D-123) — "Where We Come In" only. Four whole cards read as a grid,
   so the next card is shown cut off at the edge: 3.5 per view on desktop,
   2.4 on tablet, 1.15 on phones. This deliberately reverses, for this slider,
   the "no peek on mobile" choice below. Slide width is the same formula, which
   takes a fractional per-view; snapping stays at each card's start. */
.cr-slider--4.cr-slider--peek { --cr-slider-per: 3.5; }

@media (max-width: 1024px) {
  .cr-slider--4.cr-slider--peek { --cr-slider-per: 2.4; }
}

@media (max-width: 767px) {
  .cr-slider--4.cr-slider--peek { --cr-slider-per: 1.15; }
}

/* LAPTOP-AND-UP ONLY (D-121). At 1024px and below the track stops being a
   scroller and becomes a plain one-column list, so smaller screens scroll the
   page as they always did. cr-slider.js sees no overflow and hides the
   controls, drops the tab stop and the "carousel" description by itself. */
@media (max-width: 1024px) {
  .cr-slider-track.cr-slider--wide-only {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr);
    overflow: visible;
    scroll-snap-type: none;
  }
  .cr-slider-track.cr-slider--wide-only > .e-con {
    flex: none !important;
    width: auto !important;
  }
}

/* Service scope (D-121): "Last reviewed" shares the slider-controls row —
   left, with the buttons right — instead of taking its own row beneath. That
   row was what pushed the block 15px past one 1366x768 screen. Applies only
   while the controls are SHOWN (the script sets `hidden` when the track does
   not scroll, and never runs without JS), so otherwise the line stays in its
   own row. Width is capped short of the buttons so it never sits over them
   and takes their clicks. -76px = the 44px controls row + the band's 32px gap,
   +12px to centre the 20px line on the 44px buttons. */
.cr-svc-handle .cr-slider-controls:not([hidden]) + .elementor-widget-html {
  margin-top: -64px;
  max-width: calc(100% - 220px);
}

/* The heading and cards sit in child containers with Elementor's 10px inline
   padding; the line is a bare widget and stood 10px outside them. */
.cr-svc-handle .elementor-widget-html:has(> .cr-lastreviewed),
.cr-svc-handle .elementor-widget-html:has(> .elementor-widget-container > .cr-lastreviewed) {
  padding-inline-start: 10px;
}

/* The non-link slider's track is the tab stop (js/cr-slider.js). Same ring as
   every other control on a light ground — crgolddeep, 4.92:1 on ivory (D-61). */
.cr-slider-track:focus-visible {
  outline: 2px solid var(--e-global-color-crgolddeep);
  outline-offset: -2px;
  border-radius: 6px;
}

.cr-slider-controls {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 16px;
  /* Line the Next button up with the right edge of the cards, which carry
     Elementor's 10px container padding inside the track (D-121). */
  padding-inline-end: 10px;
}

.cr-slider-controls[hidden] {
  display: none !important;
}

.cr-slider-status {
  margin: 0;
  min-width: 7ch;
  text-align: center;
  font-family: var(--e-global-typography-crsmall-font-family), sans-serif;
  font-size: var(--e-global-typography-crsmall-font-size);
  font-variant-numeric: tabular-nums;
  color: var(--e-global-color-crmutedonlite);
}

/* 44px targets (WCAG 2.5.8 comfortably). The border is FUNCTIONAL, not
   decoration: it is what locates the control, so it is judged at 3:1 —
   crgolddeep on ivory 4.92:1. Chevron navy (primary) 15.70:1. */
.cr-slider-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--e-global-color-crgolddeep);
  border-radius: 50%;
  background: var(--e-global-color-crivory);
  color: var(--e-global-color-primary);
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}

.cr-slider-btn:hover {
  background: var(--e-global-color-primary);
  color: var(--e-global-color-crivory);
}

.cr-slider-btn:focus-visible {
  outline: 2px solid var(--e-global-color-crgolddeep);
  outline-offset: 3px;
}

/* Reachable and announced at the ends, but visibly inert. */
.cr-slider-btn[aria-disabled="true"] {
  opacity: .4;
  cursor: default;
}

.cr-slider-btn[aria-disabled="true"]:hover {
  background: var(--e-global-color-crivory);
  color: var(--e-global-color-primary);
}

@media (prefers-reduced-motion: reduce) {
  .cr-slider-track {
    scroll-behavior: auto;
  }
  .cr-slider-btn {
    transition: none;
  }
}

/* ===========================================================================
   MOTION

   Reveals are Elementor's NATIVE entrance animations (fadeInUp) with native
   per-item animation_delay for the stagger. Only the count-up is hand-written.

   Elementor hides pending elements with .elementor-invisible, which uses
   visibility rather than display — the box is already laid out, so revealing it
   causes no layout shift and no CLS.
   =========================================================================== */

/* Above-the-fold content never animates in. The hero is painted on load;
   revealing it costs perceived performance and buys nothing. Belt-and-braces
   in case an entrance animation is ever set on a hero child by accident. */
.cr-hero .elementor-invisible {
  visibility: visible !important;
  animation: none !important;
}

.cr-countup {
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
   prefers-reduced-motion: reduce
   Everything lands in its final state immediately. This must also neutralise
   Elementor's own entrance animations, which do not respect the media query on
   their own — without this block the reveals still run.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {

  .cr-pcard,
  .cr-whycard,
  .cr-engcard,
  .cr-officecard,
  .cr-mvblock,
  .cr-pcard .cr-pcard-arrow {
    transition: none !important;
  }

  .cr-pcard:hover,
  .cr-pcard:focus-visible,
  .cr-pcard:focus-within,
  .cr-whycard:hover,
  .cr-engcard:hover,
  .cr-officecard:hover,
  .cr-mvblock:hover {
    transform: none;
  }

  /* Service pages, audience cards and archive cards: hovers. The
     border-colour CHANGE stays — it carries the affordance; only the movement
     and the easing go. */
  .cr-svc-card,
  .cr-relcard,
  .cr-archive-loop article.elementor-post {
    transition: none !important;
  }

  .cr-relcard:hover {
    transform: none;
  }

  /* Contact form: the checkbox colour transition and the submit lift. The
     border-colour and fill CHANGES stay — they carry state and removing them
     would remove the affordance; only the movement and the easing go. */
  .cr-contact-form input[type="checkbox"],
  .cr-contact-form .elementor-button {
    transition: none !important;
  }

  .cr-contact-form .elementor-button:hover,
  .cr-contact-form .elementor-button:focus-visible {
    transform: none;
  }

  .cr-pcard:hover .cr-pcard-arrow,
  .cr-pcard:focus-visible .cr-pcard-arrow,
  .cr-pcard:focus-within .cr-pcard-arrow {
    transform: none;
  }

  /* Elementor entrance animations: show the element, skip the keyframes. */
  .elementor-invisible {
    visibility: visible !important;
    opacity: 1 !important;
    animation: none !important;
  }

  .animated,
  .elementor-element.animated {
    animation: none !important;
    transition: none !important;
  }
}

/* ===========================================================================
   SERVICE PAGES
   Structure comes from build-scripts/lib-service-page.php. Everything below
   binds to Global CSS variables — no hex, no literal font sizes.
   =========================================================================== */

/* --- Breadcrumb ----------------------------------------------------------
   A real <nav><ol>. The separator is a ::before on each <li> after the first,
   so it is decorative generated content and is never read out as an item. */

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

.cr-breadcrumb li {
  font-family: var(--e-global-typography-crsmall-font-family), sans-serif;
  font-size: var(--e-global-typography-crlegal-font-size);
  color: var(--e-global-color-crmutedondark);
}

.cr-breadcrumb li + li::before {
  content: "/";
  margin-right: 8px;
  color: var(--e-global-color-crrulevisible);
}

.cr-breadcrumb a {
  color: var(--e-global-color-crmutedondark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cr-breadcrumb a:hover {
  color: var(--e-global-color-crivory);
}

/* Current page: ivory, not a link, and marked aria-current in the markup. */
.cr-breadcrumb [aria-current="page"] {
  color: var(--e-global-color-crivory);
}

.cr-breadcrumb a:focus-visible {
  outline: 2px solid var(--e-global-color-crgoldtext);
  outline-offset: 3px;
}

/* --- Audience pills ------------------------------------------------------
   A <ul>, so it announces as "list, four items". The pills are the list
   markers' replacement, hence list-style:none. */

.cr-pills {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0;
  padding: 0;
}

/* TYPOGRAPHY IN CSS-STYLED TEXT (batch 2 item 10, D-116)
   Text that lives in raw HTML (html widgets, form html fields) cannot take an
   Elementor typography control. It is bound instead to ONE Global's own CSS
   custom properties — family, size, weight, line-height and letter-spacing
   all from the same Global — so Site Settings stays the single source.
   Before this, rules mixed two Globals (family from `text`, size from
   `crsmall`) and hardcoded line-heights. Do not reintroduce literal values.
     .cr-pills li, .cr-form-sublabel             -> accent
     .cr-checklist li, .cr-benefits li, .cr-form-hint -> crsmall
     .cr-consent-notice p, .cr-lastreviewed      -> crlegal */

.cr-pills li {
  padding: 9px 18px;
  border: 1px solid var(--e-global-color-crruleonlite);
  border-radius: 999px;
  background: var(--e-global-color-crwhite);
  color: var(--e-global-color-text);
  font-family: var(--e-global-typography-accent-font-family), sans-serif;
  font-size: var(--e-global-typography-accent-font-size);
  font-weight: var(--e-global-typography-accent-font-weight);
  line-height: var(--e-global-typography-accent-line-height);
  letter-spacing: var(--e-global-typography-accent-letter-spacing);
}

/* --- What we handle cards ------------------------------------------------ */

.cr-svc-card {
  transition: border-color 140ms ease;
}

.cr-svc-card:hover {
  border-color: var(--e-global-color-crgolddeep);
}

/* --- Documents checklist -------------------------------------------------
   The tick is generated content: decorative, and the <ul>/<li> semantics
   carry the meaning. Two columns on desktop so a five-item list does not
   become a tall thin ribbon. */

.cr-checklist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 28px;
}

@media (max-width: 767px) {
  .cr-checklist {
    grid-template-columns: minmax(0, 1fr);
  }
}

.cr-checklist li {
  position: relative;
  padding-left: 30px;
  font-family: var(--e-global-typography-crsmall-font-family), sans-serif;
  font-size: var(--e-global-typography-crsmall-font-size);
  font-weight: var(--e-global-typography-crsmall-font-weight);
  line-height: var(--e-global-typography-crsmall-line-height);
  letter-spacing: var(--e-global-typography-crsmall-letter-spacing);
  color: var(--e-global-color-text);
}

/* Drawn, not an icon font and not an SVG: it inherits currentColor, survives
   forced-colors, and costs no request. */
.cr-checklist li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 6px;
  width: 10px;
  height: 6px;
  border: 2px solid var(--e-global-color-crgolddeep);
  border-top: 0;
  border-right: 0;
  transform: rotate(-45deg);
}

/* --- "Why look at this" benefit points (GIFT IFSC only) ------------------
   A <ul> on the dark band. Same drawn tick as the documents checklist, in the
   dark-ground gold: crgoldtext #C99D3D on crgreendeep is 5.71:1, well clear of
   the 3:1 a non-text mark needs. `crgolddeep` would be 2.72:1 here and is
   banned on dark by the contrast gate. */

.cr-benefits {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 32px;
}

@media (max-width: 767px) {
  .cr-benefits {
    grid-template-columns: minmax(0, 1fr);
  }
}

.cr-benefits li {
  position: relative;
  padding-left: 30px;
  font-family: var(--e-global-typography-crsmall-font-family), sans-serif;
  font-size: var(--e-global-typography-crsmall-font-size);
  font-weight: var(--e-global-typography-crsmall-font-weight);
  line-height: var(--e-global-typography-crsmall-line-height);
  letter-spacing: var(--e-global-typography-crsmall-letter-spacing);
  color: var(--e-global-color-crmutedondark);
}

.cr-benefits li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 6px;
  width: 10px;
  height: 6px;
  border: 2px solid var(--e-global-color-crgoldtext);
  border-top: 0;
  border-right: 0;
  transform: rotate(-45deg);
}

/* ===========================================================================
   ENTRY DISCLAIMER INTERSTITIAL

   Markup: inc/disclaimer-interstitial.php. Copy: saved template #67.
   Behaviour: js/cr-disclaimer.js.

   Ground is navy `primary`, which is what template #67 already uses, so every
   pair inside it is the navy column of the contrast gate.
   =========================================================================== */

.cr-disclaimer {
  position: fixed;
  inset: 0;
  z-index: 100000;      /* above Elementor's sticky header (z-index 99) */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

/* `hidden` on a flex container needs the override — [hidden] is display:none in
   the UA sheet but `display:flex` here beats it on specificity. */
.cr-disclaimer[hidden] {
  display: none;
}

.cr-disclaimer__backdrop {
  position: absolute;
  inset: 0;
  /* Deliberately opaque enough to make the page behind unreadable: the visitor
     has not yet agreed to read it. Not a brand colour, and nothing else
     references it — same documented-exception reasoning as D-30. */
  background: rgba(4, 28, 66, 0.82);
}

.cr-disclaimer__panel {
  position: relative;
  width: min(680px, 100%);
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  border-radius: 4px;
  border: 1px solid var(--e-global-color-crgoldtext);
  background: var(--e-global-color-primary);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
}

/* The panel is the initial focus target, and it scrolls when the copy is long —
   a scrollable region must be focusable and must show that it has focus. */
.cr-disclaimer__panel:focus-visible {
  outline: 2px solid var(--e-global-color-crgoldtext);
  outline-offset: 3px;
}

/* --- Buttons -------------------------------------------------------------
   Both come from template #67 as Elementor button widgets.

   AGREE  : navy on gold      5.39:1
   DECLINE: ivory text, gold-text border on navy — 13.38:1 text, and the border
            is 5.71:1 against the panel, well over the 3:1 needed to locate a
            control (1.4.11). A ghost button with no border would be ~1.2:1
            against navy and effectively invisible as a control. */

.cr-disclaimer .elementor-button {
  border-radius: 3px;
  transition: transform 140ms ease, box-shadow 140ms ease, background-color 140ms ease;
}

.cr-disclaimer .elementor-button:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}

.cr-disclaimer .elementor-button:active {
  transform: translateY(0);
  box-shadow: none;
}

/* Focus ring on gold-text: 5.71:1 against the navy panel. Both buttons get the
   same ring so neither reads as the "safe" one by styling alone. */
.cr-disclaimer .elementor-button:focus-visible {
  outline: 3px solid var(--e-global-color-crgoldtext);
  outline-offset: 3px;
}

.cr-disclaimer__content,
.cr-disclaimer__declined {
  padding: 36px 34px;
}

.cr-disclaimer__declined p {
  margin: 0 0 10px;
  font-family: var(--e-global-typography-text-font-family), sans-serif;
  font-size: var(--e-global-typography-crsmall-font-size);
  line-height: 1.6;
  color: var(--e-global-color-crmutedondark);
}

.cr-disclaimer__declined p strong {
  color: var(--e-global-color-crivory);
}

@media (max-width: 767px) {
  .cr-disclaimer {
    padding: 12px;
  }
  .cr-disclaimer__content,
  .cr-disclaimer__declined {
    padding: 26px 22px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cr-disclaimer .elementor-button {
    transition: none !important;
  }
  .cr-disclaimer .elementor-button:hover {
    transform: none;
  }
}

/* ===========================================================================
   ENGAGEMENT MODEL CARDS  (saved template 61 — homepage + /engagement-models)

   Three cards, uneven content: 4 / 4 / 3 inclusions, and one title that wraps
   to two lines while the other two do not. Both are in the blueprint and
   neither is padded away — the layout absorbs them instead.
   =========================================================================== */

/* --- Shared title baseline -----------------------------------------------
   MEASURED: at crh3 (28px) "Compliance Retainership" needs 338px on one line
   and the card gives it 317px — short by 21px, so it wraps while the other two
   sit on one line and every element below it starts 35px lower.

   TWO LINES ARE RESERVED FOR ALL THREE rather than shrinking the type. The
   type scale has no step between crh3 28px and crh4 22px (§13.3), so "reduce
   the title until it fits" would mean either a 6px drop that makes these read
   as card sub-headings, or a literal font-size — and this build has no literal
   font sizes outside the Globals.

   `lh` is one line-height of the element itself, so this follows the crh3
   Global automatically instead of hardcoding a pixel height. The `em` line is
   the fallback for browsers without `lh` (crh3 line-height is 1.25, so two
   lines is 2.5em); where `lh` is supported it overrides.

   ⚠ THE RULE MUST TARGET THE <h3>, NOT THE WIDGET WRAPPER. Elementor puts
   `_css_classes` on the wrapper div, which inherits the BODY font — 18px with a
   29.7px line-height. Put this on `.cr-engcard-title` itself and `2lh` resolves
   to 59.4px, not the 70px two lines of crh3 actually occupy, and the titles
   still do not line up. Any font-relative unit (em, lh, ex, ch) on a widget
   class has this problem. */
.cr-engcard-title .elementor-heading-title {
  display: block;
  min-height: 2.5em;
  min-height: 2lh;
}

/* --- Footer pinned to the card bottom ------------------------------------
   The cards are CSS Grid items and already stretch to equal height. Without
   this the "Ideal for" line sits directly under the last inclusion, so the
   three footers land at three different heights — 4, 4 and 3 items deep.
   `margin-top: auto` in the card's flex column pushes it to the bottom edge,
   which is what makes the row read as a grid rather than three lists. */
.cr-engcard > .cr-engcard-ideal {
  margin-top: auto;
  padding-top: 18px;
}

/* A hairline above the footer so it reads as a card footer rather than a
   stranded italic line after a gap. Decorative — it separates content from
   content on the same ground, so no contrast floor applies (cf. D-50, where
   the footer rule WAS the only division and therefore was functional). */
.cr-engcard > .cr-engcard-ideal {
  border-top: 1px solid var(--e-global-color-crruleonlite);
}

/* Two lines reserved for the footer text as well, for the same reason as the
   title: "Ideal for founders with a specific setup requirement." wraps while
   the other two do not. Bottom-pinning aligns the footers' BOTTOM edges, but
   the hairline above them then sits at three different heights. Reserving the
   height aligns the rules too.

   Again on the <p>, not the widget wrapper — `_css_classes` lands on the
   wrapper, where `lh` would resolve against the body font. */
.cr-engcard > .cr-engcard-ideal p {
  margin: 0;
  min-height: 2.6em;
  min-height: 2lh;
}

@media (max-width: 1024px) {
  .cr-engcard > .cr-engcard-ideal p {
    min-height: 0;
  }
}

/* The inclusion list should take the slack, so the footer has something to be
   pushed away from rather than the gap opening under the frame line. */
.cr-engcard > .cr-engcard-list {
  margin-bottom: 4px;
}

/* Below the grid breakpoint the cards stack and each sizes to its own content,
   so a reserved two-line title is just dead space — release it.

   And from 1280px up, since the titles moved to crh4 (D-124): at 22px all
   three fit one line once the container reaches its full 1200px (measured:
   "Compliance Retainership" 266px, each card has 317px), so the second
   reserved line was a gap under "Project Based" and "Advisory On Call".
   Between 1025 and 1279 that title can wrap, and the reservation still
   keeps the three frame lines level. */
@media (max-width: 1024px), (min-width: 1280px) {
  .cr-engcard-title .elementor-heading-title {
    min-height: 0;
  }
}

/* ===========================================================================
   INSIGHTS — archive and single article (Theme Builder templates)
   =========================================================================== */

/* The empty state. With no posts this IS the page, so it is given real space
   and a real measure rather than being a stranded line of grey text. */
.cr-archive-loop .elementor-posts-nothing-found {
  max-width: 62ch;
  padding: 28px 0 4px;
  font-family: var(--e-global-typography-crlead-font-family), sans-serif;
  font-size: var(--e-global-typography-crlead-font-size);
  font-weight: var(--e-global-typography-crlead-font-weight);
  line-height: var(--e-global-typography-crlead-line-height);
  letter-spacing: var(--e-global-typography-crlead-letter-spacing);
  color: var(--e-global-color-crmutedonlite);
}

/* Article cards, once posts exist. */
.cr-archive-loop article.elementor-post {
  background: var(--e-global-color-crwhite);
  border: 1px solid var(--e-global-color-crruleonlite);
  border-radius: 3px;
  overflow: hidden;
  transition: border-color 140ms ease;
}

.cr-archive-loop article.elementor-post:hover,
.cr-archive-loop article.elementor-post:focus-within {
  border-color: var(--e-global-color-crgolddeep);
}

.cr-archive-loop .elementor-post__text {
  padding: 22px 24px 24px;
}

.cr-archive-loop .elementor-post__read-more {
  font-family: var(--e-global-typography-accent-font-family), sans-serif;
  font-size: var(--e-global-typography-accent-font-size);
  font-weight: var(--e-global-typography-accent-font-weight);
  color: var(--e-global-color-crgolddeep);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cr-archive-loop a:focus-visible {
  outline: 2px solid var(--e-global-color-crgolddeep);
  outline-offset: 3px;
}

/* Pagination */
.cr-archive-loop .elementor-pagination .page-numbers {
  color: var(--e-global-color-text);
}

.cr-archive-loop .elementor-pagination .page-numbers.current {
  color: var(--e-global-color-crgolddeep);
  font-weight: 600;
}

/* --- Single article ------------------------------------------------------ */

.cr-single-meta .elementor-post-info__item {
  letter-spacing: 1.6px;
}

/* Article prose. The measure is set by the 72% container in the template; this
   is the vertical rhythm and the link treatment inside it. */
.cr-single-body p {
  margin: 0 0 18px;
  line-height: 1.7;
}

.cr-single-body h2 {
  font-family: var(--e-global-typography-secondary-font-family), serif;
  font-size: var(--e-global-typography-secondary-font-size);
  color: var(--e-global-color-primary);
  margin: 36px 0 12px;
}

.cr-single-body h3 {
  font-family: var(--e-global-typography-crh3-font-family), serif;
  font-size: var(--e-global-typography-crh3-font-size);
  color: var(--e-global-color-primary);
  margin: 28px 0 10px;
}

.cr-single-body ul,
.cr-single-body ol {
  margin: 0 0 18px 20px;
  line-height: 1.7;
}

/* Prose links: navy on ivory is 15.70:1, but colour alone is not a link cue
   (1.4.1), so they are underlined — same rule as the contact page. */
.cr-single-body a {
  color: var(--e-global-color-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cr-single-body a:hover {
  color: var(--e-global-color-crgolddeep);
}

.cr-single-body a:focus-visible {
  outline: 2px solid var(--e-global-color-crgolddeep);
  outline-offset: 3px;
}

/* The standing line required on anything carrying a statutory position
   (blueprint §8 item 6). Set apart from the article body by a rule. */
.cr-single-standing {
  margin: 6px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--e-global-color-crruleonlite);
  font-family: var(--e-global-typography-crlegal-font-family), sans-serif;
  font-size: var(--e-global-typography-crlegal-font-size);
  color: var(--e-global-color-crmutedonlite);   /* no italics in content (D-124) */
}

/* AUDIENCE PAGES (/who-we-serve, /startups, /established-companies): styles
   removed with the pages in client revision round 1, 2026-09-14 (D-100). */

/* --- Related service cards ----------------------------------------------
   The whole card is the click target, via a stretched ::after on the anchor.
   The anchor itself still wraps the title, so it is ONE tab stop with a real
   accessible name — not a div with a click handler. */

.cr-relcard {
  position: relative;
  transition: border-color 140ms ease, transform 140ms ease;
}

.cr-relcard-title {
  margin: 0;
  font-family: var(--e-global-typography-crh4-font-family), sans-serif;
  font-size: var(--e-global-typography-crh4-font-size);
  font-weight: var(--e-global-typography-crh4-font-weight);
  line-height: 1.3;
}

.cr-relcard-title a {
  color: var(--e-global-color-crivory);
  text-decoration: none;
}

/* ⚠ Elementor gives every widget wrapper `position: relative`, which makes IT
   the containing block for the stretched overlay instead of the card — so
   `inset: 0` sized to the title block and only the title was clickable, not
   the card. Measured with elementFromPoint, not assumed.

   Neutralising the wrapper inside this card hands the containing block back to
   `.cr-relcard`. Scoped to the card so nothing else is affected. */
.cr-relcard > .elementor-element {
  position: static;
}

.cr-relcard-title a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 3px;
}

.cr-relcard:hover {
  border-color: var(--e-global-color-crgoldtext);
  transform: translateY(-2px);
}

.cr-relcard:hover .cr-relcard-title a {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* The ring goes on the CARD, not on the inline anchor — the anchor's own box
   is just the title text, so a ring there would not enclose the target the
   user is actually activating. */
.cr-relcard:focus-within {
  outline: 2px solid var(--e-global-color-crgoldtext);
  outline-offset: 3px;
}

.cr-relcard-title a:focus-visible {
  outline: none;
}

/* ---------------------------------------------------------------------------
   DATA TABLES — the compliance calendar and every service page's
   "Forms & timelines". Markup comes from cr_data_table() in
   build-scripts/lib-elementor-widgets.php; this is the only styling for it.

   Previously an inline <style> inside the calendar template. Moved here when
   the service pages needed the same table, so there is one implementation
   rather than one per page.

   `min-width` is set per table as an inline style, because the width at which
   a table has to start scrolling depends on how many columns it has.
   --------------------------------------------------------------------------- */

.cr-datatable-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
}

/* The scroll region is focusable (it must be, or the right-hand columns are
   unreachable by keyboard), so it needs a ring of its own. crgolddeep is
   4.92:1 on ivory and 4.51:1 on tint — both clear the 3:1 for an indicator. */
.cr-datatable-scroll:focus-visible {
  outline: 2px solid var(--e-global-color-crgolddeep);
  outline-offset: 2px;
}

.cr-datatable {
  width: 100%;
  border-collapse: collapse;
}

.cr-datatable th,
.cr-datatable td {
  text-align: left;
  padding: 14px 16px;
  border-bottom: 1px solid var(--e-global-color-crruleonlite);
  font-family: var(--e-global-typography-crtable-font-family), sans-serif;
  font-size: var(--e-global-typography-crtable-font-size);
  font-weight: 400;
  vertical-align: top;
}

.cr-datatable thead th {
  color: var(--e-global-color-primary);
  font-weight: 600;
  border-bottom-width: 2px;
  white-space: nowrap;
}

.cr-datatable tbody th {
  color: var(--e-global-color-primary);
  font-weight: 600;
}

.cr-datatable td {
  color: var(--e-global-color-text);
  font-variant-numeric: tabular-nums;
}

.cr-datatable tbody tr:last-child th,
.cr-datatable tbody tr:last-child td {
  border-bottom: 0;
}

/* ---------------------------------------------------------------------------
   Visually hidden, still announced.
   Used by js/cr-countup.js to hand assistive technology the FINAL figure while
   the digits animate behind aria-hidden. Not `display:none` and not
   `visibility:hidden` — both remove the text from the accessibility tree.
   --------------------------------------------------------------------------- */
.cr-sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ===========================================================================
   IMAGES
   =========================================================================== */

.cr-picture {
  display: block;
}

.cr-picture-img {
  display: block;
  width: 100%;
  height: auto;          /* honours the intrinsic ratio from width/height */
  border-radius: 4px;
}

/* NO SCRIM ON THE HERO IMAGE — removed 2026-09-09, and the reason matters.

   This used to carry `filter: saturate(0.9) brightness(0.92)`, described in its
   own comment as a scrim for "a future colour photograph" that would otherwise
   punch a bright hole in the dark band.

   That future asset has now arrived, and it is not a photograph. It is brand
   artwork (design-source/hero-composition.svg) whose every colour is already a
   brand token, FLATTENED ONTO #0C3116 — the band's own ground — so that it
   needs no alpha channel.

   A filter applies to the whole raster, including that flattened background. So
   the scrim darkened the panel away from the band it was supposed to match:
   measured, the band painted #0C3116 and the image painted #0E2C17, a 5/255
   edge across a large flat field, which reads as a visible rectangle.

   If a photographic hero is ever used instead, reinstate the scrim — but note
   it will only be seamless with a transparent PNG, or with an image that fills
   the slot edge to edge. */

/* ===========================================================================
   GIFT BAND — image layer + desktop-only parallax

   The image is a ::before layer BEHIND the band's solid green-deep ground, not
   an Elementor background. Two reasons:
     - image-set() gives WebP with a JPEG fallback, which Elementor's background
       control cannot express.
     - Keeping the band's own background a solid Global means the contrast gate
       still measures a real colour, and the text/ground pair stays knowable.

   NEVER background-attachment: fixed. It forces a full-band repaint on every
   scroll frame and is simply broken on iOS.
   =========================================================================== */

.cr-parallax {
  position: relative;
  overflow: hidden;      /* contains the layer's travel — no page-level scrollbar */
  isolation: isolate;    /* keeps the layer behind content without z-index wars */
}

.cr-parallax::before {
  content: "";
  position: absolute;
  /* Oversized vertically so the travel never exposes an edge. */
  inset: -80px 0;
  z-index: 0;
  pointer-events: none;
  /* background-image is NOT set here.

     It used to be a hardcoded image-set() pointing straight at
     images/placeholders/gift-1920.*, which made this the one image on the site
     that could not be changed without editing the stylesheet — and it only ever
     loaded the 1920 file, on phones included.

     It is now emitted by complyrakshak_gift_background_css() in inc/picture.php
     from the `gift` slug, so it resolves through Appearance > Customize > Site
     Images like every other slot, and picks a width by media query. Everything
     else about the layer — the scrim opacity, the travel, the containment —
     stays here, because none of it depends on which file is behind it. */
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
  /* The scrim. Fixed and opaque enough that the text/ground pair is effectively
     the solid green-deep the gate measures, whatever photo eventually lands. */
  opacity: 0.16;
  will-change: transform;
  /* Driven by js/cr-parallax.js, which sets --cr-parallax-y on the band.
     A pseudo-element cannot be styled directly from JS, but it can read a
     custom property set on its host - so the moving layer needs no extra DOM. */
  transform: translate3d(0, var(--cr-parallax-y, 0px), 0);
}

/* Content must sit above the layer. */
.cr-parallax > .e-con-inner,
.cr-parallax > * {
  position: relative;
  z-index: 1;
}

/* Static below 1025px — the script never binds there, this is the visual guard. */
@media (max-width: 1024px) {
  .cr-parallax::before {
    inset: 0;
    transform: none !important;
    will-change: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cr-parallax::before {
    inset: 0;
    transform: none !important;
    will-change: auto;
  }
}

/* ===========================================================================
   FAQ / ACCORDION QUESTION HEADERS

   Elementor's title typography control targets the inner
   `a.elementor-accordion-title` only. The element that actually wraps it is
   `h3.elementor-tab-title`, which Elementor gives font-weight and line-height
   but NO font-size — so it falls back to the browser's `h3 { font-size: 1.17em }`
   and compounds against whatever it inherits. That also sizes the open/close
   icon, which is `1.5em` of the h3, not of the link.

   So the question row was sized by an inherited em, not by anything anyone set.

   These rules pin the h3 to the SAME Global as the link. They read the Global's
   custom properties rather than hardcoding, so this is not a one-off override:
   change the `crfaq` Global and both the link and its wrapper move together, on
   the homepage and on all eight service pages that will reuse the block.
   =========================================================================== */

.cr-faq .elementor-tab-title {
  font-family: var(--e-global-typography-crfaq-font-family), sans-serif;
  font-size: var(--e-global-typography-crfaq-font-size);
  font-weight: var(--e-global-typography-crfaq-font-weight);
  line-height: var(--e-global-typography-crfaq-line-height);
  letter-spacing: var(--e-global-typography-crfaq-letter-spacing);
}

/* The link inherits from the h3 now that the h3 is authoritative, so it cannot
   drift from its own wrapper. */
.cr-faq .elementor-accordion-title {
  font-size: inherit;
  line-height: inherit;
  font-weight: inherit;
}

/* Long questions wrap to two lines at 390px. Keep the wrap tidy: the text must
   not run under the icon, and a trailing single word is avoided by letting the
   line box breathe rather than by hyphenating. */
.cr-faq .elementor-tab-title {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  text-wrap: pretty;          /* avoids a one-word last line where supported */
}

.cr-faq .elementor-accordion-icon {
  flex: 0 0 auto;
  width: auto;                /* overrides Elementor's 1.5em, which scaled with the h3 */
  line-height: inherit;
}

.cr-faq .elementor-accordion-title {
  flex: 1 1 auto;
}

/* ===========================================================================
   HEADER ALIGNMENT

   The nav and CTA sit in a flex row with the logo. Elementor's container
   align-items did not reach `.cr-headerbar` (computed `normal`), so the three
   children were only incidentally level — and once the nav wrapped to two rows
   the row height grew and the items read as riding low against the logo.

   Pinned here rather than fought through the container control.
   =========================================================================== */

.cr-headerbar {
  align-items: center !important;
}

.cr-headerbar > * {
  align-self: center;
}

/* The nav's own list must centre against the logo lockup too, not sit on the
   text baseline.

   ⚠ SCOPED TO min-width:900px, AND THAT IS LOAD-BEARING — NOT TIDINESS.
   ------------------------------------------------------------------------
   Elementor hides the desktop nav below the mobile breakpoint with

       @media (max-width: 899px) {
         .elementor-nav-menu--dropdown-mobile_extra .elementor-nav-menu--main
           { display: none }
       }                                          <- specificity 0,2,0

   The rule below is ALSO 0,2,0 and was unconditional, so on equal specificity
   it won on source order (the child theme loads after Elementor). The desktop
   nav therefore stayed `display: flex` at every width while the hamburger
   correctly appeared below 900px — which is what "two menus on mobile" was.

   The nav widget was never duplicated: ONE nav-menu widget renders both
   `--main` and `--dropdown` by design, and only one should display. The fix is
   to stop overriding the rule that decides which, not to add `!important` or a
   counter-rule that fights it.

   900px is `viewport_md` (§13.4), so this boundary and Elementor's are the same
   number by construction. If the breakpoint moves, move it in the kit and this
   query follows it — do not hardcode a second value. */
@media (min-width: 900px) {

  .cr-nav .elementor-nav-menu--main,
  .cr-nav .elementor-nav-menu--main > li,
  .cr-nav .elementor-nav-menu--main > li > a {
    display: flex;
    align-items: center;
  }

  .cr-nav .elementor-nav-menu--main {
    flex-wrap: nowrap; /* one row: the CTA is a button widget, not a menu item */
  }
}

/* ---------------------------------------------------------------------------
   Dropdown carets

   Elementor renders the caret as an inline SVG that sits on the text baseline,
   so it reads slightly low against the cap height of the label. Nudge it to the
   optical centre and give it a little breathing room.
   --------------------------------------------------------------------------- */

.cr-nav .elementor-nav-menu--main .sub-arrow {
  display: inline-flex;
  align-items: center;
  margin-inline-start: 5px;
}

.cr-nav .elementor-nav-menu--main .sub-arrow svg {
  width: 0.7em;
  height: 0.7em;
  position: relative;
  top: 1px;            /* optical, not metric: the glyph is bottom-heavy */
}

/* ---------------------------------------------------------------------------
   CTA focus state

   The button had a hover state and inherited focus styling only from the
   generic header rule. Give it its own visible focus-visible ring — keyboard
   users must get an indicator at least as clear as the pointer affordance.
   --------------------------------------------------------------------------- */

.cr-header-cta .elementor-button:focus-visible {
  outline: 3px solid var(--e-global-color-primary);
  outline-offset: 3px;
}

/* Hover/focus darkens the BORDER, not the fill.
   Darkening the fill to gold-deep would put navy text on #896622 at 3.19:1 and
   fail AA - measured before shipping, not after. The border is non-text, so it
   carries the state change at 15.70:1 against the ivory header without touching
   the text pair, which stays navy-on-gold at 5.39:1. */
.cr-header-cta .elementor-button:hover,
.cr-header-cta .elementor-button:focus-visible {
  border-color: var(--e-global-color-primary) !important;
}

@media (prefers-reduced-motion: reduce) {
  .cr-header-cta .elementor-button {
    transition: none;
  }
}

/* ---------------------------------------------------------------------------
   Nav fit in the compact range (900-1279px)

   Measured, not guessed: at 1024 the seven items need 771px and the list has
   665px, so it wrapped to two rows. Elementor's `space_between` becomes
   horizontal PADDING on each link, which is why "Home" was 80px wide for four
   characters. Trimming that padding and the CTA recovers the ~110px needed.

   The range is 900-1279, NOT tied to the 1024 tablet breakpoint. Measured: the
   desktop sizing needs ~1160px of inner width, which a 1200px viewport does not
   have (1200 - 48 padding = 1152), so 1200 wrapped even though it is "desktop".
   Sizing has to follow the space available, not the breakpoint name.

   Below 900 the hamburger takes over and none of this applies.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   BELOW 900 — the drawer takes the full row.

   This was latent until the desktop nav actually started hiding (see the
   min-width:900 note above). The nav widget sits in a flex row beside the logo,
   so the drawer inherited the width of that flex item — measured at 173px in a
   390px viewport, a narrow column of links pinned to the right with the logo
   vertically centred against its full height.

   Letting the row wrap and giving the nav widget the whole second line puts the
   menu under the header bar where it belongs. The toggle stays right-aligned on
   the first line.

   Kept as an INLINE panel (`position: static`), deliberately — it pushes the
   page down rather than covering it, which is why it needs no focus trap. See
   menuEscape() in js/cr-a11y.js.
   --------------------------------------------------------------------------- */

@media (max-width: 899px) {

  /* The bar is ONE row: [logo] ........ [CTA] [toggle], with the drawer on its
     own full-width line beneath. (Revision batch 2, item 1 — D-113. It was
     [logo][CTA] / [toggle] / [drawer]: three lines, 187px, which made the
     compact band impossible because no single centre line held the toggle.)

     `display: contents` on the nav widget promotes its three children — the
     hidden desktop nav, the toggle, and the drawer — to flex items of the bar,
     so the toggle can sit inline while the drawer takes a line of its own. The
     DOM is unchanged, so Elementor's toggle script and the drawer's aria state
     work as before, and the drawer stays an inline panel (`position: static`):
     the no-focus-trap reasoning in D-82 still holds. */
  .cr-header .cr-headerbar .e-con-inner {
    flex-wrap: wrap;
    align-items: center;
    row-gap: 0;
    column-gap: 12px;
  }

  /* Specificity 0,4,0 is deliberate: Elementor's
     `.elementor-widget-nav-menu:not(:has(.elementor-widget-container)):not([class*="elementor-hidden-"])`
     sets display:flex at 0,3,0, and a plain `.cr-header .cr-nav` (0,2,0) lost to
     it silently — the rule matched and did nothing. Measured with CDP. */
  .cr-header .cr-headerbar .cr-nav.elementor-widget-nav-menu {
    display: contents;
  }

  .cr-header .cr-header-cta {
    order: 2;
    margin-inline-start: auto;   /* CTA and toggle hug the right edge together */
  }

  .cr-header .cr-nav .elementor-menu-toggle {
    order: 3;
  }

  .cr-header nav.elementor-nav-menu--dropdown {
    order: 4;
    flex-basis: 100%;
    width: 100%;
  }

  /* Elementor spaces the drawer 10px below the toggle even while it is CLOSED
     and 0px tall, which left an empty 10px line in the bar (D-118). The gap is
     only wanted when there is a drawer to separate. Specificity beats the
     per-element `dropdown_top_distance` rule. */
  .cr-header .cr-headerbar .cr-nav .elementor-menu-toggle ~ nav.elementor-nav-menu--dropdown.elementor-nav-menu__container {
    margin-top: 0;
  }

  .cr-header .cr-headerbar .cr-nav .elementor-menu-toggle.elementor-active ~ nav.elementor-nav-menu--dropdown.elementor-nav-menu__container {
    margin-top: 10px;
  }

}

/* Narrow phones: smaller CTA (the logo is already 44px via width_mobile) so [logo][CTA][toggle] holds one row down
   to 360px. Below that the row may wrap, and js/cr-header.js then leaves the
   sticky header at full height rather than clip the toggle away.

   Specificity is raised on purpose: Elementor's per-element rules
   (`.elementor-70 .elementor-element.elementor-element-<id> …`, 0,3,x-0,4,0)
   silently beat a plain class rule, as the first attempt proved. */
@media (max-width: 480px) {
  .cr-header .cr-headerbar .cr-header-cta.elementor-widget-button .elementor-button {
    padding: 10px 14px;
    font-size: 14px;
  }

  /* The toggle is a 40px target; give the links the same generous hit area
     rather than the tighter desktop rhythm. */
  .cr-header nav.elementor-nav-menu--dropdown a.elementor-item {
    padding-block: 12px;
  }
}

@media (max-width: 1279px) and (min-width: 900px) {

  .cr-nav .elementor-nav-menu--main > ul.elementor-nav-menu > li > a.elementor-item {
    padding-inline: 4px;
    font-size: 13px;
    letter-spacing: 0;
  }

  /* Caret takes its own space; keep it tight at this width. */
  .cr-nav .elementor-nav-menu--main .sub-arrow {
    margin-inline-start: 2px;
  }

  .cr-nav .elementor-nav-menu--main .sub-arrow svg {
    width: 0.6em;
    height: 0.6em;
  }

  .cr-header-cta .elementor-button {
    padding: 10px 14px;
    font-size: 14px;
  }

  .cr-headerbar {
    column-gap: 12px;
  }
}

/* ===========================================================================
   FOOTER

   Column widths, band padding and the grid live in the Theme Builder template.
   What lives here is the shared rhythm — the things that must be identical in
   all four columns and were only incidentally so.
   =========================================================================== */

/* One heading treatment, one bottom margin, all four columns.
   The column flex gap is 12px; the extra 4px here makes heading-to-list 16px,
   so a heading separates from its list more than the list items separate from
   each other. Both values are on the 8px scale. */
/* Specificity note: Elementor ships `.e-con .elementor-widget:not(:last-child)`
   which outranks a two-class selector, so this needs the .e-con in the chain to
   win rather than an !important. */
.cr-footer .e-con .cr-footer-heading:not(:last-child) {
  margin-block-end: 4px;
}

/* ---------------------------------------------------------------------------
   BARE <a> INSIDE FOOTER TEXT WIDGETS — the same bug as the icons, one layer up.

   Elementor's kit emits `.elementor-kit-5 a { color: #041C42 }` (navy), which
   targets the anchor DIRECTLY. A text-editor widget binds `text_color` on its
   own wrapper, so the prose inherits ivory — but any <a> inside it is hit by
   the kit rule and does not inherit at all.

   Measured before this rule existed: navy #041C42 on green-deep #0C3116 is
   1.17:1. Four elements were affected and all four were effectively invisible:
   the email address, and Privacy Policy / Terms / Disclaimer in the bottom bar.

   The contrast gate did not catch them because it scans BOUND colours, and
   these anchors have no binding — they fall through to a kit default. See D-73.

   Underlined as well as recoloured: colour alone is not a link cue (1.4.1).
   --------------------------------------------------------------------------- */

/* Scoped to every DARK region that carries prose, not just the footer: the
   utility bar has the identical problem with the same email address, at the
   same 1.17:1. Anywhere a bare <a> sits on green-deep needs this. */
.cr-footer .elementor-widget-text-editor a,
.cr-footer .cr-footer-legal a,
.cr-header .cr-utility .elementor-widget-text-editor a {
  color: var(--e-global-color-crivory);   /* 13.38:1 on green-deep */
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cr-footer .elementor-widget-text-editor a:hover,
.cr-footer .cr-footer-legal a:hover,
.cr-header .cr-utility .elementor-widget-text-editor a:hover {
  color: var(--e-global-color-crgoldtext); /* 5.71:1 on green-deep */
}

/* Link lists: no markers, no indent, flush with the heading above. */
.cr-footer .elementor-icon-list-items {
  list-style: none;
  margin: 0;
  padding: 0;
}

.cr-footer .elementor-icon-list-item {
  margin: 0;
}

.cr-footer .elementor-icon-list-item > a,
.cr-footer .elementor-icon-list-text {
  line-height: 1.5;
}

/* Everything left-aligned within its column, including the logo — which was
   defaulting to centre and sitting 68px right of the text beneath it. */
.cr-footer .elementor-widget,
.cr-footer .elementor-widget-image,
.cr-footer .cr-footer-logo {
  text-align: left;
}

.cr-footer .cr-footer-logo img {
  margin-inline-start: 0;
}

/* ---------------------------------------------------------------------------
   LOGO LINKS — header and footer both go home (Site Logo widget, `site_url`).

   Both are now real links, so both need a visible focus indicator. The ring
   goes on the <a>, sized to the logo box rather than the image, and follows the
   ground rule: crgolddeep on the ivory header bar (4.92:1), crgoldtext on the
   footer's green-deep (5.71:1). Both clear the 3:1 an indicator needs.

   `display:inline-block` on the anchor so the outline wraps the image instead
   of collapsing to a zero-height inline box.
   --------------------------------------------------------------------------- */

.cr-header .elementor-widget-theme-site-logo a,
.cr-footer .cr-footer-logo a {
  display: inline-block;
  line-height: 0;
  border-radius: 3px;
}

.cr-header .elementor-widget-theme-site-logo a:focus-visible {
  outline: 2px solid var(--e-global-color-crgolddeep);
  outline-offset: 4px;
}

.cr-footer .cr-footer-logo a:focus-visible {
  outline: 2px solid var(--e-global-color-crgoldtext);
  outline-offset: 4px;
}

/* ---------------------------------------------------------------------------
   Bottom bar — quieter than the columns above.

   Same green-deep ground as the columns, separated by a hairline rather than a
   colour step, so it reads as the same surface rather than a second band.
   --------------------------------------------------------------------------- */

.cr-footer-bottom {
  text-align: center;
}

.cr-footer-bottom p {
  margin: 0;
}

.cr-footer-bottom p + p {
  margin-top: 6px;
}

/* ---------------------------------------------------------------------------
   FORMS  (/contact)

   ZERO hardcoded colour and zero hardcoded type. Everything below reads an
   Elementor Global custom property, because the form's HTML fields are raw
   markup inside a widget and cannot bind through `__globals__` the way a
   heading widget does. Referencing the variable is the substitute for binding,
   NOT a licence to type a hex or a px font-size — the calendar template
   established this pattern.
   --------------------------------------------------------------------------- */

/* Field-group legends. These sit UNDER the section H2 "Send an enquiry", so
   they are h3 in the markup and take crh4 (22px), not crh3 (28px) — a form
   legend is a group title, not a section heading. */
.cr-contact-form .cr-form-legend {
  font-family: var(--e-global-typography-crh4-font-family), sans-serif;
  font-size: var(--e-global-typography-crh4-font-size);
  font-weight: var(--e-global-typography-crh4-font-weight);
  line-height: var(--e-global-typography-crh4-line-height);
  color: var(--e-global-color-primary);
  margin: 16px 0 0;
}

.cr-contact-form .cr-form-hint {
  font-family: var(--e-global-typography-crsmall-font-family), sans-serif;
  font-size: var(--e-global-typography-crsmall-font-size);
  font-weight: var(--e-global-typography-crsmall-font-weight);
  line-height: var(--e-global-typography-crsmall-line-height);
  letter-spacing: var(--e-global-typography-crsmall-letter-spacing);
  color: var(--e-global-color-crmutedonlite);
  margin: 4px 0 0;
}

/* Consent notice. Set apart with a hairline and the legal type size so it
   reads as a notice rather than as more body copy — it is the thing the
   visitor is being asked to agree to. */
.cr-contact-form .cr-consent-notice {
  border-top: 1px solid var(--e-global-color-crruleonlite);
  padding-top: 16px;
  margin-top: 8px;
}

.cr-contact-form .cr-consent-notice p {
  font-family: var(--e-global-typography-crlegal-font-family), sans-serif;
  font-size: var(--e-global-typography-crlegal-font-size);
  font-weight: var(--e-global-typography-crlegal-font-weight);
  line-height: var(--e-global-typography-crlegal-line-height);
  letter-spacing: var(--e-global-typography-crlegal-letter-spacing);
  color: var(--e-global-color-crmutedonlite);
  margin: 0 0 8px;
}

.cr-contact-form .cr-consent-notice p:last-child {
  margin-bottom: 0;
}

/* The group sub-label. This is the checkbox group's accessible name, moved out
   of Elementor's own `field_label` because that one rendered a <label for> that
   pointed at no element (see build-contact.php). It is styled as a field label
   so it reads as one, but it is a <p> — a <label> with nothing to label is what
   we just removed. */
.cr-contact-form .cr-form-sublabel {
  font-family: var(--e-global-typography-accent-font-family), sans-serif;
  font-size: var(--e-global-typography-accent-font-size);
  font-weight: var(--e-global-typography-accent-font-weight);
  line-height: var(--e-global-typography-accent-line-height);
  letter-spacing: var(--e-global-typography-accent-letter-spacing);
  color: var(--e-global-color-text);
  margin: 10px 0 0;
}

.cr-contact-form .cr-form-sublabel + .cr-form-hint {
  margin-top: 2px;
}

/* ---------------------------------------------------------------------------
   CHECKBOXES — styled, NOT replaced

   The native <input type="checkbox"> is kept and restyled with
   `appearance: none`. It is NOT hidden behind a pseudo-element on the label,
   which is the common trick and the one that breaks things: a hidden input
   loses Windows High Contrast rendering, and forced-colors mode then paints
   nothing at all. `appearance: none` keeps a real focusable, keyboard-operable,
   AT-visible control and only changes how it is painted.

   The check mark is drawn with a rotated ::after border rather than an SVG
   background-image, so it inherits `currentColor` and survives forced-colors.
   --------------------------------------------------------------------------- */

.cr-contact-form .elementor-field-subgroup .elementor-field-option {
  display: flex;
  align-items: flex-start;
  gap: 12px;             /* box -> label gap, as specified */
  line-height: 1.45;
}

.cr-contact-form input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 1px 0 0;       /* optical align to the first line of the label */
  border: 2px solid var(--e-global-color-primary);   /* navy */
  border-radius: 3px;
  background: var(--e-global-color-crwhite);
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease;
}

/* Checked state: gold-deep fill. This is a NON-TEXT UI component, so the bar is
   3:1 (WCAG 1.4.11), not 4.5:1 — crgolddeep #896622 on ivory is 4.92:1 and on
   white 5.31:1, so it clears with headroom either way. The white tick on
   crgolddeep is 5.31:1. */
.cr-contact-form input[type="checkbox"]:checked {
  background: var(--e-global-color-crgolddeep);
  border-color: var(--e-global-color-crgolddeep);
}

/* THE TICK IS DRAWN ON THE WRAPPING SPAN, NOT ON THE INPUT.
 *
 * ::before / ::after on an <input> is unreliable — it is a replaced element,
 * and although Chrome reports a used width for the pseudo-box, it paints it
 * with the wrong geometry: the rotated check rendered as a 1px white sliver
 * pinned to the left edge of the box. Measured, then screenshotted, because
 * getComputedStyle happily reported `width: 10px; opacity: 1` for something
 * that was not on screen.
 *
 * `.elementor-field-option` is an ordinary <span> and has no such problem, so
 * the tick is positioned over the box from there. `:has()` supplies the checked
 * state; it has been baseline in every current browser since late 2023.
 *
 * Geometry: the 18px box starts 1px down (the input's top margin), so its
 * centre is (9px, 10px) from the span's top-left. The 10x6 tick is placed at
 * (4px, 7px) so its own centre lands there, and rotation about that centre
 * keeps it centred. */
.cr-contact-form .elementor-field-option {
  position: relative;
}

.cr-contact-form .elementor-field-option::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 7px;
  width: 10px;
  height: 6px;
  border: 2px solid var(--e-global-color-crwhite);
  border-top: 0;
  border-right: 0;
  border-radius: 1px;
  transform: rotate(-45deg) translateY(-1px);
  opacity: 0;
  pointer-events: none;   /* the input underneath stays the hit target */
}

.cr-contact-form .elementor-field-option:has( input[type="checkbox"]:checked )::before {
  opacity: 1;
}

/* The whole label is clickable because Elementor emits <label for="…">, which
   is already a click target. This makes the target look like one and gives it
   a comfortable hit area rather than a text-height sliver. */
.cr-contact-form .elementor-field-subgroup label,
.cr-contact-form .elementor-field-type-acceptance .elementor-field-option label {
  cursor: pointer;
  padding: 2px 0;
}

.cr-contact-form input[type="checkbox"]:hover {
  border-color: var(--e-global-color-crgolddeep);
}

/* Forced-colors / Windows High Contrast: hand the painting back to the OS.
   Our border and fill colours are ignored there by design, and SystemColor
   keywords are what the mode expects. */
@media (forced-colors: active) {
  .cr-contact-form input[type="checkbox"] {
    border-color: CanvasText;
  }
  .cr-contact-form input[type="checkbox"]:checked {
    background: Highlight;
    border-color: Highlight;
  }
  .cr-contact-form .elementor-field-option::before {
    border-color: HighlightText;
  }
}

/* ---------------------------------------------------------------------------
   Multi-select layout — 3 / 2 / 1

   Was `elementor-subgroup-inline`, a flex row, which put seven options on one
   cramped line. A grid gives even columns and even spacing, and each cell is a
   fixed track so the labels align rather than staggering by word length.
   --------------------------------------------------------------------------- */

.cr-contact-form .cr-checkgrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px 24px;
  margin-top: 10px;
}

@media (max-width: 1024px) {
  .cr-contact-form .cr-checkgrid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 767px) {
  .cr-contact-form .cr-checkgrid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Option labels read as body copy, like the consent sentence (D-124). They
   took the 18px INPUT-text Global through Elementor's field_typography rule
   (`.elementor-field-subgroup label`, 0,4,x); 0,5,2 wins without !important. */
.elementor-widget-form.cr-contact-form .elementor-field-group .cr-checkgrid .elementor-field-option > label {
  font-family: var(--e-global-typography-crsmall-font-family), sans-serif;
  font-size: var(--e-global-typography-crsmall-font-size);
  font-weight: var(--e-global-typography-crsmall-font-weight);
  line-height: var(--e-global-typography-crsmall-line-height);
  letter-spacing: var(--e-global-typography-crsmall-letter-spacing);
}

/* ---------------------------------------------------------------------------
   Consent block — set apart from the field above

   This is the one control on the page that carries a legal consequence, so it
   gets real separation rather than the standard field gap: a rule, generous
   space above it, and a tinted plate so it reads as its own region.
   --------------------------------------------------------------------------- */

/* ⚠ TARGET ELEMENTOR'S OWN PER-FIELD WRAPPER, NOT A `css_classes` VALUE.
 *
 * `css_classes` does not go where you would expect on these two field types:
 *   - on an `html` field it is not rendered AT ALL;
 *   - on an `acceptance` field it lands on the <input> itself, not on the
 *     group wrapper — so a plate style written against it gets applied to the
 *     18px checkbox, which is exactly what happened here first time round.
 *
 * `.elementor-field-group-<custom_id>` is emitted by form-base.php for every
 * field and is the stable hook. */
.cr-contact-form .elementor-field-group-consent_notice {
  margin-top: 24px;
}

.cr-contact-form .cr-consent-notice {
  border-top: 1px solid var(--e-global-color-crruleonlite);
  padding-top: 16px;
  margin-top: 0;
}

.cr-contact-form .elementor-field-group-consent {
  margin-top: 14px;
  padding: 16px 18px;
  background: var(--e-global-color-crtint);
  border: 1px solid var(--e-global-color-crruleonlite);
  border-radius: 3px;
}

/* The consent checkbox is the same control as the others — same 18px box, same
   navy border, same gold-deep checked state — deliberately, so it does not read
   as a different kind of thing. Only its surround differs. */
.cr-contact-form .elementor-field-group-consent .elementor-field-option {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

/* The acceptance label carries the consent sentence itself, so it is not a
   one-word label and must not be styled like one.

   SPECIFICITY 0,5,1 IS LOAD-BEARING (batch 2, D-116). Once the form's labels
   were bound to the `text` Global, Elementor emits a per-element rule
   `.elementor-34 .elementor-element.elementor-element-<id> .elementor-field-subgroup label`
   at 0,4,1, which silently took this sentence from crsmall to 18px. Measured
   with CDP before and after. */
.elementor-widget-form.cr-contact-form .elementor-field-group.elementor-field-type-acceptance .elementor-field-subgroup label {
  font-family: var(--e-global-typography-crsmall-font-family), sans-serif;
  font-size: var(--e-global-typography-crsmall-font-size);
  font-weight: var(--e-global-typography-crsmall-font-weight);
  line-height: var(--e-global-typography-crsmall-line-height);
  letter-spacing: var(--e-global-typography-crsmall-letter-spacing);
}

/* The "Consent" field label above the sentence is a group heading, not a
   restatement — sized down so the sentence is the thing that reads.
   Specificity 0,5,0 for the same reason as the rule above: the per-element
   label_typography rule (`.elementor-field-group > label`, 0,4,1) beat the
   old 0,3,0 selector and restyled this heading as 18px body text. */
.elementor-widget-form.cr-contact-form .elementor-field-group.elementor-field-group-consent > .elementor-field-label {
  font-family: var(--e-global-typography-accent-font-family), sans-serif;
  font-size: var(--e-global-typography-accent-font-size);
  font-weight: var(--e-global-typography-accent-font-weight);
  line-height: var(--e-global-typography-accent-line-height);
  letter-spacing: var(--e-global-typography-accent-letter-spacing);
  color: var(--e-global-color-text);
  margin-bottom: 8px;
}

/* Submit button: gold fill on ivory is 2.91:1 against its surround, which is
   below the 3:1 WCAG 1.4.11 requires to locate a control's boundary. The 1px
   crgolddeep border is FUNCTIONAL, not decorative — removing it fails 1.4.11.
   Identical reasoning to the header CTA (D-33), and deliberately the same
   vocabulary rather than a second one. */
.cr-contact-form .elementor-button {
  border: 1px solid var(--e-global-color-crgolddeep);
  border-radius: 3px;
  transition: border-color 140ms ease, transform 140ms ease, box-shadow 140ms ease;
}

/* State change goes on the BORDER, never the fill. Darkening the fill to
   gold-deep would put navy text on #896622 at 3.19:1 and fail AA — the same
   trap the header CTA hit. The border is non-text and carries the change at
   15.70:1 against ivory while the text pair stays navy-on-gold at 5.39:1.

   Border alone was too quiet to read as a hover, so it is joined by a 1px lift
   and a shadow — the same lifted-card vocabulary as D-30, not a second one.
   Both are decorative; the border is the part that carries the state. */
.cr-contact-form .elementor-button:hover,
.cr-contact-form .elementor-button:focus-visible {
  border-color: var(--e-global-color-primary);
  transform: translateY(-1px);
  box-shadow: 0 3px 10px rgba(4, 28, 66, 0.18);
}

.cr-contact-form .elementor-button:active {
  transform: translateY(0);
  box-shadow: none;
}

/* Focus. Every control gets a ring at least as clear as the pointer
   affordance. `:focus-visible`, so a mouse click does not leave a ring behind. */
.cr-contact-form .elementor-field-group .elementor-field-textual:focus-visible,
.cr-contact-form .elementor-field-group select:focus-visible,
.cr-contact-form .elementor-field-group textarea:focus-visible,
.cr-contact-form .elementor-field-group input[type="checkbox"]:focus-visible {
  /* crgolddeep, not brand gold: the form sits on ivory and on the tint consent
     plate, where #B98A2E is 2.91:1 and fails 1.4.11 as an indicator. */
  outline: 2px solid var(--e-global-color-crgolddeep);
  outline-offset: 2px;
}

.cr-contact-form .elementor-field-group .elementor-button:focus-visible,
.cr-contact-form .elementor-button:focus-visible {
  outline: 3px solid var(--e-global-color-primary);
  outline-offset: 3px;
}

/* Error state. Elementor appends role="alert" spans and sets aria-invalid on
   the input, so errors are announced; this makes them visible too, and not by
   colour alone — the field border thickens as well as changing hue (1.4.1). */
.cr-contact-form .elementor-field-group.elementor-error .elementor-field-textual,
.cr-contact-form .elementor-field-group.elementor-error select,
.cr-contact-form .elementor-field-group.elementor-error textarea {
  border-width: 2px;
}

.cr-contact-form .elementor-message-danger,
.cr-contact-form .elementor-form-help-inline {
  font-family: var(--e-global-typography-crsmall-font-family), sans-serif;
  font-size: var(--e-global-typography-crsmall-font-size);
}

/* ---------------------------------------------------------------------------
   Contact — direct details column

   Email is a link on a page of body copy. (Phone links removed with the
   numbers, revision batch 2 item 7 — D-115.) Navy on ivory is 15.70:1,
   but colour alone is not a link cue (1.4.1) — navy against the body grey is
   nowhere near a 3:1 non-colour distinction. They are underlined.
   --------------------------------------------------------------------------- */

.cr-contact-body a[href^="mailto:"] {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.cr-contact-body a:focus-visible,
.cr-about-mv a:focus-visible {
  /* Both bands are ivory. See the note on the header/footer rings above. */
  outline: 2px solid var(--e-global-color-crgolddeep);
  outline-offset: 3px;
}

/* ---------------------------------------------------------------------------
   Deliberately-empty blocks and the reviewed date

   .cr-team-empty and .cr-map-empty use the same dashed-outline treatment as
   the homepage's empty client-voice block. One vocabulary for "this is
   unfinished on purpose", so a reviewer learns it once.
   --------------------------------------------------------------------------- */

.cr-team-empty p,
.cr-map-empty p {
  max-width: 62ch;
  margin-inline: auto;
}

/* On /about and /contact this is a text-editor widget, so Elementor already
   binds crlegal through the Globals. Inside a data table it is raw HTML in an
   `html` widget and inherits nothing, so the same values are stated here —
   from the same CSS variables, not from a second set of numbers. */
.cr-lastreviewed {
  margin: 0;
  font-family: var(--e-global-typography-crlegal-font-family), sans-serif;
  font-size: var(--e-global-typography-crlegal-font-size);
  font-weight: var(--e-global-typography-crlegal-font-weight);
  line-height: var(--e-global-typography-crlegal-line-height);
  letter-spacing: var(--e-global-typography-crlegal-letter-spacing);
  color: var(--e-global-color-crmutedonlite);
}

.cr-datatable-scroll + .cr-lastreviewed {
  margin-top: 14px;
}

.cr-team .cr-lastreviewed,
.cr-contact-map .cr-lastreviewed {
  text-align: center;
}

/* ===========================================================================
   SHORT LAPTOP SCREENS — one section, one screen (revision batch 3, D-121)

   Client: "info of one screen should be displayed in one panel". Agreed scope:
   on laptop and desktop every section fits one screen, with normal scrolling;
   phones, tablets, the enquiry forms and the legal text are out of scope.

   At 1440x900 and taller everything already fits. What did not was 1366x768
   (the commonest laptop screen): hero, who-we-are and the engagement cards,
   95-105px over the 704px left under the compact header. So this layer is keyed
   to a SHORT screen, not a narrow one, and changes nothing on a taller screen.

   !important on the padding custom properties is deliberate: Elementor sets
   them per element at 0,3,0 in stylesheets that load AFTER this one (the saved
   blocks' post-*.css), so a plain rule loses on order. Scoped to this query.
   =========================================================================== */

@media (min-width: 1025px) and (max-height: 880px) {

  /* Every band one step tighter: 64 -> 48 (cr_band_pad's tablet value). */
  .elementor[data-elementor-type="wp-page"] > .e-con.e-parent,
  .elementor[data-elementor-type="section"] > .e-con.e-parent {
    --padding-top: 48px !important;
    --padding-bottom: 48px !important;
  }

  /* Hero heading at 3/4 of its Global — 69 -> 52px, still derived from the
     Global — so it sets on two lines instead of three. */
  .cr-hero h1.elementor-heading-title {
    font-size: calc(var(--e-global-typography-crhero-font-size) * .75) !important;
  }

  /* Images take what height the screen leaves, never more than they had.
     width:auto + max-height keeps the ratio. Each keeps the content edge it
     had at full size: the hero artwork the right edge, who-we-are the left
     (so it still lines up with the mission box beneath it). */
  .cr-picture--hero .cr-picture-img,
  .cr-picture--whoweare .cr-picture-img {
    width: auto;
    max-width: 100%;
  }

  .cr-picture--hero .cr-picture-img {
    margin-inline-start: auto;
  }

  /* The subtracted amounts are everything else in the band plus the 64px
     compact header, measured: hero = 48 + 20 (column padding) + 10 + 32 +
     62 (location strip) + 48 + 64; who-we-are = 48 + 20 + 10 + 32 + 117
     (mission/vision) + 48 + 64. */
  .cr-picture--hero .cr-picture-img {
    max-height: calc(100vh - 284px);
  }

  .cr-picture--whoweare .cr-picture-img {
    max-height: calc(100vh - 339px);
  }

  /* Engagement cards: padding 36 -> 24, inner gaps 14 -> 10, and no stray
     paragraph margin under the footnote that follows the cards.
     (D-125 had split this selector by inserting the why-card rule inside it,
     so the engagement cards took 22px and the gaps applied to nothing —
     corrected in D-129.) */
  .cr-engcard {
    --padding-top: 24px !important;
    --padding-bottom: 24px !important;
    --gap: 10px 0px !important;
    --row-gap: 10px !important;
  }

  /* Why ComplyRakshak grid (D-125): 28 -> 22 padding, which is what brings its
     rows inside one 1366x768 screen. */
  .cr-whycard {
    --padding-top: 22px !important;
    --padding-bottom: 22px !important;
  }

  .e-con:has(> .e-grid .cr-engcard) > .elementor-widget-text-editor p:last-child,
  .e-con-inner:has(> .e-grid .cr-engcard) > .elementor-widget-text-editor p:last-child {
    margin-bottom: 0;
  }
}

/* ===========================================================================
   IMAGE SLOT WITH NO REAL IMAGE (D-130)

   inc/picture.php renders nothing to visitors when a slot has only its build
   placeholder. The column that held the image would then sit empty beside the
   text, so it is removed and the text column takes the row. Keyed to the
   emptiness itself, so the moment a real image is chosen in Customize > Site
   Images the two-column layout returns with no code change.
   =========================================================================== */

.e-con:has(> .cr-placeholder-image .elementor-shortcode:empty) {
  display: none;
}

.e-con:has(> .cr-placeholder-image .elementor-shortcode:empty) ~ .e-con {
  --width: 100%;
  max-width: 62rem;
  /* Line the heading up with the rest of the page: this column's own 10px
     inline padding only made sense beside the image. !important because
     Elementor sets it per element in a later stylesheet. */
  --padding-left: 0px !important;
  --padding-right: 0px !important;
}


/* ===========================================================================
   OFFICES — /contact (D-136)

   One card per office city: an original landmark line drawing, the city, its
   state and the landmark's name. Markup: cr_office_cards() in
   lib-elementor-widgets.php. Lift, shadow and reduced-motion handling come
   from the shared card rules above (.cr-officecard is in that list).
   Every font and colour reads a Global — no literal sizes, no hex.
   =========================================================================== */

.cr-offices {
  list-style: none;
  margin: 0;
  /* Elementor's 10px inline container padding, so the cards line up with the
     section heading above them (the list sits in a bare html widget). */
  padding: 0 10px;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 20px;
}

@media (max-width: 1024px) {
  .cr-offices { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 767px) {
  .cr-offices { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
}

.cr-officecard {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  margin: 0;
  padding: 24px 16px 22px;
  background: var(--e-global-color-crwhite);
  border: 1px solid var(--e-global-color-crruleonlite);
  border-radius: 4px;
}

.cr-officecard-art {
  width: 100%;
  max-width: 150px;
  margin-bottom: 14px;
  color: var(--e-global-color-primary);            /* the drawing's lines: navy */
}

.cr-mon {
  display: block;
  width: 100%;
  height: auto;
}

/* The one gold detail in each drawing. accent is a fill/icon colour (D-31). */
.cr-mon .cr-mon-accent {
  fill: var(--e-global-color-accent);
  stroke: var(--e-global-color-accent);
}

.cr-mon .cr-mon-accent-stroke {
  stroke: var(--e-global-color-accent);
}

.cr-officecard-city {
  margin: 0;
  font-family: var(--e-global-typography-crh4-font-family), sans-serif;
  font-size: var(--e-global-typography-crh4-font-size);
  font-weight: var(--e-global-typography-crh4-font-weight);
  line-height: var(--e-global-typography-crh4-line-height);
  letter-spacing: var(--e-global-typography-crh4-letter-spacing);
  color: var(--e-global-color-primary);
}

.cr-officecard-state {
  margin: 2px 0 0;
  font-family: var(--e-global-typography-crsmall-font-family), sans-serif;
  font-size: var(--e-global-typography-crsmall-font-size);
  font-weight: var(--e-global-typography-crsmall-font-weight);
  line-height: var(--e-global-typography-crsmall-line-height);
  color: var(--e-global-color-crmutedonlite);
}

.cr-officecard-landmark {
  margin: 10px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--e-global-color-crruleonlite);
  align-self: stretch;
  font-family: var(--e-global-typography-crlegal-font-family), sans-serif;
  font-size: var(--e-global-typography-crlegal-font-size);
  font-weight: var(--e-global-typography-crlegal-font-weight);
  line-height: var(--e-global-typography-crlegal-line-height);
  letter-spacing: var(--e-global-typography-crlegal-letter-spacing);
  color: var(--e-global-color-crmutedonlite);
}
