@font-face {
  font-family: "Outfit";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("../fonts/Outfit-Light.ttf") format("truetype");
}
@font-face {
  font-family: "Outfit";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/Outfit-Regular.ttf") format("truetype");
}
@font-face {
  font-family: "Outfit";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/Outfit-Medium.ttf") format("truetype");
}
@font-face {
  font-family: "Outfit";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/Outfit-SemiBold.ttf") format("truetype");
}
@font-face {
  font-family: "Outfit";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/Outfit-Bold.ttf") format("truetype");
}
@font-face {
  font-family: "Outfit";
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("../fonts/Outfit-ExtraBold.ttf") format("truetype");
}
@font-face {
  font-family: "Outfit";
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url("../fonts/Outfit-Black.ttf") format("truetype");
}
:root {
  --oss-bg: #ffffff;
  --oss-surface: #fafafa;
  --oss-surface-2: #f4f4f5;
  --oss-hairline: #e5e5e5;
  --oss-hairline-strong: #d4d4d8;
  --oss-text: #0a0a0f;
  --oss-text-dim: #8b8b95;
  --oss-text-soft: #4a4a5a;
  --oss-cyan: #00ccff;
  --oss-cyan-dim: rgba(0, 204, 255, 0.18);
  --oss-cyan-edge: rgba(0, 204, 255, 0.35);
  --oss-red: #ef4444;

  --oss-display: "Outfit", ui-sans-serif, system-ui, sans-serif;
  --oss-body: "Outfit", ui-sans-serif, system-ui, sans-serif;
  --oss-mono: "Outfit", ui-monospace, "SFMono-Regular", monospace;

  --oss-max: 1440px;
  --oss-gutter: clamp(20px, 4vw, 56px);
}
* {
  box-sizing: border-box;
}
html,
body {
  margin: 0;
  padding: 0;
}
body {
  background-color: var(--oss-bg);
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.7)),
    url("../img/pattern-checkerboard.webp");
  background-repeat: repeat;
  background-position: top left;
  background-attachment: scroll;
  color: var(--oss-text);
  font-family: var(--oss-body);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}
a {
  color: inherit;
  text-decoration: none;
}
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}
.oss-shell {
  max-width: 1680px;
  margin: 0 auto;
  padding-inline: 2rem;
  position: relative;
}
.oss-section-rule {
  border-top: 1px solid var(--oss-hairline);
}
.oss-section-tag {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 0;
  font-family: var(--oss-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--oss-text-dim);
}
.oss-section-tag .oss-num {
  color: var(--oss-text);
  opacity: 0.55;
}
.oss-section-tag .oss-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--oss-cyan);
  box-shadow: 0 0 12px var(--oss-cyan-edge);
}
.oss-has-dropdown {
  position: relative;
}
.oss-has-dropdown > a::after {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-left: 8px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  opacity: 0.7;
  transition: transform 200ms ease;
}
.oss-has-dropdown:hover > a::after,
.oss-has-dropdown:focus-within > a::after {
  transform: translateY(0) rotate(225deg);
}
.oss-btn {
  display: inline-flex;
  align-items: center;
  gap: 18px;
  padding: 8px 8px 8px 28px;
  border-radius: 50px;
  font-family: var(--oss-body);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition:
    transform 180ms ease,
    background 180ms ease,
    color 180ms ease,
    border-color 180ms ease,
    box-shadow 180ms ease;
  white-space: nowrap;
  min-height: 60px;
  box-sizing: border-box;
}
.oss-btn--primary {
  background: var(--oss-cyan);
  color: #0a0a0f;
}
.oss-btn--primary:hover {
  transform: translateY(-1px);
  background: #1fd2ff;
}
.oss-btn--ghost {
  background: #ffffff;
  color: var(--oss-text);
  border: 2px solid #0a0a0f;
}
.oss-btn--ghost:hover {
  transform: translateY(-1px);
}
.oss-btn--sm {
  min-height: 48px;
  padding: 6px 6px 6px 22px;
  gap: 14px;
  font-size: 12px;
  border-radius: 50px;
}
.oss-btn .oss-arrow {
  width: 44px;
  height: 44px;
  border-radius: 999px;
  background: #ffffff;
  color: #0a0a0f;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-right: 0;
  flex-shrink: 0;
  transition: transform 180ms ease;
}
.oss-btn--sm .oss-arrow {
  width: 36px;
  height: 36px;
}
.oss-btn--primary .oss-arrow {
  background: #ffffff;
  color: #0a0a0f;
}
.oss-btn--ghost .oss-arrow {
  background: var(--oss-cyan);
  color: #0a0a0f;
}
.oss-btn .oss-arrow svg {
  width: 16px;
  height: 16px;
}
.oss-btn--sm .oss-arrow svg {
  width: 14px;
  height: 14px;
}
.oss-btn:hover .oss-arrow {
  transform: translateX(3px);
}
@keyframes blink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}
@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(0, 204, 255, 0.55);
  }
  100% {
    box-shadow: 0 0 0 14px rgba(0, 204, 255, 0);
  }
}
@keyframes marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}
.oss-problem {
  position: relative;
  padding: 100px 0;
  color: #ffffff;
}
.oss-problem::before {
  content: "";
  position: absolute;
  inset: 0;
  margin-inline: calc(50% - 50vw);
  background: #0a0a0f;
  z-index: -1;
  pointer-events: none;
}
@media (max-width: 640px) {
  .oss-problem {
    padding: 100px 0;
  }
}
@keyframes reviews-left {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}
@keyframes reviews-right {
  from {
    transform: translateX(-50%);
  }
  to {
    transform: translateX(0);
  }
}

