/* Hand-written fixes layered on top of the Webflow export (loc-tech.css).
   Loaded after the other stylesheets on every page. A few Webflow <style> blocks inside
   the pages' <body> (the marquee's .scroll and the service cards' .grid__item-img rules)
   come later still, so overriding those needs a more specific selector. */

/* IBM Plex Sans Arabic (Arabic page text, the "عربي" link), self-hosted from Google
   Fonts' files: weights 400/500/700 in the Arabic, Latin and Latin-extended subsets.
   The browser only downloads a subset when the page uses its characters. Licence:
   fonts/IBMPlexSansArabic-OFL.txt. ar.html preloads the Bold Arabic file for its
   headline.
   The Arabic files also contain the space characters, which Google's ranges assign to
   the Latin files, so their ranges add U+0020 and U+00A0. Each Arabic face is declared
   after its Latin one because overlapping ranges are checked last-declared first. This
   way Arabic text takes its spaces from the (preloaded) Arabic file and doesn't re-wrap
   when the Latin file arrives. */
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/IBMPlexSansArabic-Regular-latin.woff2?v=4ba1584a') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/IBMPlexSansArabic-Regular-latin-ext.woff2?v=6b1f1c08') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/IBMPlexSansArabic-Regular-arabic.woff2?v=9f1801b4') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1, U+0020, U+00A0;
}

@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/IBMPlexSansArabic-Medium-latin.woff2?v=ce4a6922') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/IBMPlexSansArabic-Medium-latin-ext.woff2?v=2233b1c8') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/IBMPlexSansArabic-Medium-arabic.woff2?v=cf5bfd34') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1, U+0020, U+00A0;
}

@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/IBMPlexSansArabic-Bold-latin.woff2?v=9d640cf8') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/IBMPlexSansArabic-Bold-latin-ext.woff2?v=174ccd43') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('../fonts/IBMPlexSansArabic-Bold-arabic.woff2?v=d2604093') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1, U+0020, U+00A0;
}

/* Section titles were changed from h1 to h2 so each page has a single h1.
   This repeats the h1 tag styling from loc-tech.css; :where() keeps it at tag-level
   specificity so the existing class styles (.heading-primary, .cta, ...) still win. */
h2:where(.h1-style) {
  color: #fff;
  letter-spacing: -.01em;
  margin-top: 0;
  margin-bottom: .2em;
  font-family: Satoshi, Arial, sans-serif;
  font-size: 6.6rem;
  font-weight: 500;
  line-height: 1;
}

/* The hero headline is now the page's h1 (it was a div). Cancel the h1 tag
   defaults so it looks exactly as before; .hero-title still sets its own values. */
h1:where(.hero-title) {
  color: inherit;
  letter-spacing: inherit;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  margin: 0;
}

/* Readable contrast for testimonial attributions and the footer small print */
.review-caption {
  color: var(--b--600);
}

.footer-section .dfs-wrap-9 p {
  color: var(--b--400);
}

/* Palette addition alongside loc-tech.css's --a--500 / --a--600: a slightly deeper
   brand blue that reaches 4.5:1 contrast on the white and lavender section backgrounds */
:root {
  --a--550: #205afe;
}

/* Section eyebrow labels ("WHY LOCTECH?") */
.section-borrow {
  color: var(--a--550);
}

/* Show the "Tech Stack" link in the floating menu on phones too. loc-tech.css hides
   it below 480px; below 360px wide the four links don't fit, so it stays hidden there */
@media screen and (min-width: 360px) and (max-width: 479px) {
  .menu-link.not-mobile {
    display: flex;
  }
}

/* Arabic page reads right-to-left: point the stats-row arrows left
   (the shimmer animation flips with them) */
.body.arb .arrow-image {
  transform: scaleX(-1);
}

/* Stats-row arrows: a highlight sweeps along each one. Not for "reduce motion"
   visitors, who see the plain arrow. */
