/*
  Global defaults + shared component styles.
*/

body {
  font-family: var(--font-family-sans);
  color: var(--color-text-body);
  background-color: var(--color-background);

  /* Page-wide dot pattern. Source: Figma "Background Dots" frame (3:14),
     a 1600 × 599 tile. Rendered at natural size and tiled in both axes
     so the dot spacing stays consistent at every viewport width
     (instead of stretching/compressing as the window resizes). Swapped
     from the 838KB SVG to a 57KB PNG (~15× smaller, same pattern). */
  background-image: url("../images/bg-dots.png");
  background-repeat: repeat;
  background-position: top center;
}

/* Respect users who request reduced motion. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------
   Reveal animations (shared)
   --------------------------------------------------------------- */
/* `fade-rise` is the standard entrance animation used by sections
   throughout the site: fade in from transparent + rise 24px. Used by
   the hero on page load (with staggered delays). For below-the-fold
   sections, see the `.reveal` utility below instead. The reduced-motion
   rule above shortens the duration to ~0 so the end state still
   applies but without visible motion. */
@keyframes fade-rise {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Scroll-driven reveal utility. Any element marked .reveal starts
   transparent + 24px below its resting position. /assets/js/reveal.js
   uses an IntersectionObserver to add .is-revealed when the element
   crosses ~15% into view, which transitions it to the final state.
   `--reveal-delay` (settable per-element via CSS or inline style)
   lets you stagger neighbours. The reduced-motion override below
   pins .reveal elements straight to their final state so they're
   visible without animation. */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity 0.6s ease-out var(--reveal-delay, 0s),
    transform 0.6s ease-out var(--reveal-delay, 0s);
}

.reveal.is-revealed {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
  }
}

/* ---------------------------------------------------------------
   Container
   --------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
}

/* Screen-reader-only utility: hides content visually while keeping it
   in the accessibility tree. Standard "sr-only" pattern. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------------------------------------------------------------
   Button — shared CTA component (.btn / .btn--outline)
   First used in: site header "Let's Talk" (Step 3).
   --------------------------------------------------------------- */
/* The bg fill that sweeps in (or out) on hover lives on a ::before
   pseudo-element so we can animate it with transform: scaleX() — much
   cheaper than animating background-color. `isolation: isolate` plus
   `z-index: -1` on the pseudo keeps the fill behind the button's text
   and icon. `overflow: hidden` clips the fill to the pill shape. */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-family-sans);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-tight);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: color 0.22s ease-out, border-color 0.22s ease-out;
}

.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  /* Pill sits *above* the outgoing text (z-index 1) so the rising fill
     visibly covers the text from below — the text slides up "under"
     the pill. The incoming text (and the icon) are placed at z-index 2
     so they stay on top of the pill in the hover state. */
  z-index: 1;
  /* Match the button's pill outline so the rising fill is itself
     pill-shaped — its top edge is curved (not a flat line) at every
     intermediate scale, and it sits flush with the border on both ends
     at scaleY(1). */
  border-radius: inherit;
  /* transform + background set per variant below */
  transition: transform 0.22s ease-out;
}

/* --- Outline: empty by default, a full pill slides up from below on
   hover. translateY (not scaleY) keeps the pill at full size the whole
   way up, so it feels like a fresh pill is pushing the original pill
   out of the way instead of growing into it. --- */
.btn--outline {
  background-color: transparent;
  border-color: var(--color-accent);
  color: var(--color-text-on-dark);
}

.btn--outline::before {
  background-color: var(--color-accent);
  transform: translateY(100%);
}

.btn--outline:hover::before,
.btn--outline:focus-visible::before {
  transform: translateY(0);
}

.btn--outline:hover,
.btn--outline:focus-visible {
  color: var(--color-navy-blue);
}

/* --- Filled: teal by default; on hover the filled pill slides up and
   out the top, revealing the transparent hover state behind it. Same
   direction of motion as outline (everything moves up). --- */
.btn--filled {
  background-color: transparent;
  border-color: var(--color-accent);
  color: var(--color-navy-blue);
}

.btn--filled::before {
  background-color: var(--color-accent);
  transform: translateY(0);
  /* On filled buttons the pill is visible by *default* (it's the teal
     bg). Push it behind the text so the label reads through; the
     pill-on-top layering used by .btn--outline (so the rising fill
     can cover the text) doesn't apply here. */
  z-index: -1;
}

.btn--filled:hover::before,
.btn--filled:focus-visible::before {
  transform: translateY(-100%);
}

.btn--filled:hover,
.btn--filled:focus-visible {
  color: var(--color-text-on-dark);
}

