/* ===== Design tokens ===== */
:root {
  --bg: #0b0f1a;
  --bg-alt: #0f1424;
  --bg-card: #141a2e;
  --surface: #ffffff;
  --text: #e8ecf6;
  --text-dim: #9aa6c0;
  --text-ink: #1a2238;
  --accent: #245baa;
  --border: rgba(255, 255, 255, 0.08);
  --radius: 16px;
  --radius-sm: 10px;
  --max: 1140px;
  --shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
}

/* ===== Reset ===== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: "Inter", system-ui, -apple-system, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
.container { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 24px; }

h1, h2, h3, .brand-text { font-family: "Sora", sans-serif; letter-spacing: -0.02em; }

/* ===== Header ===== */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  background: rgba(11, 15, 26, 0.85);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}
.header-inner { display: flex; align-items: center; justify-content: space-between; height: 72px; }
.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 1.15rem; }
.brand-logo { height: 52px; width: auto; display: block; }
.brand-mark {
  display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 9px;
  background: var(--accent);
  font-family: "Sora", sans-serif; font-weight: 800; color: #fff;
}
.brand-suffix { color: var(--text-dim); font-weight: 500; }
.nav { display: flex; align-items: center; gap: 30px; }
.nav a { color: var(--text-dim); font-size: .95rem; font-weight: 500; transition: color .2s; }
.nav a:hover { color: var(--text); }
.nav-cta {
  padding: 9px 18px; border-radius: 999px;
  background: var(--accent);
  color: #fff !important; font-weight: 600;
}
.nav-cta:hover { opacity: .9; }
.nav-toggle { display: none; flex-direction: column; gap: 5px; background: none; border: 0; cursor: pointer; padding: 6px; }
.nav-toggle span { width: 24px; height: 2px; background: var(--text); border-radius: 2px; transition: .3s; }

/* ===== Hero ===== */
.hero { position: relative; height: 180vh; }
.hero-sticky {
  position: sticky; top: 0; height: 100vh;
  display: flex; align-items: center; overflow: hidden;
}
.hero-glow {
  position: absolute; top: -200px; left: 50%; transform: translateX(-50%);
  width: 900px; height: 700px; pointer-events: none;
  background: radial-gradient(circle at center, rgba(36,91,170,.28), rgba(36,91,170,.12) 40%, transparent 70%);
  filter: blur(20px);
}
/* Waveline + inline headline on one row, flush to the left edge */
.hero-line {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; gap: 22px; white-space: nowrap;
  will-change: transform;
}
.hero-wave { display: inline-block; flex: none; width: clamp(340px, 42vw, 720px); height: 250px; }
.wave {
  display: block; width: 100%; height: 100%;
  fill: none; stroke: var(--accent); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
  filter: drop-shadow(0 0 2.5px rgba(150,200,225,.3));
}
/* non-scaling-stroke keeps strokes uniform/crisp despite the non-uniform viewBox stretch.
   No will-change here: promoting each path to a raster layer made the lines pixelated. */
.wave-strands path { vector-effect: non-scaling-stroke; }
/* Divider wire — the hero bundle mirrored (scaleX) so the big lobe sits left and the small end
   tucks into the right edge, scaled down, filling the dark band between the hero and Build. */
.wire-divider { display: flex; justify-content: flex-end; width: 100%; padding: 24px 0; pointer-events: none; }
.wave-2 { flex: none; width: clamp(240px, 32vw, 520px); height: 160px; transform: scaleX(-1); }
.wave-strands-2 path { vector-effect: non-scaling-stroke; }
/* Headline letters — hidden until scroll types them in left → right */
.ch { display: inline-block; opacity: 0; will-change: opacity; }
/* With JS on, keep the headline hidden until script.js has split it into .ch spans, so the full line
   never flashes at load. The letters re-show here (opacity still drives the scroll reveal). No-JS
   visitors skip this and see the plain, fully-visible headline. */
