/* =========================================================
   ArmorForge 3D — Design System
   Industrial precision + technology + craftsmanship
   ========================================================= */

:root {
  /* Colors */
  --bg: #0a0b0d;
  --bg-alt: #131417;
  --bg-elevated: #1a1c20;
  --bg-elevated-2: #202226;
  --border: #2a2d32;
  --border-strong: #3a3d43;

  --text: #f1efe9;
  --text-muted: #9a9da3;
  /* Lightened from #6c6f75 (3.9:1) to clear WCAG AA 4.5:1 on --bg — it carries
     real text (footer IČO, media tags), not just decoration. Now ~4.8:1. */
  --text-faint: #7a7d84;

  --accent: #2e6ef0;
  --accent-hover: #5089ff;
  /* --accent as body text is only 4.3:1 on --bg; this lighter tint (~6:1) is
     the one to use whenever the accent colour carries text rather than sits
     behind it. Buttons keep --accent as a background (white on it passes). */
  --accent-text: #5089ff;
  --accent-dim: rgba(46, 110, 240, 0.14);
  --accent-line: rgba(46, 110, 240, 0.35);

  /* Secondary "steel" accent — pairs with --accent for gradients/glows */
  --accent-2: #9ba3af;
  --gradient-brand: linear-gradient(135deg, var(--accent) 0%, var(--accent-2) 100%);
  --glow-accent: 0 16px 44px -14px rgba(46, 110, 240, 0.5);
  --glow-accent-sm: 0 6px 22px -8px rgba(46, 110, 240, 0.42);

  --success: #4caf7d;
  --danger: #e5484d;

  /* Typography */
  --font-display: "Noto Sans", "Segoe UI", system-ui, sans-serif;
  --font-body: "Noto Sans", "Segoe UI", system-ui, sans-serif;

  /* Spacing scale */
  --space-1: 0.5rem;
  --space-2: 0.75rem;
  --space-3: 1rem;
  --space-4: 1.5rem;
  --space-5: 2rem;
  --space-6: 3rem;
  --space-7: 4.5rem;
  --space-8: 7rem;

  /* Layout */
  --container: 1240px;
  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 18px;
  --radius-pill: 999px;

  --shadow: 0 10px 40px -12px rgba(0, 0, 0, 0.6);
  --transition: 180ms ease;

  /* Motion — expo-out is the signature curve: fast start, long graceful settle */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
  --reveal-duration: 900ms;
}

/* ---------- Reset ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* The header is sticky and 91px tall, so a #hash jump would otherwise park the
     target section underneath it. Applied globally via scroll-padding so every
     anchor target (service sections, #poptavka, #dale) clears the header. */
  scroll-padding-top: calc(91px + 1.5rem);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img,
svg {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

button {
  font-family: inherit;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  margin: 0 0 var(--space-3);
  text-wrap: balance;
}

/* Display headings: large, light and tightly tracked. The weight drops as the
   size grows so big type reads as considered rather than shouty. */
h1 {
  font-size: clamp(2.6rem, 6vw, 4.6rem);
  font-weight: 300;
  line-height: 1.04;
  letter-spacing: -0.035em;
}

h2 {
  font-size: clamp(2rem, 3.6vw, 3.1rem);
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: -0.03em;
}

h3 {
  font-size: 1.15rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.012em;
}

h4 {
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
}

p {
  margin: 0 0 var(--space-3);
  color: var(--text-muted);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  /* Show every animated element outright rather than leaving it mid-transition */
  .js .reveal,
  .js .hero-rise {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }
  .js .word > span {
    transform: none !important;
  }
  .scroll-cue,
  .scroll-progress {
    display: none !important;
  }
  .ambient::before,
  .ambient::after {
    animation: none !important;
  }
}

/* Focus visibility */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: #ffffff;
  padding: 0.75rem 1.25rem;
  z-index: 200;
  font-weight: 600;
  border-radius: 0 0 var(--radius-sm) 0;
}
/* Visually hidden but still announced — used for live-region status text that
   would be redundant on screen (the filtered grid is already visible). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link:focus {
  left: 0;
}

/* ---------- Layout helpers ---------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

.section {
  padding-block: var(--space-8);
}

.section--tight {
  padding-block: var(--space-6);
}

/* Alternating band. The edges dissolve into the page instead of being cut by a
   hard rule, so sections read as one continuous surface. */
.section--alt {
  background: linear-gradient(
    180deg,
    rgba(19, 20, 23, 0) 0%,
    rgba(19, 20, 23, 1) 12%,
    rgba(19, 20, 23, 1) 88%,
    rgba(19, 20, 23, 0) 100%
  );
}

.section--alt::before,
.section--alt::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(46, 110, 240, 0.28) 50%, transparent);
}

.section--alt::before {
  top: 0;
}

