/* Bouter Bouw - custom overrides
 *
 * Deliberately minimal. assets/media/2026/mobile-fixes.css was adopted
 * here wholesale and then rolled back out: applying it for the first time made
 * the carousel prev-arrow overlap the "Our Team" heading and stopped the
 * name/role overlay rendering, and it added ~6,050px of height across 21 mobile
 * pages. Mobile is parked as its own pass; that file gets reviewed rule by rule
 * then, not adopted in bulk. It remains untouched on disk.
 */

/* Team carousel: stop Safari stretching the slide and defeating its aspect-ratio.
 *
 * The slide is a flex item of .swiper-wrapper, which computes align-items:normal
 * (= stretch). WebKit stretches it to the flex line's cross size, which overrides
 * aspect-ratio:4/5 entirely - measured 479x1400 at viewport 1012 and 269x524 at
 * 1512, i.e. the wrong height scales with layout rather than coming from any
 * authored value. Blink sizes it from the ratio, so Chrome was always correct.
 *
 * align-self:flex-start opts the slide out of stretching, letting aspect-ratio
 * size it in both engines. Verified in Safari 26.6.2 at 1012 and 1512, and in
 * Chrome at 390/480/544/600/767/768/900/1012/1024/1200/1440/1512.
 */
.team-carousel .swiper-slide {
  align-self: flex-start;
}

/* Team carousel arrows, mobile only: align with the "Our Team" heading text.
 *
 * Elementor anchors the arrows at top: 50% of the carousel height plus a
 * hardcoded -269px, which was tuned for desktop >=1200 and drifts everywhere
 * else - measured +10.5px at 375 through +151px at 600, because the 50% term
 * grows as the cards get taller. Desktop >=1200 is already within 3.5px and is
 * deliberately left alone.
 *
 * Below 768 the arrows' containing block top is a constant 220.6px and the
 * heading's text centre a constant 166px, so a fixed top aligns the whole
 * range: 166 - 15 (half the 30px button) - 220.6 + 15 (the -15px translateY
 * Elementor applies) = -54.6px.
 */
