/* ==========================================================================
   Spiders Solutions — site styles.
   Built on the Nocturne design system (_ds/nocturne-.../styles.css), which
   owns the tokens (--color-*, --font-*, --space-*, --radius-*). Nothing here
   redefines a token; this file is layout and page-specific composition only.
   ========================================================================== */

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
}
/* No `overflow-x: hidden` on body. It makes body's overflow-y compute to
   `auto`, which turns body into a scroll container whose scrollHeight equals
   its clientHeight — fragment navigation and scrollIntoView then silently do
   nothing (wheel scrolling still works, so it looks fine by hand). The only
   thing wider than the viewport is the hero's orb, and .hero clips that
   itself. */

a {
  color: var(--color-accent);
  text-decoration: none;
}
a:hover {
  color: var(--color-accent-300);
  text-decoration: underline;
}
a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

::selection {
  background: color-mix(in srgb, var(--color-accent) 35%, transparent);
}

@keyframes sp-spin {
  to { transform: rotate(360deg); }
}
@keyframes sp-drift {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 0.75; }
}

/* — shared shell — */

.shell {
  max-width: 1180px;
  margin: 0 auto;
  padding-inline: 32px;
  width: 100%;
}

.section {
  padding-top: 112px;
}

/* Sticky-header offset for in-page anchors. */
[id] {
  scroll-margin-top: 84px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 10px 18px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow-md);
}
.skip-link:focus {
  left: 16px;
  top: 16px;
}

.view[hidden] {
  display: none;
}

/* Section heading + trailing accent rule. */
.section-head {
  display: flex;
  align-items: baseline;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.section-head h2 {
  font-size: clamp(28px, 3.2vw, 40px);
  letter-spacing: -0.02em;
  margin: 0;
}
.section-head .rule {
  height: 1px;
  flex: 1;
  min-width: 80px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--color-accent) 60%, transparent), transparent);
}

.section-lede {
  color: var(--color-neutral-400);
  max-width: 560px;
  margin: 0 0 44px;
}
.section-lede--wide {
  margin-bottom: 48px;
}

/* — buttons — */

.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-accent);
  color: var(--color-accent-300);
  border-radius: var(--radius-md);
  padding: 11px 22px;
  text-decoration: none;
  font-size: 15px;
  transition: background-color 120ms ease, border-color 120ms ease;
}
.cta:hover {
  background: color-mix(in srgb, var(--color-accent) 14%, transparent);
  color: var(--color-accent-300);
  text-decoration: none;
}

.cta--quiet {
  border-color: color-mix(in srgb, var(--color-text) 16%, transparent);
  color: var(--color-neutral-200);
}
.cta--quiet:hover {
  background: transparent;
  border-color: var(--color-neutral-400);
  color: var(--color-neutral-200);
}

/* — header — */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  backdrop-filter: blur(14px);
  background: color-mix(in srgb, var(--color-bg) 82%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--color-text) 8%, transparent);
}
.site-header__inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 14px 32px;
  display: flex;
  align-items: center;
  gap: 32px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--color-text);
  text-decoration: none;
}
.brand:hover {
  color: var(--color-text);
  text-decoration: none;
}
.brand__mark {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--color-accent);
  display: block;
  flex: none;
  box-shadow: 0 0 12px color-mix(in srgb, var(--color-accent) 45%, transparent) inset;
}
.brand__name {
  font-family: var(--font-heading);
  font-weight: 500;
  letter-spacing: -0.01em;
  font-size: 16px;
  white-space: nowrap;
}

.site-nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 24px;
  font-size: 14px;
}
.site-nav a {
  color: var(--color-neutral-300);
  text-decoration: none;
}
.site-nav a:hover {
  color: var(--color-accent-300);
}

.lang-toggle {
  background: none;
  border: 1px solid color-mix(in srgb, var(--color-text) 18%, transparent);
  color: var(--color-neutral-400);
  border-radius: var(--radius-sm);
  padding: 4px 9px;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: border-color 120ms ease, color 120ms ease;
}
.lang-toggle:hover {
  border-color: var(--color-accent);
  color: var(--color-accent-300);
}

.site-nav .cta {
  padding: 7px 16px;
  font-size: 14px;
}

/* — hero — */

.hero {
  position: relative;
  overflow: hidden;
  min-height: 88vh;
  display: flex;
  align-items: center;
  padding: 96px 0 0;
}