.section--alt::after {
  bottom: 0;
}

.section-head {
  max-width: 640px;
  margin-bottom: var(--space-6);
}

.section-head--center {
  max-width: 640px;
  margin-inline: auto;
  text-align: center;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-display);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--space-2);
}

.eyebrow::before {
  content: "";
  width: 22px;
  height: 2px;
  background: var(--accent);
  display: inline-block;
}

.grid {
  display: grid;
  gap: var(--space-4);
}

.grid-2 {
  grid-template-columns: repeat(2, 1fr);
}
.grid-3 {
  grid-template-columns: repeat(3, 1fr);
}
.grid-4 {
  grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 900px) {
  .grid-3,
  .grid-4 {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 620px) {
  .grid-2,
  .grid-3,
  .grid-4 {
    grid-template-columns: 1fr;
  }
}

.text-muted {
  color: var(--text-muted);
}

.badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.3em 0.7em;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
  background: var(--bg-elevated);
}

.badge--accent {
  color: var(--accent);
  border-color: var(--accent-line);
  background: var(--accent-dim);
}

/* Gradient text — use sparingly, on one emphasised word/phrase per heading */
.text-gradient {
  color: var(--accent);
}

@supports (background-clip: text) or (-webkit-background-clip: text) {
  .text-gradient {
    background: var(--gradient-brand);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
  }
}

/* Quiet supplementary info — a caveat or aside that supports the main copy
   without competing with it. Brand-colored border keeps it on-system. */
.info-note {
  font-size: 0.85rem;
  color: var(--text-muted);
  border-left: 2px solid var(--accent-line);
  padding-left: 0.7em;
}

/* ---------- Buttons ---------- */
.btn {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  padding: 0.9em 1.8em;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: -0.01em;
  border: 1px solid transparent;
  cursor: pointer;
  transition:
    transform 320ms var(--ease-out-expo),
    background 260ms var(--ease-smooth),
    border-color 260ms var(--ease-smooth),
    color 260ms var(--ease-smooth),
    box-shadow 320ms var(--ease-smooth);
  white-space: nowrap;
}

.btn:hover {
  transform: translateY(-2px);
}

.btn:active {
  transform: translateY(0);
}

.btn-primary {
  background: var(--gradient-brand);
  color: #ffffff;
  box-shadow: var(--glow-accent-sm);
}

/* Specular sweep — reads as a highlight catching a metal edge */
.btn-primary::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    transparent 25%,
    rgba(255, 255, 255, 0.45) 50%,
    transparent 75%
  );
  transform: translateX(-100%);
  transition: transform 750ms var(--ease-out-expo);
  pointer-events: none;
}

.btn-primary:hover::after {
  transform: translateX(100%);
}

.btn-primary:hover {
  box-shadow: var(--glow-accent);
}

.btn-secondary {
  background: transparent;
  color: var(--text);
  border-color: var(--border-strong);
}
.btn-secondary:hover {
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-line);
}

.btn-ghost {
  background: transparent;
  color: var(--text-muted);
  padding: 0.5em 0;
}
.btn-ghost:hover {
  color: var(--accent);
}

.btn-block {
  width: 100%;
}

.btn-sm {
  padding: 0.72em 1.32em;
  font-size: 1.02rem;
}

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(10, 11, 13, 0.86);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
  transition: box-shadow var(--transition), background var(--transition);
}

.site-header.is-scrolled {
  background: rgba(10, 11, 13, 0.95);
  box-shadow: 0 16px 40px -22px rgba(0, 0, 0, 0.8);
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 91px;
}

.logo {
  display: flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
}

.logo .mark {
  width: 50px;
  height: 50px;
  flex: none;
  object-fit: contain;
  border-radius: 50%;
}

/* Header-only: footer keeps the base 50px/1.05rem size above */
.site-header .logo {
  font-size: 1.26rem;
}

.site-header .logo .mark {
  width: 60px;
  height: 60px;
}

.main-nav {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.nav-links {
  display: flex;
  gap: var(--space-5);
}

.nav-links a {
  font-size: 1.1rem;
  color: var(--text-muted);
  font-weight: 500;
  transition: color var(--transition);
  position: relative;
}

.nav-links a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -22px;
  height: 2px;
  background: var(--gradient-brand);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--transition);
}

.nav-links a:hover,
.nav-links a[aria-current="page"] {
  color: var(--text);
}

