/**
 * Small patches on top of the Digitics theme CSS.
 *
 * Linked from the root layout *after* style.css and brand.css so these rules
 * win the cascade — that ordering is the whole point of the file, so do not
 * move it into globals.css (which Next injects before the theme).
 *
 * Everything here exists to support a React port of markup that was originally
 * static HTML — mostly making interactive elements real buttons without
 * changing how they look. Keep this file tiny; visual design still belongs in
 * `public/assets/css/brand.css`.
 */

/**
 * The theme ships `body { position: fixed }` and relies on its preloader script
 * to flip it back to static once the DOM is ready — a flash of blank page
 * waiting to happen, and pointless without a blocking preloader.
 *
 * Deliberately nothing else here. `overflow-x: hidden` on the body looks like
 * the obvious way to contain the layout's off-screen decoration, but it makes
 * the body a scroll container, and that silently kills `position: sticky` for
 * every descendant — which is the whole about-section animation, where the
 * mission/vision/stories cards are meant to pin and stack on top of each other.
 *
 * The theme's own `html { overflow-x: hidden }` already handles the clipping;
 * the live site sets nothing on the body either.
 */
body {
  position: static;
}

/* next/image renders every image with `display: block`; the theme's markup was
   plain inline <img> tags throughout, and its spacing was measured against
   that. An inline image sits on the text baseline, so its line box carries the
   font's descender space; as a block that space disappears and the surrounding
   layout tightens by a few pixels — enough to make the header 6px shorter, the
   footer's social row ride up, and blog cards lose 5px each.

   Applied site-wide rather than per-component: the mismatch is systemic (every
   image next/image renders), and an allow-list silently misses whichever
   section is added next. Utility overrides below still win where a specific
   image genuinely needs to be a block. */
img {
  display: inline;
}

/* The accordion header was a plain <div> in the theme. It is a <button> now so
   it is keyboard-reachable, which means resetting the UA button styles so the
   heading renders exactly as before. */
.ul-single-accordion-item__title button {
  all: unset;
  display: block;
  width: 100%;
  cursor: pointer;
  font: inherit;
  color: inherit;
  text-align: inherit;
}

/* Same for the sticky about-tab nav links, which are <a> without href. */
.ul-about-content-tab .tab-sticky-nav {
  cursor: default;
}

/* Blog thumbnails are wrapped in a <Link> (anchor) in the React port; the
   theme's markup had the <img> as a direct child of .ul-blog-img. The anchor
   defaults to inline-block, so it shrinks to its content — the image's
   `width: 100%` then resolves against a zero-width box and the thumbnail
   collapses (most visible on mobile, where the horizontal cards stack and the
   image is meant to span the full card). Making the anchor a block gives the
   image a full-width containing block again. */
.ul-blog-img a,
.ul-blog-2-img a {
  display: block;
}

/* Home blog teaser on phones: the two compact horizontal cards stack full
   width (≤479px), so match them to the featured card — a wide landscape
   thumbnail and the post excerpt — for a uniform three-card list. The excerpt
   is rendered for every card; it stays hidden on the horizontal cards above
   this width, where the theme's image-left layout has no room for it, so the
   desktop "1 featured + 2 compact" design is untouched. */
.ul-blog-horizontal .ul-blog-excerpt {
  display: none;
}
@media screen and (max-width: 479px) {
  .ul-blog-horizontal .ul-blog-img img {
    aspect-ratio: 530 / 248;
  }
  .ul-blog-horizontal .ul-blog-excerpt {
    display: block;
    margin-bottom: 0;
  }
}

/* Focus ring for keyboard users. The theme shipped none at all, which fails
   WCAG 2.4.7; :focus-visible keeps it invisible for mouse clicks. */