/* Star field. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.55;
  animation: sp-drift 14s ease-in-out infinite;
  background-image:
    radial-gradient(1.5px 1.5px at  8% 14%, #e9e9ed 50%, transparent 50%),
    radial-gradient(1px   1px   at 21% 32%, #cfd3e5 50%, transparent 50%),
    radial-gradient(1px   1px   at 33%  9%, #e9e9ed 50%, transparent 50%),
    radial-gradient(1.5px 1.5px at 47% 24%, #d2cefd 50%, transparent 50%),
    radial-gradient(1px   1px   at 58%  6%, #b2b6ca 50%, transparent 50%),
    radial-gradient(1px   1px   at 66% 30%, #e9e9ed 50%, transparent 50%),
    radial-gradient(1.5px 1.5px at 78% 16%, #d2cefd 50%, transparent 50%),
    radial-gradient(1px   1px   at 88% 36%, #cfd3e5 50%, transparent 50%),
    radial-gradient(1px   1px   at 94% 11%, #e9e9ed 50%, transparent 50%),
    radial-gradient(1px   1px   at 14% 46%, #9397ab 50%, transparent 50%),
    radial-gradient(1px   1px   at 72% 48%, #9397ab 50%, transparent 50%),
    radial-gradient(1px   1px   at 40% 41%, #b2b6ca 50%, transparent 50%);
}

/* Outer bloom of the planet limb — a sibling layer because the orb itself
   clips its children. */
.hero::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -58vh;
  width: 150vw;
  height: 96vh;
  transform: translateX(-50%);
  border-radius: 50%;
  box-shadow: 0 0 70px 8px color-mix(in srgb, var(--color-accent) 26%, transparent);
  pointer-events: none;
  z-index: 0;
}