.nav-links a:hover::after,
.nav-links a[aria-current="page"]::after {
  transform: scaleX(1);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.nav-toggle {
  display: none;
  background: none;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  width: 50px;
  height: 50px;
  color: var(--text);
  cursor: pointer;
  align-items: center;
  justify-content: center;
}

@media (max-width: 900px) {
  /* The header's backdrop-filter makes it the containing block for fixed
     children, so `bottom: 0` would resolve against the 91px header rather than
     the viewport. An explicit height keeps the panel full-height regardless. */
  .main-nav {
    position: fixed;
    top: 91px;
    left: 0;
    right: 0;
    height: calc(100vh - 91px);
    height: calc(100dvh - 91px);
    background: var(--bg);
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    padding: var(--space-5) var(--space-4) var(--space-6);
    gap: var(--space-5);
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--transition), transform var(--transition);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .main-nav.is-open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }
  .nav-links {
    flex-direction: column;
    gap: 0;
  }
  /* Full-width rows with generous tap targets so every section is obvious */
  .nav-links li + li {
    border-top: 1px solid var(--border);
  }
  .nav-links a {
    display: block;
    padding: var(--space-4) 0;
    font-size: 1.35rem;
    font-weight: 500;
    letter-spacing: -0.02em;
    color: var(--text);
  }
  .nav-links a[aria-current="page"] {
    color: var(--accent);
  }
  .nav-links a::after {
    display: none;
  }
  .header-actions {
    flex-direction: column;
    align-items: stretch;
  }
  .header-actions .btn {
    width: 100%;
  }
  .nav-toggle {
    display: inline-flex;
  }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  overflow: hidden;
  min-height: min(82vh, 740px);
  display: flex;
  align-items: center;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}

.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 60%;
  display: block;
}

.hero-overlay {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(900px 520px at 6% 12%, rgba(46, 110, 240, 0.28), transparent 60%),
    linear-gradient(100deg, rgba(10, 11, 13, 0.93) 0%, rgba(10, 11, 13, 0.78) 40%, rgba(10, 11, 13, 0.4) 68%, rgba(10, 11, 13, 0.12) 100%),
    linear-gradient(180deg, rgba(10, 11, 13, 0.25) 0%, rgba(10, 11, 13, 0) 22%, rgba(10, 11, 13, 0) 68%, rgba(10, 11, 13, 0.95) 100%);
}

.hero-inner {
  position: relative;
  z-index: 1;
  padding-block: var(--space-7);
}

.hero-copy {
  max-width: 640px;
}

.hero-copy h1 {
  margin-bottom: var(--space-4);
}

/* Each word is wrapped by JS so it can rise out of its own clipping mask —
   the headline assembles itself rather than simply fading in. */
.word {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
}

.js .word > span {
  display: inline-block;
  transform: translateY(105%);
  transition: transform 1000ms var(--ease-out-expo);
  transition-delay: var(--word-delay, 0ms);
}

.js .is-revealed .word > span {
  transform: translateY(0);
}

.hero-copy .lead {
  font-size: 1.12rem;
  max-width: 46ch;
  margin-bottom: var(--space-5);
  color: #b9bcc2;
}

/* Hero entrance — the copy settles in after the headline words land */
.js .hero-rise {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity 900ms var(--ease-out-expo),
    transform 900ms var(--ease-out-expo);
  transition-delay: var(--rise-delay, 0ms);
}

.js .is-revealed .hero-rise {
  opacity: 1;
  transform: translateY(0);
}

/* ---------- Scroll cue ---------- */
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: var(--space-4);
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55em;
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-faint);
  transition: color var(--transition);
}

.scroll-cue:hover {
  color: var(--accent);
}

.scroll-cue .track {
  width: 22px;
  height: 34px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  position: relative;
}

.scroll-cue .track::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 7px;
  width: 3px;
  height: 6px;
  margin-left: -1.5px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  animation: scrollPulse 2s var(--ease-smooth) infinite;
}

@keyframes scrollPulse {
  0% { transform: translateY(0); opacity: 0; }
  35% { opacity: 1; }
  70% { transform: translateY(12px); opacity: 0; }
  100% { transform: translateY(12px); opacity: 0; }
}

@media (max-width: 900px) {
  .scroll-cue {
    display: none;
  }
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}

.hero-stats {
  display: flex;
  gap: var(--space-6);
  border-top: 1px solid rgba(241, 239, 233, 0.14);
  padding-top: var(--space-4);
}

.hero-stats .stat b {
  display: block;
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--text);
}

.hero-stats .stat span {
  font-size: 0.82rem;
  color: var(--text-faint);
}

@media (max-width: 640px) {
  .hero {
    min-height: auto;
  }
  .hero-inner {
    padding-block: var(--space-8) var(--space-6);
  }
  .hero-overlay {
    background:
      linear-gradient(180deg, rgba(10, 11, 13, 0.55) 0%, rgba(10, 11, 13, 0.55) 55%, rgba(10, 11, 13, 0.97) 100%);
  }

  /* A flex row pushes the third stat off-screen; an equal-width grid keeps all
     three inside the viewport and lets their labels wrap instead. */
  .hero-stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-3);
  }
  .hero-stats .stat b {
    font-size: 1rem;
  }
  .hero-stats .stat span {
    font-size: 0.74rem;
    line-height: 1.35;
    display: block;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-video {
    display: none;
  }
  .hero-media {
    background: center 60% / cover no-repeat url("../assets/hero/hero-poster.jpg");
  }
}

