/* ==========================================================================
   Chrome — nav, dropdown, mobile overlay, footer, preview chip.
   Identical across all three homepage variants so the comparison is purely
   about the page body.
   ========================================================================== */

/* --- Nav ------------------------------------------------------------------ */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  border-bottom: none;
}

/* --- Glass -----------------------------------------------------------------

   A single backdrop-filter gives one hard blur edge: content is perfectly sharp
   at one pixel and fully blurred at the next, which reads as a band sitting on
   top of the page rather than as glass.

   Instead, four tiers stack. Each blurs harder than the last and is masked to a
   shorter band from the top, so the blur ramps down toward the nav's lower edge
   and content dissolves gradually as it scrolls underneath.

   The tiers extend past the nav's own height (--nav-glass-h) so the ramp has
   room to finish below the bar. Pointer events are off throughout.
--------------------------------------------------------------------------- */

.nav {
  --nav-glass-h: calc(var(--nav-h) + 26px);
  --nav-glass-o: 0;
  /* How long the bar takes to change sides. Slower than a hover so it reads as
     the bar adapting to the page rather than as a state toggle. */
  --nav-swap: 420ms var(--ease-out);
  /* 0 over dark, 1 over light. nav.js flips the class; everything that has to
     change colour cross-fades on this one number. */
  --nav-light: 0;
}

.nav.is-on-light {
  --nav-light: 1;
}

.nav.is-scrolled {
  --nav-glass-o: 1;
}

.nav__glass {
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--nav-glass-h);
  pointer-events: none;
  z-index: 0;
}

.nav__glass-tier,
.nav__glass-tint,
.nav__glass-edge {
  position: absolute;
  inset: 0;
  display: block;
}

.nav__glass-tier {
  /* Fades in on scroll so the hero sits untouched at the top of the page. */
  opacity: var(--nav-glass-o);
  transition: opacity var(--dur) var(--ease-out);
  will-change: opacity;
}

/* Each tier: blur strength up, masked band down. The mask is what turns four
   discrete blurs into one continuous gradient. */
.nav__glass-tier[data-tier="1"] {
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 100%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 100%, transparent 100%);
}

.nav__glass-tier[data-tier="2"] {
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 58%, transparent 88%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 58%, transparent 88%);
}

.nav__glass-tier[data-tier="3"] {
  backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 34%, transparent 66%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 34%, transparent 66%);
}

.nav__glass-tier[data-tier="4"] {
  backdrop-filter: blur(26px) saturate(165%);
  -webkit-backdrop-filter: blur(26px) saturate(165%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 12%, transparent 44%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 12%, transparent 44%);
}

/* Tint carries the surface colour, and fades out on the same ramp so the glass
   has no visible bottom border.

   Both tints — ink and paper — live on pseudo-elements of the same span and
   cross-fade against each other. A gradient can't be transitioned, and stacking
   the paper one over the ink one wouldn't work either: the paper tint tops out
   at 0.86 alpha, so the ink beneath would show through and the bar would read
   grey over a white page. Only one of the two is ever visible at rest. */
.nav__glass-tint,
.nav__glass-edge {
  opacity: var(--nav-glass-o);
  transition: opacity var(--dur) var(--ease-out);
}

.nav__glass-tint::before,
.nav__glass-tint::after,
.nav__glass-edge::before,
.nav__glass-edge::after {
  content: "";
  position: absolute;
  inset: 0;
  transition: opacity var(--nav-swap);
}

/* ::before is the dark treatment, ::after the light one. */
.nav__glass-tint::before,
.nav__glass-edge::before {
  opacity: calc(1 - var(--nav-light));
}

.nav__glass-tint::after,
.nav__glass-edge::after {
  opacity: var(--nav-light);
}

.nav__glass-tint::before {
  background: linear-gradient(
    to bottom,
    rgba(10, 10, 15, 0.74) 0%,
    rgba(10, 10, 15, 0.6) 46%,
    rgba(10, 10, 15, 0) 100%
  );
}

.nav__glass-tint::after {
  background: linear-gradient(
    to bottom,
    rgba(253, 252, 251, 0.86) 0%,
    rgba(253, 252, 251, 0.7) 46%,
    rgba(253, 252, 251, 0) 100%
  );
}