/* Outline button modifier for use on light backgrounds — text starts
   navy and stays navy through the sweep. */
.btn--on-light {
  color: var(--color-navy-blue);
}

.btn--outline.btn--on-light:hover,
.btn--outline.btn--on-light:focus-visible {
  color: var(--color-navy-blue);
}

/* Filled button on a light background — same pill-rises-and-out motion
   as default .btn--filled, but the text + arrow stay navy through the
   hover sweep instead of flashing to white (which would disappear once
   the pill clears, since the page bg is light). Without this, light-bg
   filled CTAs (e.g. media-highlight-with-stats, alt-second-level-hero-
   intro on Roadmap, video-cta "Watch Recording") render white text/arrow
   on a transparent button mid-hover — invisible. */
.btn--filled.btn--on-light:hover,
.btn--filled.btn--on-light:focus-visible {
  color: var(--color-navy-blue);
}

/* Button label: a 1-line-tall, overflow-clipped wrapper holding two
   stacked copies of the text. The two copies are spaced an extra
   line apart and translate by twice their own height on hover. That
   way the outgoing text fully clears the visible slot *before* the
   incoming one enters — the slot is briefly empty mid-animation, no
   overlap, no "collapsed letters" artifact. The motion runs over the
   same duration as the bg fill, so they finish together. */
.btn__label {
  position: relative;
  display: inline-block;
  overflow: hidden;
  vertical-align: middle;
  line-height: 1;
}

.btn__label > span {
  display: block;
  line-height: 1;
  transition: transform 0.22s ease-out;
}

/* Outgoing copy: sits beneath the rising pill (z-index 0) so the pill
   visibly slides over it. */
.btn__label > span:nth-child(1) {
  position: relative;
  z-index: 0;
}

/* Incoming copy: stays on top of the pill (z-index 2). Starts one
   button-height below the slot and rises into place — that way it
   moves at the same pixel rate as the pill (both travel ~full button
   height in the same 0.22s). */
.btn__label > span:nth-child(2) {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  transform: translateY(300%);
}

.btn:hover .btn__label > span:nth-child(1),
.btn:focus-visible .btn__label > span:nth-child(1) {
  transform: translateY(-100px);
}

.btn:hover .btn__label > span:nth-child(2),
.btn:focus-visible .btn__label > span:nth-child(2) {
  transform: translateY(0);
}

/* Icon sits on top of the pill too — it doesn't get covered. */
.btn__icon {
  position: relative;
  z-index: 2;
  width: 14px;
  height: 5px;
  display: block;
  flex-shrink: 0;
  fill: currentColor;
}

/* ---------------------------------------------------------------
   CTA text link — text + 2px teal underline below.
   First used in: products section "Learn More". Reusable across sections.
   --------------------------------------------------------------- */
.cta-link {
  position: relative; /* anchors the ::after underline */
  display: inline-block;
  align-self: flex-start; /* don't stretch when used inside a flex column */
  width: fit-content;
  padding-bottom: var(--space-2);
  font-family: var(--font-family-sans);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-tight);
  color: var(--color-text-heading);
  text-decoration: none;
  transition: color 0.2s ease;
}

/* 2px teal underline rendered as a pseudo-element instead of a real
   border so we can animate it with a transform (cheap GPU op) instead
   of border-width. transform-origin: left pins the left edge, so
   scaleX(0) makes the right edge travel toward the left — the wipe
   visibly disappears right-to-left. */
.cta-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background-color: var(--color-accent);
  transform-origin: left center;
  transition: transform 0.35s ease;
}

/* Arrow that slides in just to the right of the label AFTER the underline
   has wiped away. Hidden by default; the hover rule below delays it by the
   underline's duration so the two animations sequence rather than overlap.
   The arrow glyph is a data-URI mask so it inherits the accent colour and
   needs no external asset (avoids the html/theme image-path divergence). */