/* ---------- Cards ---------- */
.card {
  position: relative;
  isolation: isolate;
  background:
    linear-gradient(160deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0) 45%),
    var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  overflow: hidden;
  transition:
    border-color 320ms var(--ease-smooth),
    transform 420ms var(--ease-out-expo),
    box-shadow 420ms var(--ease-out-expo);
}

/* Light sweeps diagonally across the card on hover */
.card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    115deg,
    transparent 30%,
    rgba(155, 163, 175, 0.09) 48%,
    transparent 66%
  );
  transform: translateX(-100%);
  transition: transform 900ms var(--ease-out-expo);
  pointer-events: none;
}

.card:hover::after {
  transform: translateX(100%);
}

.card:hover {
  border-color: rgba(46, 110, 240, 0.42);
  transform: translateY(-4px);
  box-shadow: 0 28px 60px -28px rgba(46, 110, 240, 0.4);
}

/* ---------- Technical diagram panels (schematic SVGs) ---------- */
.hero-visual {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-alt);
  box-shadow: 0 30px 64px -36px rgba(46, 110, 240, 0.28);
}

.hero-visual svg {
  width: 100%;
  height: 100%;
  display: block;
}

.hero-visual img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.service-card .icon {
  width: 44px;
  height: 44px;
  color: var(--accent);
  margin-bottom: var(--space-3);
}

.service-card h3 {
  font-size: 1.15rem;
  margin-bottom: var(--space-2);
}

/* The heading link is the card's only real link, but its ::after stretches over
   the whole card so the entire tile is clickable. Keeps one clear link target
   for screen readers and gives the anchor text to the service page. */
.service-card h3 a {
  color: inherit;
  text-decoration: none;
}

.service-card h3 a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

.service-card:hover h3 a,
.service-card h3 a:focus-visible {
  color: var(--accent-text);
}

/* Focus ring belongs on the card, since the link itself is only the heading text */
.service-card h3 a:focus-visible {
  outline: none;
}

.service-card:has(h3 a:focus-visible) {
  outline: 2px solid var(--accent-text);
  outline-offset: 3px;
}

.service-card ul {
  margin-top: var(--space-3);
  display: grid;
  gap: 0.5em;
}

.service-card ul li {
  font-size: 0.88rem;
  color: var(--text-muted);
  padding-left: 1.2em;
  position: relative;
}

.service-card ul li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 6px;
  height: 6px;
  background: var(--accent);
  border-radius: 1px;
}

/* ---------- Process ---------- */
.process-list {
  position: relative;
  display: grid;
  gap: 0;
  counter-reset: step;
}

/* Rail behind the step numbers; the accent fill tracks scroll progress via JS */
.process-list::before {
  content: "";
  position: absolute;
  left: 27px;
  top: var(--space-4);
  bottom: var(--space-4);
  width: 2px;
  background: var(--border);
}

.process-list::after {
  content: "";
  position: absolute;
  left: 27px;
  top: var(--space-4);
  width: 2px;
  height: calc((100% - var(--space-4) * 2) * var(--process-progress, 0));
  background: var(--gradient-brand);
  box-shadow: 0 0 14px rgba(46, 110, 240, 0.55);
  transition: height 220ms linear;
}

.process-item {
  position: relative;
  display: grid;
  grid-template-columns: 90px 1fr;
  gap: var(--space-4);
  padding-block: var(--space-4);
  border-top: 1px solid var(--border);
}

.process-item:last-child {
  border-bottom: 1px solid var(--border);
}

.process-item .num {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--border-strong);
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--accent);
  font-weight: 700;
  transition:
    border-color 420ms var(--ease-smooth),
    box-shadow 420ms var(--ease-smooth);
}

.process-item.is-visible .num {
  border-color: rgba(46, 110, 240, 0.5);
  box-shadow: 0 0 0 4px rgba(46, 110, 240, 0.09);
}

.process-item h3 {
  font-size: 1.1rem;
  margin-bottom: 0.3em;
}

@media (max-width: 620px) {
  .process-item {
    grid-template-columns: 46px 1fr;
    gap: var(--space-3);
  }
  .process-item .num {
    width: 46px;
    height: 46px;
    font-size: 0.92rem;
  }
  /* Re-centre the rail on the smaller circle */
  .process-list::before,
  .process-list::after {
    left: 22px;
  }
}

/* ---------- Portfolio ---------- */
.portfolio-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}

.filter-btn {
  border: 1px solid var(--border-strong);
  background: transparent;
  color: var(--text-muted);
  padding: 0.5em 1.1em;
  border-radius: 999px;
  font-size: 0.85rem;
  cursor: pointer;
  transition: all var(--transition);
}