/* The static design wraps every page in .shell, which supplies the 1680px cap and the 2rem
   page gutter; sections with a full-bleed background break back out of it with
   margin-inline: calc(50% - 50vw). Elementor supplies its own containers instead and would
   not take a custom class on them, so the same box is applied to each top-level block the
   plugin renders. Selectors are doubled so this wins whatever order the sheets load in —
   measured: without it every page ran 64px wider than the design and the split columns
   reflowed. */
.oss-nav.oss-nav,
.oss-hero.oss-hero,
.oss-tech.oss-tech,
.oss-about-section.oss-about-section,
.oss-services.oss-services,
.oss-process.oss-process,
.oss-case-studies.oss-case-studies,
.oss-faq.oss-faq,
.oss-cta-band.oss-cta-band,
.oss-svc-sec.oss-svc-sec,
.oss-site-footer.oss-site-footer {
  max-width: 1680px;
  margin-inline: auto;
  padding-inline: 2rem;
}

/* ── Font inheritance vs Elementor's Kit ───────────────────────────────────
   The design sets font-family explicitly on the classes it cares about and lets everything
   else inherit from `body`. Elementor's Kit emits `.elementor-kit-<id> { font-family: ... }`
   on the body element, which outranks our `body` rule — so every element the design left to
   inherit rendered in -apple-system instead of Outfit. Measured across all 18 pages: 40+
   elements affected, all of them plausible-looking at a glance.

   Setting the family on the widget wrapper fixes it by proximity rather than specificity:
   inheritance takes the nearest ancestor that declares a value, and the wrapper is nearer
   than <body>. */
[class*="elementor-widget-oss-"] {
  font-family: var(--oss-body);
  font-size: 16px;
  line-height: 1.5;
  color: var(--oss-text);
}

/* Hello's reset.css declares `h1, h2, h3, h4, h5, h6 { line-height: 1.2 }`. The design has no
   such reset, so a heading it never styles inherits body's 1.5 — the footer column titles are
   18px leading there and came out 14.4px here. A directly-matching rule always beats
   inheritance regardless of specificity, so proximity cannot fix this one; it needs a selector
   that outranks a bare element. `:where()` contributes zero, leaving (0,1,0) — enough to beat
   reset.css at (0,0,1), and low enough that the design's own single-class heading rules (also
   (0,1,0), in stylesheets enqueued after this one) still win on source order. */
[class*="elementor-widget-oss-"] :where(h1, h2, h3, h4, h5, h6) {
  line-height: inherit;
}

/* The design has `a { color: inherit }`, so a link takes the colour of whatever it sits in.
   Elementor's Kit sets an explicit link colour, which beat that rule — the logo anchor and
   the card wrappers came out #c36. Restored inside our widgets only. */
/* `:where()` contributes ZERO specificity, so this lands at (0,1,0) — enough to beat Hello's
   `a { color: … }` but NOT the design's own single-class link rules. Written as a plain
   descendant selector it was (0,1,1) and outranked `.oss-footer__office-phone`, which then
   rendered inherited white instead of cyan. */