.js .hero-title { visibility: hidden; }
.js .hero-title .ch { visibility: visible; }
.hero-title { font-size: clamp(1.9rem, 3.6vw, 3.2rem); font-weight: 800; line-height: 1.1; white-space: nowrap; }
.grad {
  color: var(--accent);
}
.hero-sub { margin: 26px auto 0; max-width: 640px; font-size: 1.12rem; color: var(--text-dim); }
.hero-actions { display: flex; gap: 14px; justify-content: center; margin-top: 38px; flex-wrap: wrap; }

/* ===== Buttons ===== */
.btn {
  display: inline-block; padding: 13px 26px; border-radius: 999px;
  font-weight: 600; font-size: .98rem; cursor: pointer; border: 1px solid transparent;
  transition: transform .15s ease, opacity .2s ease, background .2s ease;
}
.btn:hover { transform: translateY(-2px); }
.btn-primary { background: var(--accent); color: #fff; box-shadow: 0 10px 30px rgba(36,91,170,.35); }
.btn-block { width: 100%; text-align: center; }

/* ===== Sections ===== */
.section { padding: 100px 0; }
.section-title { font-size: clamp(1.7rem, 4vw, 2.6rem); font-weight: 700; line-height: 1.15; }
.section-title.center { text-align: center; }

.grid-2 { display: grid; grid-template-columns: 1fr 1.2fr; gap: 50px; align-items: center; }
.grid-2.flip { grid-template-columns: 1.2fr 1fr; }   /* text (left) wider, title to the right */
.grid-2.flip .about-head { order: 2; }                /* title → right column */
.grid-2.flip .about-body { order: 1; }                /* text  → left column  */
.grid-2.flip .about-head, .grid-2.flip .about-body { text-align: right; } /* reveals from the right */
.about-body p { color: var(--text-dim); font-size: 1.08rem; }
.about-body p + p { margin-top: 18px; }

/* ===== Approach: cards stacked on the left, title on the right ===== */
.approach-inner { display: grid; grid-template-columns: 1.25fr 1fr; gap: 56px; align-items: center; }
.approach-inner .cards { order: 1; }            /* cards in the left column */
.approach-head { order: 2; }                     /* title in the right column */
.approach-head .section-title { text-align: left; white-space: nowrap; }   /* one line, left aligned */
.approach-copy { margin-top: 18px; color: var(--text-dim); line-height: 1.6; }
/* Cards as real jigsaw pieces: a SQUARE with a knob/blank on every edge. The per-piece outline
   (which edge is flat / knob / blank) is generated in script.js — vertical edges stay complementary
   (bottom knob ↔ top blank) so stacked pieces interlock; left/right edges vary per piece.
   Fixed 340x340 box because clip-path: path() uses absolute coordinates. */
.cards { display: flex; flex-direction: column; align-items: flex-start; --card-size: 340px; }
.card {
  width: var(--card-size); height: var(--card-size); box-sizing: border-box;
  /* deepest logo blue with a soft top-left sheen so the piece reads three-dimensional */
  background:
    radial-gradient(130% 90% at 28% 8%, rgba(255,255,255,.14), rgba(255,255,255,0) 55%),
    linear-gradient(155deg, #224f8d 0%, #1b4077 55%, #15335f 100%);
  padding: calc(var(--card-size) * 0.247);  /* keep text clear of the knob/blank zones on all edges (scales with the piece) */
  display: flex; flex-direction: column; justify-content: center;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.16), inset 0 -18px 30px rgba(0,0,0,.28);  /* bevel + depth */
  filter: drop-shadow(0 6px 14px rgba(0,0,0,.4));   /* shadow outlines the jigsaw silhouette */
  transition: transform .25s ease, filter .25s ease, background .25s ease;
}
.card + .card { margin-top: calc(var(--card-size) * -0.2); }   /* ~20px gap — knob approaches blank, almost touching (scales with the piece) */
.card h3 { font-size: clamp(1.1rem, calc(var(--card-size) * 0.0706), 1.5rem); text-align: center; margin: 0; color: var(--text); letter-spacing: .01em;
  text-shadow: 0 1px 2px rgba(0,0,0,.35); }
.card:hover {
  background:
    radial-gradient(130% 90% at 28% 8%, rgba(255,255,255,.2), rgba(255,255,255,0) 55%),
    linear-gradient(155deg, #2a5da6 0%, #214c8a 55%, #193c6e 100%);
  filter: drop-shadow(0 10px 22px rgba(27,64,119,.55));
  transform: translateX(6px);
}

/* ===== Contact ===== */
.contact-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
.contact-copy .section-title { line-height: 1.5; }   /* more space between the three heading rows */
.contact-copy p { color: var(--text-dim); margin-top: 14px; }

.contact-form {
  position: relative;
  /* frosted blue glass panel */
  background: linear-gradient(160deg, rgba(36,91,170,.25), rgba(27,64,119,.15));
  border: 1px solid rgba(46,123,232,.3);
  border-radius: var(--radius); padding: 34px; display: grid; gap: 18px;
  box-shadow: 0 24px 60px rgba(0,0,0,.45);
  backdrop-filter: blur(8px);
}
.field { display: grid; gap: 7px; }
.field label { font-size: .85rem; font-weight: 600; letter-spacing: .02em; color: var(--text-dim); }
.field input, .field textarea {
  width: 100%; padding: 13px 15px; border-radius: var(--radius-sm);
  background: rgba(11,15,26,.55); border: 1px solid rgba(46,123,232,.3);   /* translucent dark fields */
  color: var(--text); font: inherit; font-size: .98rem; resize: vertical;
  transition: border-color .2s, background .2s, box-shadow .2s;
}
.field input:focus, .field textarea:focus {
  outline: none; border-color: #2e7be8;
  background: rgba(11,15,26,.75); box-shadow: 0 0 0 3px rgba(46,123,232,.2);
}
.contact-form .btn-primary { background: var(--accent); color: #fff; box-shadow: 0 10px 30px rgba(36,91,170,.35); }   /* same blue as the top-menu Contact button */
.contact-form .btn-primary:hover { background: #2a69c0; }
.form-note { font-size: .9rem; min-height: 1.2em; }
.form-note.ok { color: #5be29a; }
.form-note.err { color: #ff7a7a; }

/* ===== Footer ===== */
.site-footer { border-top: 1px solid var(--border); background: var(--bg); padding: 44px 0; }
.footer-inner { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.footer-brand { display: flex; align-items: center; gap: 10px; font-family: "Sora", sans-serif; font-weight: 600; }
.footer-logo { height: 58px; width: auto; display: block; margin-left: -10px; } /* offset the logo's built-in left padding so it sits flush with the copyright */
.footer-copy { color: var(--text-dim); font-size: .85rem; width: 100%; margin-top: 8px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.footer-address { color: var(--text-dim); font-size: .82rem; max-width: 340px; text-align: right; }
.footer-social { display: flex; align-items: center; gap: 16px; }
.footer-social a { color: var(--text-dim); display: inline-flex; transition: color .2s; }
.footer-social a:hover { color: var(--text); }
.footer-social svg { width: 18px; height: 18px; fill: currentColor; display: block; }

/* ===== Reveal animation — directional wipe, reversible on scroll up/down. Direction alternates
   per section (set in JS): left→right, then right→left, and so on, echoing the hero's draw. ===== */
[data-reveal] {
  opacity: 0;
  transition: opacity .7s ease, transform .7s ease;
  will-change: opacity, transform;
}
[data-reveal].rv-lr { transform: translateX(-56px); } /* slides in from the left  → left→right */
[data-reveal].rv-rl { transform: translateX(56px);  } /* slides in from the right → right→left */
[data-reveal].in    { opacity: 1; transform: none; }

/* ===== Responsive ===== */
@media (max-width: 900px) {
  /* .grid-2.flip is listed explicitly: it outspecifies a bare .grid-2 rule, so without it the
     Build section would keep its desktop two-column layout here and stay cramped. */
  .grid-2, .grid-2.flip, .contact-inner, .approach-inner { grid-template-columns: 1fr; gap: 30px; }
  .cards { align-items: center; }   /* centre the puzzle stack when it's the full width */
  .approach-head { order: 0; }   /* title back on top when stacked */
  .approach-head .section-title { white-space: normal; }   /* allow wrap when stacked */
  .grid-2.flip .about-head, .grid-2.flip .about-body { order: 0; }   /* title back on top when stacked */
  /* Build keeps its desktop right-alignment (heading + body) when stacked, mirroring the PC look
     and matching its right→left reveal. */

  /* Hero: the desktop horizontal "type-in" line is far wider than a phone/tablet, so it slides
     mostly off-screen. Stack it instead — wave on top, headline wrapping and centred below. The
     scroll-driven draw-in + letter fade still play; the horizontal camera-follow is switched off
     in script.js at this same breakpoint. */
  .hero { height: 160vh; }
  .hero-sticky { justify-content: center; }
  .hero-line {
    flex-direction: column; align-items: center; gap: 18px;
    white-space: normal; width: 100%; padding: 0 24px; text-align: center;
  }
  .hero-wave { width: min(340px, 80vw); height: 150px; }
  .hero-title { white-space: normal; text-align: center; font-size: clamp(1.7rem, 6.4vw, 2.6rem); }
  /* Letters are inline-block on desktop (atomic boxes), which lets the wrapping headline break
     mid-word here. Make them plain inline so words stay intact and breaks happen only at spaces;
     the opacity reveal is unaffected. */
  .hero-title .ch { display: inline; }
  /* centre the bridging wire under the now-centred hero (it's flush-right on desktop) */
  .wire-divider { justify-content: center; padding: 8px 24px; }
  .wave-2 { width: min(300px, 70vw); }

  /* Stacked content is full container width, so the desktop 56px reveal slide would push it past the
     viewport edge (a sliver of horizontal scroll). Shrink it under the 24px gutter; .in is re-stated
     last so revealed items still settle to transform:none. */
  [data-reveal].rv-lr { transform: translateX(-20px); }
  [data-reveal].rv-rl { transform: translateX(20px); }
  [data-reveal].in    { transform: none; }
}
@media (max-width: 720px) {
  .nav {
    position: fixed; inset: 72px 0 auto 0;
    flex-direction: column; gap: 0; padding: 12px 24px 24px;
    background: rgba(11,15,26,.97); backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--border);
    transform: translateY(-120%); transition: transform .3s ease; visibility: hidden;
  }
  .nav.open { transform: none; visibility: visible; }
  .nav a { width: 100%; padding: 14px 0; border-bottom: 1px solid var(--border); }
  .nav-cta { text-align: center; margin-top: 10px; border-bottom: 0 !important; }
  .nav-toggle { display: flex; }
  .nav-toggle.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-toggle.open span:nth-child(2) { opacity: 0; }
  .nav-toggle.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
  .section { padding: 70px 0; }
  /* Shrink the puzzle pieces so they never overflow narrow phones (fixed 340px clips < ~388px).
     script.js rebuilds each clip-path from the live size, so the jigsaw stays intact. */
  .cards { --card-size: min(340px, calc(100vw - 72px)); }
  /* Stack the footer centred instead of the desktop space-between row. */
  .footer-inner { justify-content: center; text-align: center; }
  .footer-address { text-align: center; max-width: none; }
  .footer-copy { flex-direction: column; gap: 12px; justify-content: center; text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
  .hero { height: auto; }
  .hero-sticky { position: relative; height: auto; padding: 150px 0 90px; }
  .ch { opacity: 1 !important; transform: none !important; }
  [data-reveal] { opacity: 1 !important; transform: none !important; transition: none; }
}