.filter-btn:hover {
  color: var(--text);
  border-color: var(--text-muted);
}

.filter-btn.is-active {
  background: var(--gradient-brand);
  border-color: transparent;
  color: #ffffff;
  box-shadow: var(--glow-accent-sm);
}

.portfolio-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--bg-alt);
  transition: transform var(--transition), border-color var(--transition), box-shadow var(--transition);
}

.media-frame {
  aspect-ratio: 1 / 1;
  background: linear-gradient(145deg, var(--bg-elevated-2), var(--bg-alt));
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}

.media-frame svg {
  width: 40%;
  color: var(--border-strong);
}

.media-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transition: transform 600ms cubic-bezier(0.2, 0.6, 0.2, 1);
}

/* Tall phone photos whose subject sits high in frame would lose their top edge on a centred crop */
.media-frame img.focus-top {
  object-position: center 20%;
}

.portfolio-card:hover .media-frame img {
  transform: scale(1.04);
}

.media-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(46, 110, 240, 0) 55%, rgba(46, 110, 240, 0.18) 100%);
  opacity: 0;
  transition: opacity var(--transition);
  pointer-events: none;
}

.portfolio-card:hover .media-frame::after {
  opacity: 1;
}

.portfolio-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 24px 54px -26px rgba(46, 110, 240, 0.3);
}

.media-frame .media-tag {
  position: absolute;
  bottom: var(--space-2);
  left: var(--space-2);
  font-size: 0.68rem;
  color: var(--text-faint);
  background: rgba(10, 11, 13, 0.7);
  padding: 0.25em 0.6em;
  border-radius: 999px;
  border: 1px solid var(--border);
}

.portfolio-card .body {
  padding: var(--space-4);
}

.portfolio-card h3 {
  font-size: 1.02rem;
  margin-bottom: 0.2em;
}

.portfolio-card .meta {
  font-size: 0.78rem;
  color: var(--text-faint);
  margin-bottom: 0.6em;
}

/* ---------- Testimonials / FAQ ---------- */
.testimonial {
  border-left: 2px solid var(--accent);
  padding-left: var(--space-4);
}

.testimonial p {
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: var(--text);
}

.testimonial cite {
  font-style: normal;
  font-size: 0.85rem;
  color: var(--text-faint);
}

.faq-item {
  border-top: 1px solid var(--border);
}
.faq-item:last-child {
  border-bottom: 1px solid var(--border);
}

.faq-item summary {
  cursor: pointer;
  padding: var(--space-4) 0;
  font-family: var(--font-display);
  font-weight: 600;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  list-style: none;
  transition: color var(--transition);
}

.faq-item summary:hover {
  color: var(--accent);
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item summary::after {
  content: "+";
  font-size: 1.4rem;
  color: var(--accent);
  transition: transform var(--transition);
  flex: none;
}

.faq-item[open] summary::after {
  transform: rotate(45deg);
}

.faq-item .faq-answer {
  padding-bottom: var(--space-4);
  max-width: 65ch;
}

/* ---------- CTA band ---------- */
.cta-band {
  position: relative;
  overflow: hidden;
  background: var(--bg-alt);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  text-align: center;
  padding-block: var(--space-7);
}

.cta-band::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(760px 360px at 50% -20%, rgba(46, 110, 240, 0.22), transparent 65%),
    radial-gradient(circle, rgba(241, 239, 233, 0.05) 1px, transparent 1px);
  background-size: auto, 26px 26px;
  pointer-events: none;
}

.cta-band .container {
  position: relative;
  z-index: 1;
}

.cta-band h2 {
  font-size: clamp(1.8rem, 3vw, 2.4rem);
}

.cta-band .actions {
  display: flex;
  justify-content: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: var(--space-4);
}

/* ---------- Forms ---------- */
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 0.4em;
}

.form-field.full {
  grid-column: 1 / -1;
}

.form-field label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text);
}

.form-field .optional {
  color: var(--text-faint);
  font-weight: 400;
}

.form-field input,
.form-field select,
.form-field textarea {
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 0.8em 1em;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 0.95rem;
  transition: border-color var(--transition);
}

/* Consent checkbox — the label wraps the control, so the whole line is a hit
   target and no separate for/id wiring is needed. */
.consent {
  display: flex;
  align-items: flex-start;
  gap: 0.7em;
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--text-muted);
  cursor: pointer;
}

.consent input[type="checkbox"] {
  flex: none;
  width: 1.15em;
  height: 1.15em;
  margin-top: 0.15em;
  accent-color: var(--accent);
  cursor: pointer;
}

.consent a {
  color: var(--accent-text);
}

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-dim);
}

.form-field textarea {
  resize: vertical;
  min-height: 120px;
}