[class*="elementor-widget-oss-"] :where(a) {
  color: inherit;
  text-decoration: none;
}

/* The same collision on the HOVER state, which the resting rule above does not cover:
   Elementor's Kit ships `a:hover { color: #336 }`, so every link and button in our widgets
   turned purple-ink on hover. Measured on the primary button — design keeps #0A0A0F, live went
   to #333366. At (0,2,0) this beats the Kit's (0,1,1) but stays under the design's own
   `.oss-x:hover` rules at (0,2,1), and sits early in this file so later same-specificity
   rules still win on source order. */
[class*="elementor-widget-oss-"] :where(a):hover,
[class*="elementor-widget-oss-"] :where(a):focus {
  color: inherit;
}

/* Hello's reset also repaints real <button>s: `[type="button"]:hover { color: #fff }` at
   (0,2,0), which turned the footer's Subscribe label white-on-cyan.
   `color: inherit` is NOT the fix here — it was, briefly, and it made things worse: a button
   in the dark footer inherits white. Links inherit correctly because the design says
   `a { color: inherit }`; a button carries its own colour, so the resting value is restated.
   (0,2,0) ties the reset and this file loads after it. */
.oss-btn--primary:hover,
.oss-btn--primary:focus {
  color: #0a0a0f;
}
.oss-btn--ghost:hover,
.oss-btn--ghost:focus {
  color: var(--oss-text);
}
/* The dark variant sits in the CTA band and is white in the design — not ink. */
.oss-btn--dark:hover,
.oss-btn--dark:focus {
  color: #ffffff;
}

/* Hello's reset also gives every bare <button> a hover BACKGROUND of #CC3366 — hot pink.
   Measured: the careers role toggle went white -> #CC3366, and the blog category buttons
   transparent -> #CC3366. The design changes only the text colour on these, never the fill.
   There is no generic way to say "keep whatever background you already had", so each bare
   button restates its own resting value; the list is every button the design leaves unfilled. */
.oss-role__toggle:hover,
.oss-role__toggle:focus {
  background-color: #ffffff;
}
.oss-blog-cat:hover,
.oss-blog-cat:focus,
.oss-faq-q:hover,
.oss-faq-q:focus,
.oss-faq-item__head:hover,
.oss-faq-item__head:focus,
.oss-reviews__viewport:hover,
.oss-cs-viewall:hover {
  background-color: transparent;
}

/* And the mirror of the same problem for TEXT colour.
   `:where(a):hover { color: inherit }` above is right for links the design leaves uncoloured
   (cards, nav, footer columns) but wrong for the ones it colours by class: the office phone
   link is cyan at rest and inherited ink on hover. Note Elementor's Kit was already breaking
   these before that rule existed — its `a:hover` outranks a single class either way — so the
   design colour has to be restated on hover regardless.
   Generated from the design: every class used on an <a> or <button> that sets a colour and has
   no colour-setting :hover rule of its own. Same (0,2,0) as the generic rule, later in the
   file, so these win. */
.oss-nav__hamburger:hover,
.oss-nav__hamburger:focus {
  color: #ffffff;
}
.oss-btn--primary:hover,
.oss-btn--primary:focus {
  color: #0a0a0f;
}
.oss-btn--ghost:hover,
.oss-btn--ghost:focus {
  color: var(--oss-text);
}
.oss-process__cta:hover,
.oss-process__cta:focus {
  color: #0a0a0f;
}
.oss-process__step:hover,
.oss-process__step:focus {
  color: #0a0a0f;
}
.oss-cs-card:hover,
.oss-cs-card:focus {
  color: inherit;
}
.oss-cs-viewall:hover,
.oss-cs-viewall:focus {
  color: #0a0a0f;
}
.oss-faq-item__head:hover,
.oss-faq-item__head:focus {
  color: #0a0a0f;
}
.oss-footer__office-phone:hover,
.oss-footer__office-phone:focus {
  color: var(--oss-cyan);
}
.oss-co-brand__link:hover,
.oss-co-brand__link:focus {
  color: var(--oss-cyan);
}
.oss-co-loc__tel:hover,
.oss-co-loc__tel:focus {
  color: var(--oss-cyan);
}
.oss-careers-email:hover,
.oss-careers-email:focus {
  color: var(--oss-cyan);
}