.ul-single-accordion-item__title button:focus-visible,
.ul-header-nav a:focus-visible,
.ul-btn:focus-visible,
.ul-sidebar-closer:focus-visible,
.ul-search-closer:focus-visible,
.ul-header-search-opener:focus-visible,
.ul-header-sidebar-opener:focus-visible {
  outline: 2px solid var(--ul-primary);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Swiper's ESM build ships its own styles; the theme already sizes these
   containers, so only the pieces Swiper genuinely needs are imported. Guard
   against the library's default 100% width fighting the theme's overflow rules
   on the services slider, which is deliberately allowed to bleed. */
.ul-services-slider.overflow-visible {
  overflow: visible;
}

/* Honour a reduced-motion preference: WOW.js reveals and Swiper autoplay are
   decorative, and the theme never accounted for the setting. */
@media (prefers-reduced-motion: reduce) {
  .wow,
  .animate__animated {
    animation: none !important;
    visibility: visible !important;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Newsletter form status message (footer). A tinted pill rather than raw red
   text, sized for the narrow dark-blue footer column — Bootstrap's light alert
   would be a jarring bright block there. Success and error share the shape and
   differ only in tint. */
.ul-nwsltr-msg {
  margin-top: 12px;
  padding: 9px 14px;
  border-radius: 8px;
  font-size: 13px;
  line-height: 1.45;
  border: 1px solid transparent;
}
.ul-nwsltr-msg[data-status='error'] {
  color: #ffd7d7;
  background: rgba(220, 53, 69, 0.18);
  border-color: rgba(255, 138, 138, 0.35);
}
.ul-nwsltr-msg[data-status='success'] {
  color: #d3f6df;
  background: rgba(40, 167, 69, 0.2);
  border-color: rgba(120, 226, 158, 0.35);
}

/* Banner background texture — performance.
   The theme's `.ul-banner::before` (home) and `.ul-breadcrumb::before` (every
   inner page's hero) both pulled in banner-bg-shape.svg, which wraps a
   4096×2388 JPEG as base64: a 2MB file (1.4MB even brotli'd) sitting on the LCP
   element, so the hero couldn't finish painting until it downloaded — on the
   home page and every inner page. It is a decorative texture shown at 0.2
   opacity with multiply blend, so resolution barely matters. Swapped for a
   37KB AVIF / 80KB WebP of the same texture; the 0.2 opacity that lived inside
   the SVG is reapplied here. Keeps the exact look at ~2% of the bytes. */
.ul-banner::before,
.ul-breadcrumb::before {
  /* Plain WebP first so a browser without image-set() still gets the small
     file, never the 2MB SVG; image-set() then upgrades to AVIF where supported. */
  background-image: url(../img/banner-bg-texture.webp);
  background-image: -webkit-image-set(
    url(../img/banner-bg-texture.avif) type('image/avif'),
    url(../img/banner-bg-texture.webp) type('image/webp')
  );
  background-image: image-set(
    url(../img/banner-bg-texture.avif) type('image/avif'),
    url(../img/banner-bg-texture.webp) type('image/webp')
  );
  opacity: 0.2;
}

/* Review/contact section background — same story as the banner texture: the
   theme loaded a 193KB PNG as a full-cover background. Swapped for a 10KB AVIF
   / 9KB WebP of the same image (it sits behind a form and reviews, so quality
   headroom is generous). */
.ul-review-contact {
  background-image: url(../img/contact-review-bg.webp);
  background-image: -webkit-image-set(
    url(../img/contact-review-bg.avif) type('image/avif'),
    url(../img/contact-review-bg.webp) type('image/webp')
  );
  background-image: image-set(
    url(../img/contact-review-bg.avif) type('image/avif'),
    url(../img/contact-review-bg.webp) type('image/webp')
  );
}

/* Banner stats: keep all three counters on one row on phones.
   The theme wraps them below 768px (flex-wrap: wrap), which drops the third
   counter ("70+ Team Members") onto its own line — the live site does this too.
   Requested to sit on a single row instead: nowrap plus tightened spacing and
   non-wrapping labels let the three fit across a ~360px screen. */
@media screen and (max-width: 767px) {
  .ul-banner-stats {
    flex-wrap: nowrap;
    gap: 0;
    padding-left: 10px;
    padding-right: 10px;
  }
  .ul-banner-stat {
    padding-right: 10px;
    margin-right: 10px;
  }
  .ul-banner-stat-text {
    white-space: nowrap;
    font-size: 13px;
  }
}

/* Banner: prevent the flash-of-unstyled-slides before Swiper initialises.
   Each column's four slides are server-rendered; until Swiper adds
   `.swiper-initialized` and positions them, they'd all stack full-size — a
   brief broken-looking banner on load, made more visible now that all four
   first slides are eager (for LCP). Showing only the first slide until Swiper
   is ready mirrors the settled state; the first slide is the eager/LCP image,
   so nothing above the fold is delayed. */
.ul-banner-slider:not(.swiper-initialized) .swiper-wrapper {
  display: block;
}
.ul-banner-slider:not(.swiper-initialized) .swiper-slide:not(:first-child) {
  display: none;
}