.upload-zone {
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius);
  padding: var(--space-5);
  text-align: center;
  color: var(--text-muted);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}

.upload-zone:hover,
.upload-zone.is-dragover {
  border-color: var(--accent);
  background: var(--accent-dim);
  box-shadow: 0 0 0 3px var(--accent-dim);
}

.upload-zone svg {
  width: 32px;
  height: 32px;
  margin: 0 auto var(--space-2);
  color: var(--accent);
}

.file-list {
  margin-top: var(--space-2);
  display: grid;
  gap: 0.4em;
}

.file-list li {
  font-size: 0.82rem;
  color: var(--text-muted);
  display: flex;
  justify-content: space-between;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.5em 0.8em;
}

.form-note {
  font-size: 0.8rem;
  color: var(--text-faint);
  margin-top: var(--space-2);
}

.form-status {
  margin-top: var(--space-3);
  padding: 0.9em 1.1em;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  display: none;
}

.form-status.is-visible {
  display: block;
}

.form-status.success {
  background: rgba(76, 175, 125, 0.12);
  color: var(--success);
  border: 1px solid rgba(76, 175, 125, 0.35);
}

.form-status.error {
  background: rgba(229, 72, 77, 0.12);
  color: var(--danger);
  border: 1px solid rgba(229, 72, 77, 0.35);
}

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

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--border);
  padding-block: var(--space-7) var(--space-5);
  background: var(--bg-alt);
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: var(--space-6);
  margin-bottom: var(--space-6);
}

.footer-brand .logo {
  margin-bottom: var(--space-3);
}

/* Semantically an <h2> (keeps the footer landmark free of skipped heading
   levels) but styled as a small eyebrow label, so the display-h2 size and
   weight have to be overridden explicitly. */
.footer-col .footer-heading {
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.25;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  margin-bottom: var(--space-3);
}

.footer-col ul {
  display: grid;
  gap: 0.7em;
}

/* NAP block — repeated on every page so the locality is a site-wide signal.
   <address> italicises by default, which reads as emphasis here rather than
   as a contact block, so it is reset. */
.footer-nap {
  font-style: normal;
  font-size: 0.86rem;
  line-height: 1.6;
  color: var(--text-muted);
  margin-top: var(--space-3);
}

.footer-col a {
  color: var(--text-muted);
  font-size: 0.92rem;
  transition: color var(--transition);
}

.footer-col a:hover {
  color: var(--accent);
}

.social-row {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.social-row a {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
}

.social-row a:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* Scoped to the icon links specifically — the hint arrow also lives inside
   .social-row and must keep its own, much larger size. */
.social-row a svg {
  width: 16px;
  height: 16px;
}

/* Compact variant for the header, next to the CTA — no border box, tighter gap */
.social-row--inline {
  position: relative;
  margin-top: 0;
  gap: var(--space-1);
}

/* ---------- Social hint ----------
   A hand-drawn-feeling note pointing up at the icons. Anchored to the icon row
   itself rather than the header edge, so the arrow lands on the icons and not
   on the CTA button beside them. It floats over the hero, so it fades out on
   the first scroll instead of shadowing the page forever. */
.social-hint {
  position: absolute;
  /* The drawn tip sits ~18px below this box's top edge (the SVG carries empty
     space above it), so the offset is tuned to the *drawn* arrow clearing the
     76px header bar by a hair rather than to the box itself. */
  top: calc(100% + 10px);
  /* Anchored from the row's left edge so the tip, which sits near the arrow's
     own left side, lands between the middle icons */
  left: 16px;
  pointer-events: none;
  color: #fff;
  /* The entrance animation lives on the children: a filled (`forwards`)
     animation outranks normal declarations, so animating this element directly
     would make the scrolled-away rule below unable to hide it. */
  transition: opacity 350ms var(--ease-smooth);
}

.social-hint__arrow {
  display: block;
  width: 80px;
  height: 96px;
  /* A slight tilt keeps the sketch from reading as a geometric UI glyph */
  transform-origin: 50% 0;
  rotate: -4deg;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.6));
  opacity: 0;
  transform: translateY(-6px);
  animation: socialHintIn 900ms var(--ease-out-expo) 1200ms forwards;
}

/* Absolutely placed so its centre line pins to where the arrow's tail ends,
   independent of how many lines the sentence wraps to. */
.social-hint__text {
  position: absolute;
  left: 88px;
  top: 82px;
  width: 230px;
  margin: 0;
  text-align: left;
  font-size: 1.5rem;
  font-style: italic;
  font-weight: 500;
  line-height: 1.3;
  color: #fff;
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.75);
  opacity: 0;
  transform: translateY(calc(-50% - 6px));
  animation: socialHintTextIn 900ms var(--ease-out-expo) 1200ms forwards;
}