/* Specular hairline along the top edge — the cue that sells it as a material
   rather than a translucent rectangle. */
.nav__glass-edge {
  height: var(--nav-h);
}

.nav__glass-edge::before {
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.1) 0,
    rgba(255, 255, 255, 0) 2px
  );
  box-shadow: inset 0 -1px 0 rgba(232, 232, 240, 0.06);
}

.nav__glass-edge::after {
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.6) 0,
    rgba(255, 255, 255, 0) 2px
  );
  box-shadow: inset 0 -1px 0 rgba(21, 21, 27, 0.07);
}

/* backdrop-filter is the whole effect; without it the tint alone would be a
   flat scrim over live content. Fall back to an opaque bar instead. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav.is-scrolled .nav__glass-tint::before {
    background: rgba(10, 10, 15, 0.94);
  }
  .nav.is-scrolled .nav__glass-tint::after {
    background: rgba(253, 252, 251, 0.97);
  }
}

/* Heavy stacked blur is expensive and can shimmer during momentum scroll.
   Collapse to one modest tier when motion is unwelcome. */
@media (prefers-reduced-motion: reduce) {
  .nav__glass-tier,
  .nav__glass-tint,
  .nav__glass-edge,
  .nav__glass-tint::before,
  .nav__glass-tint::after,
  .nav__glass-edge::before,
  .nav__glass-edge::after {
    transition: none;
  }
  .nav__glass-tier[data-tier="2"],
  .nav__glass-tier[data-tier="3"],
  .nav__glass-tier[data-tier="4"] {
    display: none;
  }
  .nav__glass-tier[data-tier="1"] {
    backdrop-filter: blur(12px) saturate(140%);
    -webkit-backdrop-filter: blur(12px) saturate(140%);
  }
}

/* When the nav sits over a paper section it inverts: ink text, and the black
   lockup in place of the white one. The surface itself is handled by
   .nav__glass-tint above — this block is text and iconography only.

   Every property here transitions, so a section boundary passing under the bar
   reads as the bar changing its mind rather than as a hard cut. nav.js holds
   these off for the first frame after load (.is-surface-init) so the opening
   state arrives already correct. */

.nav.is-on-light .nav__link {
  color: var(--ink-muted);
}

.nav.is-on-light .nav__link:hover,
.nav.is-on-light .nav__link:focus-visible,
.nav.is-on-light .nav__link[aria-expanded="true"],
.nav.is-on-light .nav__link[aria-current="page"] {
  color: var(--ink);
}

.nav.is-on-light .nav__login,
.nav.is-on-light .nav__login:visited {
  color: var(--ink);
  border-color: var(--line);
}

.nav.is-on-light .nav__login:hover,
.nav.is-on-light .nav__login:focus-visible {
  border-color: var(--purple);
  background: rgba(97, 25, 172, 0.05);
}

.nav.is-on-light .nav__burger-bar {
  background: var(--ink);
}

/* purple-light is tuned for a dark backdrop; the deeper purple is the one that
   holds against paper. */
.nav.is-on-light .nav__link[aria-current="page"]::after {
  background: var(--purple);
}

/* The one frame after nav.js takes its first reading. Without this, a page
   whose hero is paper would fade the whole bar from white to ink in front of
   the visitor every single load. */
.nav.is-surface-init,
.nav.is-surface-init *,
.nav.is-surface-init *::before,
.nav.is-surface-init *::after {
  transition-duration: 0s !important;
}

.nav__inner {
  /* Above .nav__glass, which is a sibling at z-index 0. */
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1560px;
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  gap: var(--sp-4);
}

.nav__logo {
  flex: none;
  display: block;
}

/* Two lockups stacked in the same box, cross-fading. The alternative — one white
   PNG under filter: invert(1) — snaps, and animating the filter would drag the
   mark through grey on the way past 50%. */
.nav__logo-swap {
  position: relative;
  display: block;
  transition: opacity var(--dur) var(--ease-out);
}