@media (max-width: 767px) {
  .team-carousel .elementor-swiper-button-prev,
  .team-carousel .elementor-swiper-button-next {
    /* !important is required: Elementor's rule is
     * .elementor-widget-n-carousel.elementor-element :is(.swiper,.swiper-container) ~ .elementor-swiper-button-prev
     * at specificity (0,4,0), and it sets
     * top: calc(var(--..-top-align) + var(--..-top-position) - var(--..-caption-spacing))
     * = 50% + -269px - 15px. Overriding those custom properties does not work
     * either; they are set at (0,3,0) on the widget and the calc still wins. */
    /* -52.86px, not -54.6px: the old value put the arrow centre on the
     * heading's LINE-BOX centre (166.00). The optical centre is lower - "Our
     * Team" has no descenders, so its ink sits high in a line box that also
     * carries half-leading. Measured from the baseline (185) with canvas ink
     * metrics (ascent 35.39, descent 0.86): optical centre 167.74, i.e. 1.74px
     * below where the arrows were. -54.6 + 1.74 = -52.86. Constant 360-767. */
    top: -52.86px !important;

    /* Group the pair and centre it on the "Our Team" heading.
     *
     * The containing block is the widget itself (.elementor-element-a91335f
     * .e-widget-swiper), so left:50% resolves to the widget's centre. The
     * heading box starts further left than the widget (x=1 vs x=28 at 390) and
     * shares its right edge, so the heading's centre sits a constant 13px left
     * of the widget's centre - measured 13px at 360/390/414/480/600 and 14px at
     * 767.
     *
     * A grouped pair is 68px: 30 + 8 + 30, the same 8px the Featured Projects
     * arrows already use, anchored from the container's right edge.
     *
     * Before this, only prev was fixed (left:207px); next was anchored to the
     * container's right edge and drifted with width, so the gap grew from 41px
     * at 360 to 281px at 600. Verified after: prev lands at 131/146/158/191/251
     * at 360/390/414/480/600, within 1px of the heading centre at every width.
     *
     * translateY(-15px) is Elementor's own vertical offset and must be kept -
     * it is what puts the arrow centre on the heading's text centre (166).
     * !important throughout for the same reason as the top above: Elementor's
     * rule is (0,4,0) and this is (0,2,0).
     */
    left: auto !important;
    transform: translateY(-15px) !important;
  }

  /* next sits flush with the card's right edge; prev comes in 8px from it.
   *
   * The arrows' containing block is the widget itself, whose right edge is the
   * same 358 as the active slide's at 390 - so right:0 puts next exactly on the
   * card edge. It previously carried right:-8px, inherited from where Elementor
   * had left it, which hung the whole pair 8px proud of the card (measured: next
   * right 366 vs card right 358).
   *
   * Centring the pair on the heading was tried first and is wrong: the heading
   * is text-align:start, so "Our Team" sits at the left of a full-width box and
   * a pair centred on that box lands on the glyphs. Featured Projects works
   * because it groups the arrows at the right and shares the line with a
   * left-set heading - the same arrangement adopted here. */
  .team-carousel .elementor-swiper-button-next {
    right: 0 !important;
  }

  .team-carousel .elementor-swiper-button-prev {
    right: 38px !important;  /* 0 + 30px button + 8px gap */
  }

  /* "Our Team" sits flush to the container while the card below starts further
   * in. Measured: heading box left 1, its ink left 3.8 (the 'O' carries a 2.8px
   * left side bearing), and the ACTIVE slide's left edge 28 - a constant gap at
   * 360/390/414/480/600, and the same 27 / 24.2 at 767 where both shift together
   * (84.5 / 87.3 / 111.5).
   *
   * Indented by the ink gap (24.2px), not the box gap (27px): the card is a
   * photograph with a hard edge and no side bearing, so aligning the boxes would
   * leave the 'O' looking 2.8px inset. text-indent rather than padding or margin
   * keeps the heading's own box untouched. */
  .elementor-element-d434c17 .elementor-heading-title {
    text-indent: 24.2px;
  }
}

/* Featured Projects (45e28e3): arrows only, no dots.
 *
 * Carousel navigation is arrows site-wide. This widget carried both - its
 * data-settings declare arrows:"yes" and pagination:"bullets" - and it is the
 * only carousel on the site that did. Hidden rather than unset in settings so
 * Swiper keeps managing the instance unchanged; the element is display:none so
 * it also leaves the flow. The homepage hero (27f6ba6) and the About Us reviews
 * widget (23842e1) are deliberately untouched.
 */
.elementor-element-45e28e3 .swiper-pagination {
  display: none !important;
}

/* Featured Projects carousel (homepage, element 45e28e3): the same two fixes as
 * the about-us team carousel. Same widget type (n-carousel), same structure, so
 * the Safari bug is identical; the arrow geometry is not, so the constant differs.
 */

/* Safari stretches the slide and defeats its aspect-ratio, exactly as on
 * about-us: the slide is a flex item of .swiper-wrapper (align-items:normal =
 * stretch) and computes align-self:auto with aspect-ratio:4/5. Measured on the
 * homepage before this rule: slide 350x438 at 390 and 375x498 at 1440. */
.elementor-element-45e28e3 .swiper-slide {
  align-self: flex-start;
}