.cta-link::before {
  content: "";
  position: absolute;
  left: 100%;
  /* Anchored from the BOTTOM, not the top. `top` is resolved against the
     padding box, so any section that adds padding-top to a .cta-link would
     push the label down while leaving the arrow behind. Measuring up from
     the bottom — past the component's own padding-bottom, then half a line —
     lands on the text centre regardless of what padding-top is applied. */
  bottom: calc(var(--space-2) + var(--font-size-sm) / 2);
  margin-left: var(--space-2);
  width: 14px;
  height: 5px;
  background-color: var(--color-accent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 5'%3E%3Cpath d='M10.0776 5C10.2385 4.62963 10.4061 4.29233 10.5805 3.9881C10.7548 3.68386 10.9358 3.4127 11.1236 3.1746H0V1.8254H11.1236C10.9358 1.5873 10.7548 1.31614 10.5805 1.0119C10.4061 0.694445 10.2385 0.357143 10.0776 0H11.3046C12.136 0.965609 13.0345 1.68651 14 2.1627V2.8373C13.0479 3.30026 12.1494 4.02116 11.3046 5H10.0776Z'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 5'%3E%3Cpath d='M10.0776 5C10.2385 4.62963 10.4061 4.29233 10.5805 3.9881C10.7548 3.68386 10.9358 3.4127 11.1236 3.1746H0V1.8254H11.1236C10.9358 1.5873 10.7548 1.31614 10.5805 1.0119C10.4061 0.694445 10.2385 0.357143 10.0776 0H11.3046C12.136 0.965609 13.0345 1.68651 14 2.1627V2.8373C13.0479 3.30026 12.1494 4.02116 11.3046 5H10.0776Z'/%3E%3C/svg%3E") no-repeat center / contain;
  opacity: 0;
  transform: translate(-8px, 50%);
  transition: opacity 0.25s ease-out, transform 0.25s ease-out;
}

/* Trigger the hover styles on the cta-link itself OR on any <a> ancestor
   that contains it. cta-link is typically a child of a wrapping card-link
   like <a class="products__card">, so hovering anywhere on the card should
   activate the underline wipe and the color change just like hovering
   the cta-link span directly. */
.cta-link:hover,
.cta-link:focus-visible,
a:hover .cta-link,
a:focus-visible .cta-link {
  color: var(--color-accent);
}

.cta-link:hover::after,
.cta-link:focus-visible::after,
a:hover .cta-link::after,
a:focus-visible .cta-link::after {
  transform: scaleX(0);
}

/* Arrow slides in after a delay (= the underline wipe duration) so it
   appears once the underline has cleared. Leaving hover, the base rule
   (no delay) hides it immediately. */
.cta-link:hover::before,
.cta-link:focus-visible::before,
a:hover .cta-link::before,
a:focus-visible .cta-link::before {
  opacity: 1;
  transform: translate(0, 50%);
  transition-delay: 0.35s;
}

/* ---------------------------------------------------------------
   Admin-only "[Edit: <id>]" pill — rendered by
   infleqtion_render_section_edit_link() for sections that have no
   per-card post to link to (e.g. Announcements, Featured Case Study).
   Each section positions the pill via its own scoped selector; this
   rule only defines the pill visuals.
   --------------------------------------------------------------- */
.section-edit-link {
  z-index: 3;
  font-family: var(--font-family-sans);
  font-size: 11px;
  font-weight: var(--font-weight-medium);
  letter-spacing: 0.03em;
  padding: 4px 8px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  text-decoration: none;
  transition: background 0.15s ease;
}

.section-edit-link:hover,
.section-edit-link:focus-visible {
  background: var(--color-green-2, #00a86b);
  color: #fff;
}

/* ---------------------------------------------------------------
   Careers page section rhythm — Figma 822:3489
   The Careers frame has ~120px gaps between sections; theme default
   is 40/60px per --section-padding-block. These sibling selectors
   fire ONLY on the Careers composition (tall banner immediately
   followed by Industries, and Industries immediately before Final
   CTA), so they don't leak onto other pages that reuse the same
   sections in different orders.
   --------------------------------------------------------------- */
.alt-second-level-hero--tall + .heading-linked-card-grid-with-icon-text {
  padding-block: clamp(80px, 68.39px + 3.226vw, 120px);
}

.heading-linked-card-grid-with-icon-text + .final-cta {
  padding-block-start: clamp(80px, 68.39px + 3.226vw, 120px);
}

/* Overlap tune (Careers + Contact-us) — pull the tall banner and the
   closing CTA up by the same clamp. On the Contact-us composition the
   closing CTA follows region-address-columns instead of Industries;
   both selectors trigger. */
.alt-second-level-hero--tall,
.alt-second-level-hero--extra-tall {
  margin-top: clamp(-54px, -6.5vw, -44px);
}

.heading-linked-card-grid-with-icon-text + .final-cta,
.region-address-columns + .final-cta {
  margin-top: clamp(-54px, -6.5vw, -44px);
}

/* Contact-us: lift the inquiry-form panel up into the tall hero so it
   overlaps the bottom of the banner (Figma 851:472). */
.alt-second-level-hero--tall + .contact-form .contact-form__panel,
.alt-second-level-hero--extra-tall + .contact-form .contact-form__panel {
  /* Eased off by 8px across the whole range (was -114/-6.5vw/-44) so the
     panel clears the hero subheading — design review, all breakpoints. */
  margin-top: clamp(-106px, calc(-6.5vw + 8px), -36px);
}