/* The lockup is two stacked words, so it reads larger than its height suggests.
   28px on desktop sits better against the 76px bar; mobile keeps a touch more
   presence since it is the only branding on screen. */
.nav__logo img {
  display: block;
  width: auto;
  height: 28px;
}

.nav__logo-swap img + img {
  position: absolute;
  inset: 0;
}

.nav__logo-swap .nav__logo-ink {
  opacity: var(--nav-light);
  transition: opacity var(--nav-swap);
}

.nav__logo-swap .nav__logo-paper {
  opacity: calc(1 - var(--nav-light));
  transition: opacity var(--nav-swap);
}

@media (max-width: 1080px) {
  .nav__logo img {
    height: 32px;
  }
}

.nav__logo:hover .nav__logo-swap {
  opacity: 0.78;
}

.nav__primary {
  margin-inline: auto;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: clamp(0.35rem, 1.4vw, 1.4rem);
}

.nav__item {
  position: relative;
}

.nav__link {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: 0.02em;
  color: var(--muted);
  padding: 0.7em 0.75em;
  border-radius: var(--radius);
  transition: color var(--dur) var(--ease-out);
  white-space: nowrap;
}

.nav__link:hover,
.nav__link:focus-visible,
.nav__link[aria-expanded="true"] {
  color: var(--white);
}

.nav__link[aria-current="page"] {
  color: var(--white);
}

/* A hairline under the active item — the accent system, not a filled pill. */
.nav__link[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0.75em;
  right: 0.75em;
  bottom: 0.35em;
  height: 1px;
  background: var(--purple-light);
}

.nav__caret {
  transition: transform var(--dur) var(--ease-out);
}

.nav__link[aria-expanded="true"] .nav__caret {
  transform: rotate(180deg);
}

/* Dropdown */
.nav__menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 50%;
  translate: -50% 0;
  min-width: 310px;
  background: rgba(20, 20, 32, 0.94);
  backdrop-filter: blur(22px) saturate(150%);
  -webkit-backdrop-filter: blur(22px) saturate(150%);
  border: 1px solid var(--divider);
  border-radius: var(--radius-lg);
  padding: 0.5rem;
  box-shadow: 0 30px 70px -30px rgba(0, 0, 0, 0.9);

  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--dur) var(--ease-out),
    transform var(--dur) var(--ease-out),
    visibility var(--dur);
}

.nav__item--has-menu.is-open .nav__menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.nav__menu a {
  display: block;
  padding: 0.85rem 1rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
  transition: background var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.nav__menu a:hover,
.nav__menu a:focus-visible {
  background: rgba(139, 92, 246, 0.08);
  border-color: rgba(139, 92, 246, 0.28);
}

/* Type comes from the nav-label role in typography.css. */
.nav__menu-title {
  display: block;
  color: var(--white);
}

.nav__menu-blurb {
  display: block;
  margin-top: 0.2rem;
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--muted);
}

/* margin-left:auto rather than relying on .nav__primary's auto margins — that
   element is display:none below 1080px, so without this the burger collapses
   back against the logo instead of sitting at the right edge. */
.nav__end {
  flex: none;
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.nav__login,
.nav__login:visited {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--step--1);
  color: var(--warm-white);
  padding: 0.7em 1.15em;
  border: 1px solid var(--divider);
  border-radius: var(--radius);
  transition: color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    background var(--dur) var(--ease-out);
}

.nav__login:hover,
.nav__login:focus-visible {
  color: var(--white);
  border-color: var(--purple-light);
  background: rgba(139, 92, 246, 0.08);
}

.nav__login:active {
  color: var(--white);
}

.nav__burger {
  display: none;
  width: 44px;              /* 44px keeps the tap target at the iOS minimum */
  height: 44px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin-right: -10px;      /* optically align the bars with the gutter */
}

/* 1.5px bars 6px apart read as an equals sign at phone size. Thicker strokes,
   a wider gap and rounded ends make it read as a menu control. */
.nav__burger-bar {
  display: block;
  width: 24px;
  height: 2px;
  border-radius: 2px;
  background: var(--warm-white);
  transition: transform var(--dur) var(--ease-out),
    opacity var(--dur) var(--ease-out);
}