@keyframes socialHintIn {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Mirrors socialHintIn but preserves the -50% that does the centring */
@keyframes socialHintTextIn {
  to {
    opacity: 1;
    transform: translateY(-50%);
  }
}

/* Out of the way as soon as the reader starts moving down the page */
.site-header.is-scrolled .social-hint {
  opacity: 0;
}

/* Hidden well before the mobile nav breakpoint: the note keeps a fixed offset
   from the container's right edge, so on a narrow desktop it would start
   drifting into the hero headline before the header ever collapses. */
@media (max-width: 1000px) {
  .social-hint {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .social-hint__arrow {
    animation: none;
    opacity: 1;
    transform: none;
  }
  /* Keeps the centring transform — dropping it would shove the text down */
  .social-hint__text {
    animation: none;
    opacity: 1;
    transform: translateY(-50%);
  }
}

.social-row--inline a {
  width: 36px;
  height: 36px;
  border: none;
  color: var(--text-faint);
}

.social-row--inline a svg {
  width: 19px;
  height: 19px;
}

.social-row--inline a:hover {
  color: var(--accent);
}

@media (max-width: 900px) {
  .social-row--inline {
    justify-content: center;
    margin-bottom: var(--space-2);
  }
}

.footer-bottom {
  border-top: 1px solid var(--border);
  padding-top: var(--space-4);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: 0.82rem;
  color: var(--text-faint);
}

.footer-bottom a {
  color: var(--text-faint);
}
.footer-bottom a:hover {
  color: var(--accent);
}

@media (max-width: 900px) {
  .footer-grid {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 560px) {
  .footer-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- Page hero (inner pages) ---------- */
.page-hero {
  position: relative;
  overflow: hidden;
  padding-block: var(--space-7) var(--space-6);
  border-bottom: 1px solid var(--border);
  background: linear-gradient(180deg, var(--bg-alt), var(--bg));
}

.page-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(560px 380px at 10% 0%, rgba(46, 110, 240, 0.16), transparent 65%),
    radial-gradient(480px 340px at 95% 100%, rgba(155, 163, 175, 0.12), transparent 65%);
  pointer-events: none;
}

.page-hero .container {
  position: relative;
  z-index: 1;
}

.breadcrumbs {
  font-size: 0.82rem;
  color: var(--text-faint);
  margin-bottom: var(--space-3);
}

.breadcrumbs a {
  color: var(--text-faint);
}
.breadcrumbs a:hover {
  color: var(--accent);
}

.page-hero h1 {
  font-size: clamp(2rem, 3.4vw, 2.8rem);
  max-width: 20ch;
}

.page-hero .lead {
  max-width: 60ch;
  font-size: 1.05rem;
}

/* ---------- Scroll reveal ----------
   One transition, several entry vectors. The long expo-out settle is what makes
   the motion read as deliberate instead of bouncy. --reveal-delay is set per
   element by JS so siblings cascade rather than all firing at once. */
/* Hidden states are scoped to .js so the page stays fully readable if the
   script never runs — content is visible by default and JS opts into hiding it. */
.js .reveal {
  opacity: 0;
  transform: translate3d(0, 28px, 0);
  transition:
    opacity var(--reveal-duration) var(--ease-out-expo),
    transform var(--reveal-duration) var(--ease-out-expo),
    filter var(--reveal-duration) var(--ease-out-expo);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

.js .reveal--left {
  transform: translate3d(-32px, 0, 0);
}

.js .reveal--right {
  transform: translate3d(32px, 0, 0);
}

.js .reveal--scale {
  transform: scale(0.94);
  filter: blur(6px);
}

.js .reveal--fade {
  transform: none;
}

.js .reveal.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
  filter: none;
  will-change: auto;
}

/* ---------- Starfield ----------
   Fixed behind everything, so it reads as depth the page floats over rather
   than as decoration that scrolls with the content. Sections with their own
   opaque background (hero, cards, footer) naturally mask it, which is what
   keeps the effect subtle instead of covering the whole site. */
.starfield {
  position: fixed;
  inset: 0;
  /* A canvas is a replaced element, so inset alone leaves it at its intrinsic
     300x150 — it needs explicit sizing to fill the viewport. */
  width: 100%;
  height: 100%;
  z-index: 0;
  display: block;
  pointer-events: none;
}

/* ---------- Scroll progress ---------- */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: var(--gradient-brand);
  z-index: 200;
  pointer-events: none;
}

/* ---------- Ambient light ----------
   Soft off-screen colour that bleeds into the section behind the content.
   Purely decorative, so it never intercepts pointer events. */
.ambient {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.ambient::before,
.ambient::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.5;
}

.ambient::before {
  width: 46vw;
  height: 46vw;
  max-width: 620px;
  max-height: 620px;
  top: -18%;
  left: -12%;
  background: radial-gradient(circle, rgba(46, 110, 240, 0.34), transparent 68%);
}

.ambient::after {
  width: 38vw;
  height: 38vw;
  max-width: 520px;
  max-height: 520px;
  bottom: -22%;
  right: -10%;
  background: radial-gradient(circle, rgba(155, 163, 175, 0.2), transparent 68%);
}

.ambient--single::after {
  display: none;
}

/* A standalone .section (unlike .glow-field) usually isn't tall enough for the
   46vw blurred circle above — the blur halo runs past the box before it fades,
   so overflow:hidden slices it into a hard-edged shape. Swap to the same
   technique .page-hero::before already uses successfully: the fade is baked
   into the gradient's own stops, so there's no halo left to clip. */
.ambient--single::before {
  inset: 0;
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  border-radius: 0;
  filter: none;
  opacity: 1;
  background: radial-gradient(620px 520px at 4% 8%, rgba(46, 110, 240, 0.22), transparent 62%);
}

/* Spans several sections so the glow reads as one continuous light source
   instead of stopping dead at a section boundary. */
.glow-field {
  position: relative;
  overflow: hidden;
}

.glow-field > .container,
.glow-field > section {
  position: relative;
  z-index: 1;
}

/* Two orbs drifting on different, deliberately mismatched cycles — the paths
   never quite repeat together, so the movement doesn't read as a loop. */
.ambient--drift::before {
  top: 8%;
  left: -14%;
  opacity: 0.55;
  animation: driftA 34s var(--ease-smooth) infinite alternate;
}

.ambient--drift::after {
  display: block;
  bottom: 6%;
  right: -12%;
  opacity: 0.4;
  animation: driftB 27s var(--ease-smooth) infinite alternate;
}

@keyframes driftA {
  0% { transform: translate3d(0, 0, 0) scale(1); }
  50% { transform: translate3d(46vw, 34%, 0) scale(1.18); }
  100% { transform: translate3d(18vw, 96%, 0) scale(0.94); }
}

@keyframes driftB {
  0% { transform: translate3d(0, 0, 0) scale(1.05); }
  50% { transform: translate3d(-38vw, -46%, 0) scale(0.9); }
  100% { transform: translate3d(-8vw, -92%, 0) scale(1.14); }
}

@media (max-width: 640px) {
  /* Large blurred orbs are expensive on phones; keep one, slower and softer */
  .ambient--drift::after {
    display: none;
  }
  .ambient--drift::before {
    animation-duration: 44s;
    opacity: 0.42;
  }
}

.section,
.section--tight,
.cta-band,
.page-hero {
  position: relative;
}

.section > .container,
.section--tight > .container,
.page-hero > .container {
  position: relative;
  z-index: 1;
}

/* ---------- Gradient divider ----------
   Replaces a flat 1px border: brightest in the middle, dissolving at the edges. */
.divider-glow {
  position: relative;
  height: 1px;
  border: 0;
  margin: 0;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(46, 110, 240, 0.45) 50%,
    transparent
  );
}

/* ---------- Lightbox ----------
   One shared overlay, injected once by initLightbox() and reused for every
   click. Uses opacity/visibility rather than display:none while closed, so
   the fade/scale transition can run; aria-hidden keeps it out of the a11y
   tree either way. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6) var(--space-4);
  background: rgba(10, 11, 13, 0.92);
  opacity: 0;
  visibility: hidden;
  transition: opacity 240ms var(--ease-smooth), visibility 0s linear 240ms;
}
.lightbox.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity 240ms var(--ease-smooth);
}

.lightbox__img {
  max-width: min(92vw, 1400px);
  max-height: min(88vh, 88svh);
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--radius);
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.7);
  background: var(--bg-alt);
  transform: scale(0.96);
  transition: transform 260ms var(--ease-out-expo);
}
.lightbox.is-open .lightbox__img {
  transform: scale(1);
}

.lightbox__close {
  position: fixed;
  top: var(--space-3);
  right: var(--space-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: var(--bg-elevated);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  color: var(--text);
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition), transform var(--transition);
}
.lightbox__close:hover {
  background: var(--bg-elevated-2);
  border-color: var(--accent);
  color: var(--accent-hover);
}
.lightbox__close svg {
  width: 20px;
  height: 20px;
}

/* Lightbox-openable images keep the default system cursor rather than a
   zoom affordance — click/keyboard behavior is unchanged, only the hover
   cursor is suppressed. */
main img[data-lightbox] {
  cursor: default;
}

@media (max-width: 620px) {
  .lightbox__close {
    top: var(--space-2);
    right: var(--space-2);
    width: 40px;
    height: 40px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .lightbox,
  .lightbox__img,
  .lightbox__close {
    transition: none;
  }
}

/* ---------- Utility ---------- */
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.flex { display: flex; }
.items-center { align-items: center; }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