@keyframes shimmerMaskRL {
  0% {
    mask-position: 200% 0;
  }
  100% {
    mask-position: -200% 0;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .shimmer-mask.right-to-left {
    mask-image: linear-gradient(-90deg, transparent, black 25%, black 75%, transparent);
    mask-size: 200% 200%;
    mask-repeat: no-repeat;
    animation: shimmerMaskRL 2s linear infinite;
  }
}

/* Cursor of the typing lines (Typed.js adds it; see js/site.js) */
.typed-cursor {
  height: 1rem;
  width: .25rem;
  background-color: #8f00ff;
  color: #8f00ff;
}

/* "Inspired by the universe's ..." (Our mission): the sentence and the typed word have
   different sizes and line heights, so lining up their bottom edges (Webflow's flex-end)
   left the typed word sitting below the sentence. Line them up on the text baseline
   instead; the cursor, which has no text, then rests on that baseline too. */
.div-block {
  align-items: baseline;
}

/* Logical margin so the cursor hugs the word's end on the right-to-left page too */
.div-block .typed-cursor {
  margin-inline-start: -4px;
}

/* The Arabic line has the typed word in the middle ("مستلهمين من ... الكون"), so the
   sentence is split in two and each half must keep its own width rather than 30em */
.div-block .hero-sub:lang(ar) {
  max-width: none;
  white-space: nowrap;
}

/* Touch devices: process cards light up while in the middle of the screen, the same as
   hovering on desktop (class set by js/touch-hover.js). Not for "reduce motion"
   visitors. */
@media (prefers-reduced-motion: no-preference) {
  .dark-cover-glow.is-inview {
    -webkit-mask-image: linear-gradient(#fff 40%, #fff0 120%);
    mask-image: linear-gradient(#fff 40%, #fff0 120%);
  }
}

/* Hero headline fade-in: English letter by letter, Arabic word by word. LOC.splitHeadline
   (js/early.js, called right after each <h1>) splits the text and sets each piece's
   animation-delay. The curve matches the anime.js "easeOutExpo" the English headline
   animation used before. */
@keyframes text-reveal {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.text-reveal-unit {
  animation: text-reveal .8s cubic-bezier(.16, 1, .3, 1) both;
}

/* While the hero's fonts are still loading (see LOC.holdForFonts in js/early.js), the
   hero animations wait at their start and the held elements are hidden (keeping their
   space), so nothing is seen in a fallback font. hero-font-pending holds the Arabic
   headline (data-wait-for-font) and everything after it until the headline's font is
   in; hero-reveal-font-pending holds the subtitle, logo and buttons on both pages until
   the fonts their text uses are in. visibility: hidden also covers the spaces between
   the headline's words, which sit outside the faded word spans; without it their move
   when the text re-wraps counts as a layout shift. Only the visible (aria-hidden) copy is
   hidden, not the <h1> itself, so screen readers still find the heading and its
   aria-label. */
html.hero-font-pending .text-reveal-unit,
html.hero-font-pending .hero-reveal,
html.hero-reveal-font-pending .hero-reveal {
  animation-play-state: paused;
}

html.hero-font-pending [data-wait-for-font] > [aria-hidden],
html.hero-font-pending .hero-reveal,
html.hero-reveal-font-pending .hero-reveal {
  visibility: hidden;
}

/* English headline: until Formula has loaded (the hold in js/early.js gives up after
   2.5 s), it shows in Arial or, on Android, Roboto, scaled to Formula's widths and line
   metrics, so it wraps the same in either font and a late Formula moves almost nothing.
   Measured on the headline: Formula Bold is 116.61% as wide as Arial Bold and 124.53%
   as wide as Roboto Bold. The overrides are Formula's ascent and descent divided by
   those, because size-adjust scales them too. */
@font-face {
  font-family: "Formula Fallback Arial";
  src: local("Arial Bold"), local("Arial-BoldMT");
  font-weight: 700;
  size-adjust: 116.61%;
  ascent-override: 75.46%;
  descent-override: 24.01%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Formula Fallback Roboto";
  src: local("Roboto Bold"), local("Roboto-Bold");
  font-weight: 700;
  size-adjust: 124.53%;
  ascent-override: 70.66%;
  descent-override: 22.48%;
  line-gap-override: 0%;
}

.hero-title:lang(en) {
  font-family: Formula, "Formula Fallback Arial", "Formula Fallback Roboto", Arial, sans-serif;
}

/* Arabic text gets em widths instead of the ch ones in loc-tech.css. 1ch is the width of
   the font's "0", and Safari takes it from the Arabic IBM Plex file (the first face that
   has the space, see the @font-face rules above), which has no "0": 1ch fell to 0.5em
   there and the contact headline wrapped onto two lines. In Chrome 1ch is 0.6em, so
   these keep the same widths. */
.hero-sub:lang(ar) {
  max-width: 30em;
}

.cta:lang(ar) {
  max-width: 7.8em;
}

/* Hero logo: reserve its height before the SVG loads (its width comes from loc-tech.css),
   so the buttons below it don't jump down when it appears. 1234 x 194 is the SVG's size. */
.hero-logo {
  aspect-ratio: 1234 / 194;
  height: auto;
}

/* Hero subtitle, logo and buttons: fade in from 16px above after the headline, with the
   movement and easing of the Webflow "Hero Load" interaction they used before. As CSS
   they start from the first paint, together with the headline's fade, instead of
   waiting for the page's scripts. The English delays are Webflow's, tuned to the
   letter-by-letter fade; the Arabic ones overlap the end of the shorter word fade. */
@keyframes hero-reveal {
  from {
    opacity: 0;
    transform: translate3d(0, -16px, 0);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.hero-reveal {
  animation: hero-reveal 1s cubic-bezier(.22, 1, .36, 1) both;
}

.hero-reveal-1 {
  animation-delay: 1.4s;
}

.hero-reveal-2 {
  animation-delay: 1.8s;
}

.hero-reveal-3 {
  animation-delay: 2s;
}

.hero-reveal-1:lang(ar) {
  animation-delay: .7s;
}

.hero-reveal-2:lang(ar) {
  animation-delay: 1.1s;
}

.hero-reveal-3:lang(ar) {
  animation-delay: 1.3s;
}

/* Webflow slides the stats cards in from 100px to the left. On the right-to-left Arabic
   page, content past the left edge is scrollable, so phones briefly widened the page,
   zoomed out and made the fixed bottom menu jump. Clip it at the full-width section so
   the cards still slide in from the screen edge. "clip", unlike "hidden", doesn't turn
   the section into a scroll container or clip it vertically. */
.section:has(> .container-special) {
  overflow-x: clip;
}

/* Respect the visitor's "reduce motion" setting */
@media (prefers-reduced-motion: reduce) {
  .marquee-content.scroll,
  .hero-reveal,
  .text-reveal-unit {
    animation: none;
  }

  html {
    scroll-behavior: auto;
  }
}

/* The hero intro plays once. After the visitor changes the "reduce motion" setting,
   which switches it off above, it stays off rather than replaying when the setting is
   switched back (class set by js/early.js). */
html.hero-intro-done .hero-reveal,
html.hero-intro-done .text-reveal-unit {
  animation: none;
}