/* Matched from the end, not the start. The button's first child is the
   screen-reader-only "Menu" label, so `.nav__burger-bar:first-child` selected
   nothing at all and only the lower bar ever rotated — the open state rendered
   as a slash with a stray horizontal stroke rather than an X.
   The bars are the last two children; counting backwards is stable.

   Each travels half the centre-to-centre distance so the two meet on the
   midline: with 2px bars and a 7px gap that is (2 + 7) / 2 = 4.5px. Keep this
   in step with .nav__burger-bar's height and .nav__burger's gap. */
.nav__burger[aria-expanded="true"] .nav__burger-bar:nth-last-child(2) {
  transform: translateY(4.5px) rotate(45deg);
}

.nav__burger[aria-expanded="true"] .nav__burger-bar:nth-last-child(1) {
  transform: translateY(-4.5px) rotate(-45deg);
}

/* --- Mobile overlay -------------------------------------------------------- */

.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 99;
  /* Nearly opaque before; the video sits behind the panel now, so the surface
     colour moved to .mobile-nav__scrim where it can be tuned for legibility
     without hiding the footage entirely. */
  background: rgba(10, 10, 15, 0.6);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  padding: calc(var(--nav-h) + var(--sp-4)) var(--gutter) var(--sp-6);
  overflow-y: auto;
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
}

/* --- Mobile nav background video ------------------------------------------ */

.mobile-nav__bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}

.mobile-nav__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Menu links sit directly on the footage, so this is carrying legibility, not
   decoration — and it is carrying all of it. A negative-z child paints above
   its parent's background, so .mobile-nav's own tint is behind the video and
   contributes nothing. These values are set for the brightest frame of the
   loop; the footage should read as texture, not as a picture. */
.mobile-nav__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(10, 10, 15, 0.95),
    rgba(10, 10, 15, 0.89) 45%,
    rgba(10, 10, 15, 0.97)
  );
}

/* The menu is a scrolling panel, so its content has to sit above the fixed
   background layer. */
.mobile-nav > nav {
  position: relative;
  z-index: 1;
}

@media (prefers-reduced-motion: reduce) {
  .mobile-nav__video {
    display: none;
  }
  .mobile-nav__bg {
    background: var(--black);
  }
}

.mobile-nav[hidden] {
  display: none;
}

.mobile-nav.is-open {
  opacity: 1;
}

.mobile-nav__list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--divider);
}

.mobile-nav__list > li {
  border-bottom: 1px solid var(--divider);
}

.mobile-nav__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 1.15rem 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-2);
  letter-spacing: -0.01em;
  color: var(--warm-white);
  text-align: left;
}

.mobile-nav__link:hover,
.mobile-nav__link:focus-visible {
  color: var(--white);
}

.mobile-nav__accordion[aria-expanded="true"] svg {
  transform: rotate(180deg);
}

.mobile-nav__accordion svg {
  transition: transform var(--dur) var(--ease-out);
}