/* Featured Projects arrows, mobile only (<768): heading left, both arrows
 * grouped at the right, on one line.
 *
 * Three things are needed together; none works alone.
 *
 * 1. The heading is centred by default, and its text is a constant 276.7px.
 *    Centred, it leaves only 21.7px of free space at 360 and 36.7px at 390 -
 *    not enough for any arrow pair - so it is left-aligned here.
 *
 * 2. Elementor pads these buttons 16px a side, making them 62px. Two 62px
 *    buttons plus an 8px gap need 132px, which does not fit beside 276.7px of
 *    text in a 320px container. Zeroing the padding gives the 30px button the
 *    about-us carousel uses, so the pair is 68px.
 *
 * 3. Horizontal anchoring. Elementor puts prev at left:100% with a -292px
 *    offset and a -100% translate, which is what threw it to the far left while
 *    next sat at the right edge - measured gap 311px at every mobile width.
 *    Both are re-anchored from the right instead: next at -19px (the outer
 *    edge, where it already sat) and prev at 19px, i.e. 30 + 8 further in, which
 *    reproduces the 8px edge gap the same carousel already uses at >=768.
 *
 * Vertical: the previous -79.8px was derived for a 62px button. A 30px button
 * with the same top would sit 16px higher at its centre, so the value becomes
 * -79.8 + 16 = -63.8px to keep the arrow centre on the heading centre.
 *
 * >=768 is deliberately untouched: 62px buttons, 70px centre gap, next 1px
 * inside the container edge, arrows 10.7px below the heading centre.
 */
@media (max-width: 767px) {
  /* heading left so the text and the arrow pair share a line */
  .elementor-element.elementor-element-05039ef {
    text-align: left !important;
  }

  .elementor-element-45e28e3 .elementor-swiper-button-prev,
  .elementor-element-45e28e3 .elementor-swiper-button-next {
    /* 62px -> 30px, matching about-us */
    padding: 0 !important;
    /* drop Elementor's left anchoring and its -100% translate */
    left: auto !important;
    transform: none !important;
    /* !important throughout: Elementor's rule is (0,4,0) and sets these via
     * calc() on custom properties, which cannot be overridden by resetting
     * the properties themselves. */
    top: -63.8px !important;
  }

  /* Both arrows must stay INSIDE the widget box: it computes
   * overflow: clip visible (x clipped at its right edge). The previous
   * right:-19px put next 19px outside, and Chrome painted only 11px of its
   * 30px - visible fraction 0.367 - while WebKit dropped it entirely.
   * These insets mirror the >=768 arrangement: next 1px in from the edge,
   * prev a further 30 + 8 inboard. */
  .elementor-element-45e28e3 .elementor-swiper-button-next {
    right: 1px !important;
  }

  .elementor-element-45e28e3 .elementor-swiper-button-prev {
    right: 39px !important;   /* 1 + 30px button + 8px gap */
  }
}

/* Narrowest phones (<=374): 4px off the heading so it shares its line.
 *
 * Derived AFTER the arrows were brought inside the widget's clip box, which
 * costs ~20px of horizontal budget: at 360 prev's left edge is now 271, and
 * "Featured Projects" at 37px measures 276.7px ending at 296.7 - a 25.7px
 * collision. Measured at 360 with the corrected positions: 34px clears by only
 * 0.2px (too tight to trust across font fallbacks and rounding), 33px clears by
 * 8.8px, 32px by 17.5px. 33px is the smallest value with real margin.
 *
 * 375 and up keep 37px: 390 already clears by 4.3px and it grows with width.
 */
@media (max-width: 374px) {
  .elementor-element.elementor-element-05039ef .elementor-heading-title {
    font-size: 33px !important;
  }
}

/* Services hero: optical left alignment of the subtitle to the heading.
 *
 * The two text BOXES already align exactly - measured delta 0 at 1440, 1024
 * and 390. What is misaligned is the ink: the round 'O' of "Our Services"
 * carries a larger left side bearing than the 'S' of "Solutions", so the O sits
 * further right and the S overhangs it. Nudging the subtitle right closes it.
 *
 * Measured bearings, confirmed twice by independent methods (font metrics via
 * TextMetrics.actualBoundingBoxLeft, and canvas rasterisation scanned for the
 * first inked column), agreeing to within 0.06px:
 *
 *            'O'              'S'              ink delta
 *   1440      3.75px @75px     2.00px @43px     -1.75px
 *   390       1.75px @37px     1.00px @24px     -0.75px
 *
 * Applied as a flat 2px per instruction. Note this slightly overshoots at 390,
 * where the measured offset is 0.75px - the correction is size-dependent, so a
 * single value cannot be exact at both ends.
 */