.hero__orb {
  position: absolute;
  left: 50%;
  bottom: -58vh;
  width: 150vw;
  height: 96vh;
  transform: translateX(-50%);
  border-radius: 50%;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  background: radial-gradient(120% 200% at 50% 8%, #343a6e 0%, #1f2239 34%, #181b2a 62%, #14161f 100%);
  box-shadow:
    inset 0 2px 0 color-mix(in srgb, #d2cefd 60%, transparent),
    0 -22px 90px color-mix(in srgb, var(--color-accent) 26%, transparent);
}

.hero__clouds {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  opacity: 0.55;
  animation: sp-spin 320s linear infinite;
  background-repeat: no-repeat;
  background-size: 34% 30%, 26% 22%, 40% 34%, 24% 20%, 30% 26%;
  background-image:
    radial-gradient(closest-side at 30% 22%, #3d4478 0%, transparent 100%),
    radial-gradient(closest-side at 58% 16%, #474e84 0%, transparent 100%),
    radial-gradient(closest-side at 46% 34%, #363c68 0%, transparent 100%),
    radial-gradient(closest-side at 16% 30%, #3f4677 0%, transparent 100%),
    radial-gradient(closest-side at 78% 30%, #3a406d 0%, transparent 100%);
}

.hero__meridians {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  opacity: 0.09;
  background-image: repeating-linear-gradient(
    90deg,
    transparent 0 7%,
    color-mix(in srgb, #d2cefd 40%, transparent) 7% 7.06%
  );
}

.hero__inner {
  position: relative;
  z-index: 3;
}
.hero__copy {
  max-width: 720px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}
.hero__eyebrow {
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent-300);
}
.hero h1 {
  font-size: clamp(38px, 5.4vw, 68px);
  line-height: 1.04;
  letter-spacing: -0.025em;
  margin: 0;
}
.hero__lede {
  font-size: 18px;
  line-height: 1.6;
  color: var(--color-neutral-300);
  max-width: 600px;
  text-wrap: pretty;
  margin: 0;
}
.hero__actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  padding-top: 6px;
}

/* — products — */

/* 250px min so four cards still fit one row at the 1180px shell; below that it
   steps down to three, two, one on its own. */
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

.product {
  border: 1px solid color-mix(in srgb, var(--color-text) 10%, transparent);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, #1c1f30 0%, #191b29 100%);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Media well. Ships as a styled placeholder; drop an <img> inside and the
   placeholder label steps aside. */
.product__media {
  position: relative;
  height: 220px;
  background: #14161f;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.product__media::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(80% 120% at 50% 120%, color-mix(in srgb, var(--color-accent) 16%, transparent) 0%, transparent 70%),
    repeating-linear-gradient(90deg, transparent 0 11%, color-mix(in srgb, #d2cefd 8%, transparent) 11% 11.4%);
}
.product__media img {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Website screenshots read as a page, so anchor the crop to the top-left rather
   than centring it: a centred crop drops the header for a meaningless middle
   band, and trims both sides so the headline loses its first letters. Anchored,
   the logo and headline survive and the crop comes off the far edge instead. */
.product__media--top img {
  object-position: left top;
}

/* Phone screenshots are about 0.46 wide-to-tall. Cropping one to a landscape
   well would throw away three quarters of the screen, so stand it up as a
   device instead and let the well's bottom edge cut it off. */
.product__media--device {
  align-items: flex-start;
  padding-top: 18px;
}
.product__media--device img {
  width: 156px;
  height: auto;
  flex: none;
  object-fit: contain;
  border: 1px solid color-mix(in srgb, var(--color-text) 16%, transparent);
  border-bottom: 0;
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -10px 34px rgba(0, 0, 0, 0.55);
}
.product__media-label {
  position: relative;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-neutral-600);
}
.product__media:has(img) .product__media-label,
.product__media:has(img)::before {
  display: none;
}

.product__body {
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex: 1;
}
.product__head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.product__head h3 {
  font-size: 22px;
  margin: 0;
}
.product__status {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 1px solid color-mix(in srgb, var(--color-text) 20%, transparent);
  color: var(--color-neutral-400);
  border-radius: 999px;
  padding: 3px 10px;
  white-space: nowrap;
}
.product__status--live {
  border-color: var(--color-accent-600);
  color: var(--color-accent-300);
}
.product__desc {
  color: var(--color-neutral-300);
  margin: 0;
  font-size: 14.5px;
  text-wrap: pretty;
}
.product__tags {
  list-style: none;
  padding: 0;
  margin: 6px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.product__tags li {
  font-size: 11.5px;
  color: var(--color-neutral-400);
  border: 1px solid color-mix(in srgb, var(--color-text) 12%, transparent);
  border-radius: var(--radius-sm);
  padding: 3px 8px;
}
.product__when {
  margin: auto 0 0;
  padding-top: 14px;
  font-size: 12.5px;
  color: var(--color-neutral-500);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px 16px;
  flex-wrap: wrap;
}
.product__link {
  font-size: 12.5px;
  white-space: nowrap;
}

/* — capabilities — */

.capability-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 36px 40px;
}
.capability {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.capability::before {
  content: "";
  height: 2px;
  width: 28px;
  background: var(--color-accent);
  display: block;
}
.capability h3 {
  margin: 0;
  font-size: 18px;
}
.capability p {
  margin: 0;
  color: var(--color-neutral-400);
  font-size: 14px;
  text-wrap: pretty;
}

/* — stats band — */

.stats {
  margin: 112px 0 0;
  background: var(--color-section);
  position: relative;
  overflow: hidden;
}
.stats::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(60% 120% at 15% 0%, var(--color-section-glow) 0%, transparent 70%);
}
.stats__grid {
  position: relative;
  padding-block: 64px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 32px;
}
.stat__figure {
  font-family: var(--font-heading);
  font-size: 44px;
  letter-spacing: -0.03em;
  line-height: 1;
}
.stat__label {
  font-size: 13px;
  color: var(--color-accent-200);
  letter-spacing: 0.04em;
  margin-top: 6px;
}

/* — studio — */

.studio-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 56px;
  align-items: start;
}
.studio__prose p {
  color: var(--color-neutral-300);
  font-size: 16px;
  text-wrap: pretty;
}
.studio__prose p:last-child {
  color: var(--color-neutral-400);
  font-size: 14.5px;
}
.studio__head {
  display: flex;
  align-items: baseline;
  gap: 20px;
  margin-bottom: 20px;
}
.studio__head h2 {
  font-size: clamp(28px, 3.2vw, 40px);
  letter-spacing: -0.02em;
  margin: 0;
}
.studio__head .rule {
  height: 1px;
  flex: 1;
  background: linear-gradient(90deg, color-mix(in srgb, var(--color-accent) 60%, transparent), transparent);
}

.engage {
  border: 1px solid color-mix(in srgb, var(--color-text) 10%, transparent);
  border-radius: var(--radius-lg);
  padding: 26px;
  background: #1a1c2b;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.engage h3 {
  margin: 0;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent-300);
}
.engage__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  font-size: 14px;
  color: var(--color-neutral-300);
  counter-reset: engage;
}
.engage__list li {
  display: flex;
  gap: 12px;
  counter-increment: engage;
}
.engage__list li::before {
  content: "0" counter(engage);
  color: var(--color-accent);
  flex: none;
}
.engage__link {
  font-size: 14px;
  margin-top: 4px;
}

/* — contact — */

.contact {
  padding-bottom: 96px;
}
.contact__grid {
  border-top: 1px solid color-mix(in srgb, var(--color-text) 12%, transparent);
  padding-top: 56px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 48px;
  align-items: start;
}
.contact h2 {
  font-size: clamp(28px, 3.2vw, 40px);
  letter-spacing: -0.02em;
  margin: 0 0 14px;
}
.contact__lede {
  color: var(--color-neutral-300);
  max-width: 420px;
  text-wrap: pretty;
}
.contact__email {
  margin-top: 14px;
  padding: 12px 24px;
  font-size: 16px;
  word-break: break-word;
}
.contact__details {
  font-size: 13.5px;
  color: var(--color-neutral-400);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.contact__details-title {
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-neutral-500);
  margin-bottom: 6px;
}
.contact__legal-name {
  color: var(--color-neutral-200);
}
.contact__details a {
  margin-top: 8px;
  align-self: flex-start;
}

/* — legal pages (privacy / terms) — */

.legal {
  max-width: 820px;
  margin: 0 auto;
  padding: 80px 32px 96px;
}
.legal__back {
  font-size: 13.5px;
}
.legal h1 {
  font-size: clamp(30px, 4vw, 44px);
  letter-spacing: -0.02em;
  margin: 22px 0 8px;
}
.legal__updated {
  color: var(--color-neutral-500);
  font-size: 13.5px;
  margin: 0 0 40px;
}
.legal__body {
  display: flex;
  flex-direction: column;
  gap: 30px;
  color: var(--color-neutral-300);
  font-size: 15px;
  line-height: 1.65;
}
.legal__body h2 {
  color: var(--color-text);
  font-size: 19px;
  margin: 0 0 8px;
}
.legal__body p {
  margin: 0 0 8px;
}
.legal__body p:last-child {
  margin-bottom: 0;
}
.legal__body strong {
  color: var(--color-neutral-200);
  font-weight: 600;
}

/* — footer — */

.site-footer {
  border-top: 1px solid color-mix(in srgb, var(--color-text) 10%, transparent);
  background: #13151f;
}
.site-footer__inner {
  padding-block: 36px;
  display: flex;
  flex-wrap: wrap;
  gap: 20px 40px;
  align-items: center;
  font-size: 13px;
  color: var(--color-neutral-500);
}
.site-footer nav {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}

/* — responsive — */

@media (max-width: 900px) {
  .studio-grid {
    gap: 40px;
  }
}

@media (max-width: 720px) {
  /* A wrapping sticky header would eat the viewport on a phone; let it
     scroll away instead. */
  .site-header {
    position: static;
  }
  .site-header__inner {
    flex-wrap: wrap;
    gap: 12px 20px;
    padding: 12px 20px;
  }
  .site-nav {
    margin-left: 0;
    width: 100%;
    flex-wrap: wrap;
    gap: 16px;
  }
  .shell {
    padding-inline: 20px;
  }
  .section {
    padding-top: 76px;
  }
  .stats {
    margin-top: 76px;
  }
  .hero {
    min-height: 78vh;
    padding-top: 56px;
  }
  /* At 150vw the limb is only ~1.5 screens wide, so its arc cuts through the
     copy instead of passing under it. Drop the orb until it clears the text. */
  .hero::after,
  .hero__orb {
    bottom: -74vh;
    width: 260vw;
  }
  .contact {
    padding-bottom: 72px;
  }
  .legal {
    padding: 56px 20px 72px;
  }
  [id] {
    scroll-margin-top: 20px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .hero::before,
  .hero__clouds {
    animation: none;
  }
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
  }
}