.mobile-nav__sub {
  padding: 0 0 1rem 0;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.mobile-nav__sub[hidden] {
  display: none;
}

.mobile-nav__sub a {
  color: var(--muted);
  font-size: var(--step-0);
  padding-left: 1rem;
  border-left: 1px solid var(--divider);
}

.mobile-nav__sub a:hover,
.mobile-nav__sub a:focus-visible {
  color: var(--white);
  border-left-color: var(--purple-light);
}

.mobile-nav__link--login {
  color: var(--purple-light);
}

.mobile-nav__cta {
  width: 100%;
  justify-content: center;
  margin-top: var(--sp-4);
}

/* iOS Safari ignores overflow:hidden on <body>, so the page keeps scrolling
   under the overlay. Pinning the body is the reliable version; nav.js restores
   the scroll position on close. */
body.nav-open {
  overflow: hidden;
  position: fixed;
  inset: 0;
  width: 100%;
}

/* The overlay must sit above the nav, otherwise the nav's backdrop-filter
   samples the menu behind it and paints a blurred band across the top of it.
   The burger stays reachable because it is re-exposed above the overlay. */
.mobile-nav {
  z-index: 101;
}

body.nav-open .nav {
  z-index: 102;
}

/* Glass over a solid overlay is just a smear — switch it off while open. */
body.nav-open .nav__glass {
  display: none;
}

@media (max-width: 1080px) {
  .nav__primary {
    display: none;
  }
  .nav__burger {
    display: flex;
  }
  .nav__login {
    display: none;
  }
}

@media (min-width: 1081px) {
  .mobile-nav {
    display: none !important;
  }
}

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

.foot {
  background: var(--black);
  border-top: 1px solid var(--divider);
  padding-top: var(--sp-7);
  position: relative;
  z-index: 2;
}

/* Four columns, matching live: brand blurb, Services, Contact + Socials,
   Schedule Call. The brand column is widest because it carries the paragraph. */
/* Brand, Services, Company, Contact, Schedule Call. The two link columns are
   narrower than the rest because they hold short labels; Contact carries an
   address that needs the room. */
.foot__inner {
  display: grid;
  grid-template-columns: 1.5fr 1fr 0.75fr 1.15fr 1.4fr;
  gap: var(--sp-6) var(--sp-5);
  padding-bottom: var(--sp-6);
}

.foot__logo {
  height: 40px;
  width: auto;
}

.foot__blurb {
  margin-top: var(--sp-2);
  color: var(--muted);
  font-size: var(--step-0);
  line-height: 1.6;
  max-width: 38ch;
  text-wrap: pretty;
}

.foot__social {
  display: flex;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}

.foot__social a {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  color: var(--muted);
  border: 1px solid var(--divider);
  transition: color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    background var(--dur) var(--ease-out);
}

.foot__social a:hover,
.foot__social a:focus-visible {
  color: var(--white);
  border-color: var(--purple-light);
  background: rgba(97, 25, 172, 0.18);
}

.foot__head {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--white);
  margin-bottom: var(--sp-3);
}

.foot__links {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.foot__links a {
  color: var(--muted);
  font-size: var(--step-0);
  transition: color var(--dur) var(--ease-out);
}

.foot__links a:hover,
.foot__links a:focus-visible {
  color: var(--white);
}

/* Contact rows are icon + value, so they need to align rather than stack. */
.foot__links--contact li {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  color: var(--muted);
  font-size: var(--step-0);
  line-height: 1.5;
}

.foot__ico {
  flex: none;
  margin-top: 0.2em;
  color: var(--purple-light);
}

.foot__head--socials {
  margin-top: var(--sp-4);
}

.foot__col--cta .foot__blurb {
  margin-top: 0;
  max-width: 34ch;
}

.foot__cta {
  margin-top: var(--sp-3);
  width: 100%;
}

.foot__base {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding-block: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--divider);
  color: var(--muted);
  font-size: var(--step--1);
}

.foot__base a:hover,
.foot__base a:focus-visible {
  color: var(--white);
}

@media (max-width: 1080px) {
  .foot__inner {
    grid-template-columns: 1fr 1fr;
  }
  .foot__brand {
    grid-column: 1 / -1;
  }
}

@media (max-width: 620px) {
  .foot__inner {
    grid-template-columns: 1fr;
  }
}

/* --- Preview picker chip ---------------------------------------------------- */


/* --- Page-transition loader -------------------------------------------------
   A fast flash of the mark while the browser swaps pages. transition.js adds
   .is-active on internal-link click and pageshow clears it, so the overlay
   only exists during the real navigation gap. Fade-in is quicker than the
   fade-out so an instant load barely registers. */
.page-loader {
  position: fixed;
  inset: 0;
  z-index: 240;
  display: grid;
  place-items: center;
  background: #0a0a0f;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.2s ease,
    visibility 0s linear 0.2s;
}

.page-loader.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.1s ease;
}

.page-loader img {
  animation: arcrelLoaderPulse 0.9s ease-in-out infinite;
}

@keyframes arcrelLoaderPulse {
  50% {
    opacity: 0.5;
    transform: scale(0.94);
  }
}

@media (prefers-reduced-motion: reduce) {
  .page-loader {
    display: none;
  }
}