.elementor-element.elementor-element-78247a0 p {
  text-indent: 2px;
}

/* CO2 Performance Ladder certification logo row (about-us, container 7f0752d).
 *
 * Five marks at equal optical size. Two problems were compounding:
 *
 * 1. Two sizing regimes. The three rectangles were height-locked
 *    (height:117px, VCA 96px at <=767) while the two circles had no height
 *    rule at all and simply filled their 20% column - so they tracked the
 *    viewport while the rectangles did not. At 390 that rendered marks of
 *    61x53, 59x79, 59x79, 34x34, 34x34: the circles under half.
 *
 * 2. width:100% + object-fit:contain meant a narrow column letterboxed the
 *    image, so the authored height was not what rendered - VCA's 96px box
 *    produced a 53px mark. Height is made authoritative here with width:auto.
 *
 * Sizes come from each file's measured ink fraction of its frame: VCA 91.3%
 * of frame height, the two EBN marks 87.1%, the cropped circles 100%. Heights
 * are set so every mark lands on the same ink height - 72px at mobile, 102px
 * at desktop - with the circles +6% to compensate for the corner void, which
 * is what stops a circle reading smaller than a rectangle of equal height.
 */
.elementor-element-82d2c83 img,
.elementor-element-3700c58 img,
.elementor-element-a95b34a img,
.elementor-element-429b2d4 img,
.elementor-element-a30c72f img {
  width: auto !important;
  max-width: 100% !important;
  margin-left: auto !important;
  margin-right: auto !important;
  object-fit: contain;
}

.elementor-element-82d2c83 img { height: 112px !important; }  /* VCA**  ink 102 */
.elementor-element-3700c58 img { height: 117px !important; }  /* CO2    ink 102 */
.elementor-element-a95b34a img { height: 117px !important; }  /* ISO    ink 102 */
.elementor-element-429b2d4 img { height: 108px !important; }  /* circle ink 108 */
.elementor-element-a30c72f img { height: 108px !important; }  /* circle ink 108 */

@media (max-width: 767px) {
  .elementor-element-82d2c83 img { height: 79px !important; }  /* ink 72 */
  .elementor-element-3700c58 img { height: 83px !important; }  /* ink 72 */
  .elementor-element-a95b34a img { height: 83px !important; }  /* ink 72 */
  .elementor-element-429b2d4 img { height: 76px !important; }  /* ink 76 */
  .elementor-element-a30c72f img { height: 76px !important; }  /* ink 76 */

  /* 3 + 2, centred. Thirds force exactly three per line; justify-content on the
   * container (already center) then centres the pair on the second line,
   * instead of the 4+1 that content-width items produced. */
  .elementor-element-7f0752d > .elementor-element {
    width: calc(33.333% - 14px) !important;
    max-width: calc(33.333% - 14px) !important;
  }
}

/* About Us, UNICEF section at <=767: title and body text above the image.
 *
 * The section is an e-con-inner flex row with exactly two children - 9a90963
 * (the image) and ec0fe6f (title + text) - which wrap into a column at mobile,
 * putting the image first. One order rule on the text column lifts it above the
 * image; title and text are already in the right sequence inside it.
 *
 * Desktop is untouched: at >=768 the container is flex-direction:row nowrap and
 * the two columns sit side by side, where order has no visible effect anyway.
 *
 * Set as --order, not order. Elementor ships
 * `.elementor-element { order: var(--order) }` at (0,1,0) - the same specificity
 * as a plain .elementor-element-ec0fe6f rule - and its stylesheet loads after
 * custom.css (head node 11 vs 4), so it wins the tie on source order and
 * resolves the unset variable to the initial 0. Confirmed with
 * CSS.getMatchedStylesForNode: both rules matched, computed order stayed 0.
 * Feeding the variable works with that declaration instead of against it and
 * needs no !important.
 */