/* Hello's reset also sets `button:hover { background-color: #c36; color: #fff }`. The design
   gives these particular buttons no hover at all, so without neutralising it they gain a
   magenta fill on hover. Listed explicitly — the buttons that DO have a design hover must
   keep it. */
[class*="elementor-widget-oss-"] button.oss-faq-item__head:hover,
[class*="elementor-widget-oss-"] button.oss-faq-item__head:focus,
[class*="elementor-widget-oss-"] button.oss-process__step-head:hover,
[class*="elementor-widget-oss-"] button.oss-role__head:hover {
  background-color: transparent;
  color: inherit;
}

/* ── Hello Elementor's form reset ──────────────────────────────────────────
   reset.css styles buttons and inputs with ATTRIBUTE selectors, e.g.
   `[type=submit], button { background: transparent; border: 1px solid #c36; border-radius:
   3px }` and `input[type=email] { border: 1px solid #666; border-radius: 3px }`. Those tie
   with `.oss-btn` / `.oss-footer__input` on specificity, so whichever sheet prints last wins.

   The ordering fix is in inc/widgets-loader.php: our sheets now depend on Hello's, so they
   print after and the design's cascade is reproduced as authored. What is left here is only
   the geometry Hello's `button` rule sets that no design class re-states, so it would
   otherwise leak through on every bare button. */
[class*="elementor-widget-oss-"] button {
  width: auto;
  text-align: inherit;
  white-space: inherit;
}

/* `input[type=email]` in Hello's reset is (0,1,1), which outranks a single class whatever the
   source order — so these two need the extra class, not just the ordering fix above. */
[class*="elementor-widget-oss-"] input.oss-footer__input {
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  padding: 0 20px;
  width: 100%;
}
[class*="elementor-widget-oss-"] .oss-ct-field input,
[class*="elementor-widget-oss-"] .oss-ct-field textarea,
[class*="elementor-widget-oss-"] .oss-ct-field select {
  border: 1px solid #e5e5e5;
  border-radius: 12px;
  padding: 15px 18px;
}

/* Hello's reset also has `a:active, a:hover { color: #336 }` at (0,1,1). Where the design
   gives a link a hover that is NOT a colour change (the office phone only fades its opacity),
   that magenta-navy leaked through. `color: currentColor` is NOT the fix — in a `color`
   declaration currentColor resolves to the INHERITED value, so it painted the link white.
   The link keeps its resting colour explicitly instead. */
[class*="elementor-widget-oss-"] .oss-footer__office-phone:hover,
[class*="elementor-widget-oss-"] .oss-footer__office-phone:active {
  color: var(--oss-cyan);
}

/* Elementor's frontend.min.css carries
   `.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) figure { margin: 0 }`
   — two classes, two :not()s holding a class each, and an element, so (0,4,1). That outranks
   `.oss-cd-figure` at (0,1,0) and flattened the results figure's 64px top margin to zero.
   The value has to be restated because a competing declaration can only be beaten by another
   declaration; matching (0,4,1) and relying on source order would be a tie, so the doubled
   class takes this to (0,5,1) and settles it outright. */
.elementor
  .elementor-widget[class*="elementor-widget-oss-"]
  figure.oss-cd-figure.oss-cd-figure {
  margin: 64px auto 0;
}

/* Hello's reset.css styles bare tables: `table td, table th { border: 1px solid rgba(128,128,128,.5) }`
   and `table tbody > tr:nth-child(2n+1) > td { background: rgba(128,128,128,.07) }`. The design
   has neither, so the case-study before/after table came out with full cell gridlines and zebra
   striping. `.oss-cd-table td` only ever declares border-BOTTOM, so the other three sides were
   Hello's and survived.
   The border reset lands at (0,1,1) — beats reset.css at (0,0,2), and ties oss-casedetail.css,
   which loads later and so keeps its bottom rule. The stripe reset has to reach (0,1,4) to
   outrank the nth-child selector, hence the spelled-out descendant chain. */
[class*="elementor-widget-oss-"] table :where(td, th) {
  border-width: 0;
}
[class*="elementor-widget-oss-"] table tbody > tr > td,
[class*="elementor-widget-oss-"] table tbody > tr > th {
  background-color: transparent;
}
