/* ==========================================================================
   KARAR landing page for karar.app
   Design tokens are lifted verbatim from the app's mobile/tailwind.config.js
   so the site and the product stay in sync.
   ========================================================================== */

@font-face {
  font-family: 'Arimo';
  src: url('fonts/arimo.woff2') format('woff2');
  font-weight: 400 700;          /* variable */
  font-display: swap;
  font-style: normal;
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  src: url('fonts/pjs.woff2') format('woff2');
  font-weight: 200 800;          /* variable */
  font-display: swap;
  font-style: normal;
}

:root {
  /* --- app design system ------------------------------------------------ */
  --primary: #FF651C;
  --secondary: #FBCDB7;
  --app-light: #FAFAFA;
  --app-dark: #191919;
  --app-dark-2: #292929;
  --neutral: #8E8E93;
  --light-neutral: #D3D4D7;

  /* --- semantic, light theme ------------------------------------------- */
  --bg: var(--app-light);
  --bg-elevated: #FFFFFF;
  --surface: #FFFFFF;
  --surface-2: #F4F4F5;
  --text: var(--app-dark);
  --text-muted: #62626A;
  --text-faint: #6B6B72;          /* app --neutral is 3.0:1 on light; this is 4.9:1 */
  --border: var(--light-neutral);
  --border-soft: rgba(25, 25, 25, .08);
  --shadow: 0 1px 2px rgba(25,25,25,.04), 0 12px 32px -12px rgba(25,25,25,.14);
  --shadow-lg: 0 2px 4px rgba(25,25,25,.04), 0 32px 64px -24px rgba(25,25,25,.22);
  --glow-1: rgba(255, 101, 28, .20);
  --glow-2: rgba(251, 205, 183, .55);
  --header-bg: rgba(250, 250, 250, .72);

  /* --- scale ------------------------------------------------------------ */
  --radius: 16px;
  --radius-lg: 24px;
  --radius-xl: 32px;
  --maxw: 1180px;
  --pad: clamp(20px, 5vw, 40px);
  --font-ui: 'Arimo', system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;
  --font-display: 'Plus Jakarta Sans', var(--font-ui);
  --ease: cubic-bezier(.22, 1, .36, 1);
  color-scheme: light;
}

:root[data-theme='dark'] {
  --bg: var(--app-dark);
  --bg-elevated: var(--app-dark-2);
  --surface: var(--app-dark-2);
  --surface-2: #333336;
  --text: var(--app-light);
  --text-muted: #B4B4BA;
  --text-faint: #9E9EA6;          /* 6.4:1 on #191919 */
  --border: rgba(255, 255, 255, .14);
  --border-soft: rgba(255, 255, 255, .08);
  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 12px 32px -12px rgba(0,0,0,.6);
  --shadow-lg: 0 2px 4px rgba(0,0,0,.4), 0 32px 64px -24px rgba(0,0,0,.75);
  --glow-1: rgba(255, 101, 28, .26);
  --glow-2: rgba(255, 101, 28, .10);
  --header-bg: rgba(25, 25, 25, .72);
  color-scheme: dark;
}

/* ==========================================================================
   base
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html {
  scroll-behavior: smooth; -webkit-text-size-adjust: 100%;
  /* clip, not hidden: hidden would make <html> a scroll container and break the
     sticky header. Guards against any stray horizontal overflow widening the
     layout viewport on mobile. */
  overflow-x: clip;
}
body {
  margin: 0;
  font-family: var(--font-ui);
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* clip, not hidden. `hidden` makes body a scroll container, which
     anchors position:sticky to a box that never scrolls -- the sticky
     header silently scrolled away with the page. `clip` contains stray
     horizontal overflow without that side effect. */
  overflow-x: clip;
  transition: background-color .35s var(--ease), color .35s var(--ease);
}
img, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3 { font-family: var(--font-display); font-weight: 800; line-height: 1.1; letter-spacing: -.02em; margin: 0; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
:focus-visible { outline: 3px solid var(--primary); outline-offset: 3px; border-radius: 6px; }

.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--pad); }
.section { padding-block: clamp(72px, 11vw, 132px); position: relative; }
.center { text-align: center; }


.section-head { max-width: 660px; margin-inline: auto; margin-bottom: clamp(40px, 6vw, 68px); }
.section-head h2 { font-size: clamp(1.9rem, 4.4vw, 3rem); }
.section-head p { color: var(--text-muted); font-size: clamp(1rem, 1.6vw, 1.12rem); margin-top: 16px; }

/* ==========================================================================
   buttons
   ========================================================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-ui); font-weight: 700; font-size: .94rem;
  /* body sets line-height 1.6, which added ~9px of dead height inside a pill */
  line-height: 1.2;
  padding: 12px 24px; border-radius: 999px; border: 1px solid transparent;
  cursor: pointer; white-space: nowrap;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease),
              background-color .22s var(--ease), border-color .22s var(--ease);
}
.btn-primary {
  background: var(--primary); color: #fff;
  box-shadow: 0 8px 22px -8px rgba(255,101,28,.7);
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 16px 34px -10px rgba(255,101,28,.8); }
.btn-ghost { background: transparent; color: var(--text); border-color: var(--border); }
.btn-ghost:hover { transform: translateY(-2px); border-color: var(--primary); color: var(--primary); }
.btn:active { transform: translateY(0); }

/* ==========================================================================
   header
   ========================================================================== */
.header {
  position: sticky; top: 0; z-index: 60;
  background: transparent;
  transition: background-color .3s var(--ease), border-color .3s var(--ease), backdrop-filter .3s;
  border-bottom: 1px solid transparent;
}
.header.is-stuck {
  background: var(--header-bg);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom-color: var(--border-soft);
}
.header-inner { display: flex; align-items: center; gap: 20px; height: 74px; }
.brand { display: flex; align-items: center; gap: 11px; font-family: var(--font-display); font-weight: 800; font-size: 1.16rem; letter-spacing: .01em; }
.brand img { width: 34px; height: 34px; border-radius: 9px; }
.nav { display: flex; gap: 6px; margin-left: auto; }
.nav a {
  padding: 9px 14px; border-radius: 999px; font-size: .93rem; font-weight: 500;
  color: var(--text-muted); transition: color .2s, background-color .2s;
}
.nav a:hover { color: var(--text); background: var(--surface-2); }
.header-actions { display: flex; align-items: center; gap: 10px; }

.theme-toggle {
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border); color: var(--text);
  transition: transform .25s var(--ease), border-color .2s, background-color .2s;
}
.theme-toggle:hover { transform: rotate(-18deg) scale(1.06); border-color: var(--primary); color: var(--primary); }
.theme-toggle svg { width: 19px; height: 19px; }
.theme-toggle .i-moon { display: none; }
:root[data-theme='dark'] .theme-toggle .i-sun { display: none; }
:root[data-theme='dark'] .theme-toggle .i-moon { display: block; }

/* ==========================================================================
   hero
   ========================================================================== */
.hero { position: relative; padding-top: clamp(48px, 8vw, 84px); padding-bottom: clamp(64px, 9vw, 110px); overflow: hidden; }
.hero-grid { display: grid; grid-template-columns: 1.12fr .88fr; gap: clamp(32px, 5vw, 68px); align-items: center; }
.hero h1 { font-size: clamp(2.2rem, 5vw, 3.45rem); text-wrap: initial; }
.hero h1 .accent { color: var(--primary); }
.hero-sub { color: var(--text-muted); font-size: clamp(1.04rem, 1.9vw, 1.24rem); margin-top: 22px; max-width: 30em; }
.hero-cta { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 34px; }
.hero-note { display: flex; align-items: center; gap: 9px; margin-top: 22px; color: var(--text-faint); font-size: .88rem; }

/* Hero backdrop: concentric rings radiating from behind the phone, like a
   location ping settling on a spot. It echoes the KARAR ring mark and the
   technologies orbit, and says the thing the product actually does — a group
   converging on one place. Replaces the two corner glows. */
.hero-rings {
  position: absolute; inset: 0; z-index: -1;
  overflow: hidden; pointer-events: none;
  --cx: 72%; --cy: 50%;              /* sits behind the phone */
}
.hero-rings::before {
  content: '';
  position: absolute; left: var(--cx); top: var(--cy);
  width: min(150vw, 1500px); aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: repeating-radial-gradient(circle at center,
    color-mix(in srgb, var(--primary) 17%, transparent) 0 1px,
    transparent 1px 62px);
  /* fade the rings out before they reach the text, so nothing competes */
  -webkit-mask-image: radial-gradient(circle at center, #000 4%, rgba(0,0,0,.55) 32%, transparent 64%);
          mask-image: radial-gradient(circle at center, #000 4%, rgba(0,0,0,.55) 32%, transparent 64%);
}
:root[data-theme='dark'] .hero-rings::before { opacity: .85; }

.hero-rings .ping {
  position: absolute; left: var(--cx); top: var(--cy);
  width: min(46vw, 300px); aspect-ratio: 1; border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--primary) 45%, transparent);
  transform: translate(-50%, -50%) scale(.35);
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .hero-rings .ping { animation: ping 9s cubic-bezier(.2, .6, .3, 1) infinite; }
  .hero-rings .ping:nth-child(2) { animation-delay: -3s; }
  .hero-rings .ping:nth-child(3) { animation-delay: -6s; }
}
@keyframes ping {
  0%   { transform: translate(-50%, -50%) scale(.35); opacity: 0; }
  14%  { opacity: .5; }
  100% { transform: translate(-50%, -50%) scale(3.4); opacity: 0; }
}

/* drifting brand glows */
.blob { position: absolute; border-radius: 50%; filter: blur(72px); pointer-events: none; z-index: -1; }
.blob-1 { width: 480px; height: 480px; background: var(--glow-1); top: -140px; right: -110px; animation: drift1 22s ease-in-out infinite; }
.blob-2 { width: 400px; height: 400px; background: var(--glow-2); bottom: -170px; left: -130px; animation: drift2 26s ease-in-out infinite; }
@keyframes drift1 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(-46px, 40px) scale(1.12); } }
@keyframes drift2 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(52px, -34px) scale(1.09); } }

/* phone mockup: the screen swaps with the theme, because the app has both */
/* The chips are positioned in % of this box, so it is pinned to the phone's own
   width rather than to the full grid column. That keeps the gap between a chip
   and the phone constant instead of varying with the column. */
.phone-stage { position: relative; display: grid; place-items: center;
  --phone-w: 300px;
  width: min(100%, var(--phone-w)); margin-inline: auto; }
.phone {
  position: relative; width: 100%;
  border-radius: 46px; background: var(--app-dark);
  padding: 10px; box-shadow: var(--shadow-lg);
}
.phone::after {                       /* dynamic island */
  content: ''; position: absolute; top: 2.8%; left: 50%; transform: translateX(-50%);
  width: 27%; height: 3%; border-radius: 999px; background: var(--app-dark);
}
/* aspect lives on the screen, not the shell, so the shot is never cropped */
.phone-screen { position: relative; width: 100%; aspect-ratio: 440 / 956; border-radius: 37px; overflow: hidden; background: #fff; }
.phone-screen img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.phone-screen .shot-dark { display: none; }
:root[data-theme='dark'] .phone-screen .shot-light { display: none; }
:root[data-theme='dark'] .phone-screen .shot-dark { display: block; }
/* on a dark page the shell is the same value as the background, so give the
   device a hairline to keep its silhouette readable */
:root[data-theme='dark'] .phone {
  background: #23232590;
  box-shadow: var(--shadow-lg), 0 0 0 1.5px rgba(255, 255, 255, .12);
}
/* The phone and its three chips share ONE period, so they stay phase-locked
   instead of drifting against each other. The offsets are small even fractions
   of that period, which makes the motion read as a single slow breath moving
   through the group rather than four unrelated bobs. */
.phone-stage { --float-period: 8s; }
.phone-stage .phone {
  animation: float-y var(--float-period) ease-in-out infinite;
  --amp: -20px;
}
.chip {
  animation: float-y var(--float-period) ease-in-out infinite;
  will-change: transform;
}
@keyframes float-y {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(var(--amp, -14px)); }
}

/* floating chips around the phone */
.chip {
  position: absolute; display: flex; align-items: center; gap: 8px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px; padding: 10px 15px; font-size: .84rem; font-weight: 700;
  box-shadow: var(--shadow); white-space: nowrap;
}
.chip svg { width: 15px; height: 15px; color: var(--primary); }
.chip-1 { top: 13%; left: -38%; --amp: -12px; animation-delay: calc(var(--float-period) * -0.08); }
.chip-2 { top: 45%; right: -42%; --amp: -15px; animation-delay: calc(var(--float-period) * -0.16); }
.chip-3 { bottom: 12%; left: -30%; --amp: -11px; animation-delay: calc(var(--float-period) * -0.24); }

/* ==========================================================================
   stats
   ========================================================================== */
.stats { border-block: 1px solid var(--border-soft); background: var(--bg-elevated); }
.stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; padding-block: 46px; }
.stat { text-align: center; }
.stat-num { font-family: var(--font-display); font-weight: 800; font-size: clamp(1.9rem, 3.6vw, 2.7rem); color: var(--primary); line-height: 1; }
.stat-label { color: var(--text-muted); font-size: .9rem; margin-top: 9px; }

/* ==========================================================================
   feature rows (onboarding illustrations)
   ========================================================================== */
.frow { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 6vw, 84px); align-items: center; }
.frow + .frow { margin-top: clamp(64px, 9vw, 112px); }
.frow:nth-child(even) .frow-media { order: -1; }
.frow h3 { font-size: clamp(1.5rem, 3vw, 2.1rem); margin-top: 14px; }
.frow p { color: var(--text-muted); margin-top: 22px; font-size: 1.04rem; }

/* No card: the device sits directly on the page. */
.frow-media { display: grid; place-items: center; position: relative; }
.frow-device { position: relative; width: min(100%, 268px); }

/* Just the numeral, no chip around it. */
.frow-num {
  display: inline-block; color: var(--primary);
  font-family: var(--font-display); font-weight: 800; font-size: 1.02rem;
  letter-spacing: .06em;
}

/* ==========================================================================
   TiltedCard, ported from the React Bits component (React + motion/react).
   This site is static and dependency-free, so the port keeps the original
   class names, prop semantics and spring constants (stiffness 100, damping 30,
   mass 2; caption 350/30/1) and reproduces useSpring with a small integrator
   in app.js. Behaviour matches; there is no React on the page.
   ========================================================================== */
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 26px;
}

.tilted-card-figure {
  position: relative;
  width: 100%;
  height: 100%;
  perspective: 800px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 0;
}

.tilted-card-inner {
  position: relative;
  transform-style: preserve-3d;
  will-change: transform;
}

.tilted-card-img {
  position: absolute;
  top: 0;
  left: 0;
  object-fit: cover;
  border-radius: 15px;
  will-change: transform;
  transform: translateZ(0);
  box-shadow: var(--shadow);
}

.tilted-card-overlay {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  will-change: transform;
  transform: translateZ(30px);
  width: 100%;
  height: 100%;
  padding: 30px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  gap: 10px;
  box-sizing: border-box;
  color: #FFFFFF;
  pointer-events: none;
}
.tilted-card-overlay .card-icon {
  width: 46px; height: 46px; border-radius: 13px;
  display: grid; place-items: center; margin: 0 0 auto;
  /* solid, not translucent: the chip sits over the bright part of the
     screenshot, where a washed-out fill leaves the white glyph invisible */
  background: var(--primary);
  border: 1px solid rgba(255, 255, 255, .28);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .32);
  color: #FFFFFF;
}
.tilted-card-overlay .card-icon svg { width: 23px; height: 23px; }
.tilted-card-overlay h3 {
  font-size: 1.12rem; font-weight: 700; color: #FFFFFF; text-wrap: balance;
}
.tilted-card-overlay p {
  font-size: .93rem; line-height: 1.5; color: rgba(255, 255, 255, .80); margin: 0;
}



/* ==========================================================================
   steps, using Plagorium's Process layout: a connector line running through
   numbered badges, horizontal on desktop and vertical on mobile
   ========================================================================== */
.process { position: relative; margin-top: clamp(48px, 6vw, 64px); }
.process-line {
  position: absolute; left: 10%; right: 10%; top: 28px; height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--primary) 40%, transparent), transparent);
  display: none;
}
.process-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: 1fr; gap: 40px;
}
.step {
  position: relative; display: flex; align-items: flex-start; gap: 20px;
}
.step-connector {
  position: absolute; left: 28px; top: 56px; width: 1px; height: calc(100% - 1rem);
  transform: translateX(-50%);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--primary) 45%, transparent),
    color-mix(in srgb, var(--primary) 15%, transparent));
}
.step-glow {
  pointer-events: none; position: absolute; left: 28px; top: 28px;
  width: 64px; height: 64px; transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--primary) 55%, transparent), transparent 70%);
  opacity: 0; filter: blur(18px); transition: opacity .3s var(--ease);
}
.step:hover .step-glow { opacity: 1; }
.step-badge {
  position: relative; z-index: 1;
  display: grid; place-items: center;
  width: 56px; height: 56px; flex: none; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--primary) 40%, transparent);
  background: var(--bg);
  font-family: var(--font-display); font-weight: 800; font-size: 1.06rem;
  color: var(--primary);
  transition: background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.step:hover .step-badge { background: var(--primary); border-color: var(--primary); color: #fff; }
.step h3 { font-size: 1.06rem; font-weight: 700; }
.step p { color: var(--text-muted); font-size: .95rem; margin-top: 7px; }

@media (min-width: 981px) {
  .process-line { display: block; }
  .process-list { grid-template-columns: repeat(4, 1fr); gap: 26px; }
  .step { flex-direction: column; align-items: center; text-align: center; gap: 0; }
  .step-connector { display: none; }
  .step-glow { left: 50%; }
  .step-body { margin-top: 20px; }
  .step p { margin-inline: auto; max-width: 15rem; }
}

/* ==========================================================================
   technologies, using Plagorium's "Track record" orbit: two counter-rotating rings
   of logo tiles around the KARAR mark. Radii and tile sizes are in cqw (% of
   the stage width) so the whole orbit scales fluidly instead of breaking at
   a breakpoint.
   ========================================================================== */
.orbit-stage {
  position: relative;
  aspect-ratio: 1;
  width: 100%;
  max-width: 560px;
  margin-inline: auto;
  container-type: inline-size;
  /* Each tile counter-rotates about its own centre, so its corners sweep out to
     half its DIAGONAL, not half its width. That poked past the stage and the
     overflow propagated to the document, which is what widened the layout
     viewport on mobile. `clip` contains it without creating a scroll container,
     so it cannot break the sticky header. */
  overflow: clip;
}
.orbit-guide {
  position: absolute; border-radius: 50%;
  border: 1px solid var(--border-soft);
}
.orbit-guide-outer { inset: 6%; }
.orbit-guide-inner { inset: 28%; }

.orbit-ring { position: absolute; inset: 0; }
.orbit-slot {
  position: absolute; left: 50%; top: 50%; transform-origin: top left;
  transform: rotate(var(--a)) translateY(calc(var(--r) * -1)) rotate(calc(-1 * var(--a)));
}
.orbit-counter { transform-origin: top left; }
.orbit-tile {
  transform: translate(-50%, -50%);
  width: var(--t); height: var(--t);
  border-radius: 16px; overflow: hidden;
  border: 1px solid var(--border);
  background: #fff;
  box-shadow: var(--shadow);
}
.orbit-tile img[src$="ts.png"],
.orbit-tile img[src$="nativewind.png"] { padding: 20%; }
.orbit-tile img {
  width: 100%; height: 100%; object-fit: contain; padding: 11%;
  box-sizing: border-box;
  /* Plagorium mutes its logos at rest (opacity .8 + grayscale .35) because that
     orbit is an understated wall of CLIENT logos. These are technology marks on
     white plates, where the same treatment just looks washed out, so they run
     at full strength and the hover cue is a lift instead of a colour change. */
  transition: transform .3s var(--ease);
}
.orbit-tile {
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease), transform .3s var(--ease);
}
/* purely decorative: nothing here is clickable, so no hover state */

.orbit-hub {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 21cqw; height: 21cqw; border-radius: 50%;
  display: grid; place-items: center;
  border: 1px solid var(--border);
  background: var(--surface);
}
.orbit-hub img { width: 56%; height: 56%; object-fit: contain; }

.orbit-caption {
  margin: clamp(36px, 5vw, 52px) auto 0; max-width: 44rem;
  text-align: center; color: var(--text-muted); font-size: .98rem;
}

@keyframes orbit   { to { transform: rotate(360deg); } }
@keyframes orbit-r { to { transform: rotate(-360deg); } }

/* Each ring's counter-spin uses the SAME duration in the opposite direction,
   which is what keeps every logo upright while the ring turns. */
@media (prefers-reduced-motion: no-preference) {
  .orbit-ring-outer                { animation: orbit   104s linear infinite; }
  .orbit-ring-outer .orbit-counter { animation: orbit-r 104s linear infinite; }
  .orbit-ring-inner                { animation: orbit-r  62s linear infinite; }
  .orbit-ring-inner .orbit-counter { animation: orbit    62s linear infinite; }
}

/* ==========================================================================
   team
   ========================================================================== */
.team-title { font-size: clamp(1.9rem, 4.4vw, 3rem); line-height: 1.06; }
/* three stacked lines: Meet the / KARAR / Team */
.team-title .tt-a,
.team-title .karar-word,
.team-title .tt-b { display: block; }
.karar-word {
  color: var(--primary);
  /* h1-h3 set -.02em; the navbar brand uses +.01em. Same face and weight
     already, so matching the tracking is what makes this read as the logo. */
  letter-spacing: .01em;
  /* the letters fly out of here; reserving the width stops the heading
     reflowing as they leave */
  white-space: nowrap;
}
.kl { display: inline-block; will-change: transform; }
/* the two halves of the heading slide together as the word leaves */
.tt-a, .tt-b { will-change: transform; }
/* The morph is triggered, not scrubbed: scrolling only decides when it starts,
   so once it fires it always plays through and can never sit frozen half-way. */
.js-morph .kl { transition: transform .85s cubic-bezier(.22, 1, .36, 1); }
.js-morph .tt-a,
.js-morph .tt-b { transition: transform .7s cubic-bezier(.22, 1, .36, 1); }
/* while the morph is running the landed letter IS the glyph, so the static
   one underneath would double up */
.js-morph .kl { position: relative; z-index: 6; }
.js-morph .member-initial { opacity: 0; }

/* the portraits carry this section, so it breaks out a little wider than the
   1180px shell the rest of the page uses */
#team .wrap { max-width: 1480px; }
#team .section-head { margin-bottom: clamp(56px, 7vw, 92px); }
#team .section-head p { margin-top: 22px; }
.team-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(5, 1fr); gap: 18px;
}
.member { text-align: center; }
.member-photo {
  display: block; width: 100%; max-width: 280px; aspect-ratio: 5 / 8; margin: 0 auto;
  border-radius: 20px; overflow: hidden;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  box-shadow: var(--shadow);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}
.member-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.member:hover .member-photo { transform: translateY(-6px); box-shadow: var(--shadow-lg); }
.member-initial {
  display: block; margin-top: 16px; line-height: 1;
  font-family: var(--font-display); font-weight: 800; font-size: 1.75rem;
  color: var(--primary);
}
.member strong { display: block; font-size: .98rem; margin-top: 6px; }
.supervisor { margin-top: 40px; text-align: center; color: var(--text-muted); }
.supervisor strong { color: var(--text); }

/* ==========================================================================
   download / QR
   ========================================================================== */
.cta { position: relative; overflow: hidden; }
.cta-panel {
  display: grid; grid-template-columns: 1.25fr .75fr; gap: clamp(32px, 5vw, 64px); align-items: center;
  background: var(--surface); border: 1px solid var(--border-soft);
  border-radius: var(--radius-xl); padding: clamp(34px, 5vw, 62px); box-shadow: var(--shadow);
  position: relative; overflow: hidden;
}
/* CTA backdrop: the hero's ping, inverted. There the rings broadcast OUTWARD
   from the phone (discover). Here they collapse INWARD onto the QR — the thing
   you point a phone at — so the two sections read as a call and its answer. */
.cta-rings {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none; border-radius: inherit;
  --cx: 78%; --cy: 50%;                     /* centred on the QR card */
}
.cta-rings::before {
  content: '';
  position: absolute; left: var(--cx); top: var(--cy);
  width: min(150%, 1100px); aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: repeating-radial-gradient(circle at center,
    color-mix(in srgb, var(--primary) 15%, transparent) 0 1px,
    transparent 1px 54px);
  -webkit-mask-image: radial-gradient(circle at center, #000 3%, rgba(0,0,0,.5) 30%, transparent 62%);
          mask-image: radial-gradient(circle at center, #000 3%, rgba(0,0,0,.5) 30%, transparent 62%);
}
:root[data-theme='dark'] .cta-rings::before { opacity: .9; }

.cta-rings .ping-in {
  position: absolute; left: var(--cx); top: var(--cy);
  width: min(38%, 260px); aspect-ratio: 1; border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--primary) 48%, transparent);
  transform: translate(-50%, -50%) scale(3.2);
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .cta-rings .ping-in { animation: ping-in 8s cubic-bezier(.3, .1, .2, 1) infinite; }
  .cta-rings .ping-in:nth-child(2) { animation-delay: -2.7s; }
  .cta-rings .ping-in:nth-child(3) { animation-delay: -5.4s; }
}
@keyframes ping-in {
  0%   { transform: translate(-50%, -50%) scale(3.2); opacity: 0; }
  22%  { opacity: .42; }
  100% { transform: translate(-50%, -50%) scale(.3);  opacity: 0; }
}
/* the panel's two columns sit above the backdrop */
.cta-col { position: relative; z-index: 1; }.cta-panel h2 { font-size: clamp(1.8rem, 3.8vw, 2.6rem); position: relative; }
.cta-panel p { color: var(--text-muted); margin-top: 16px; position: relative; }
.qr-card {
  background: #fff; border-radius: var(--radius-lg); padding: 18px;
  box-shadow: var(--shadow), 0 0 0 10px color-mix(in srgb, var(--primary) 9%, transparent);
  display: grid; place-items: center; gap: 12px;
  position: relative; justify-self: center;
}
.qr-card img { width: min(200px, 46vw); height: auto; }
.qr-card figcaption { font-size: .82rem; font-weight: 700; color: #191919; letter-spacing: .01em; }
.qr-hint { display: flex; align-items: center; justify-content: center; gap: 7px; margin-top: 14px; color: var(--text-faint); font-size: .84rem; }

/* ==========================================================================
   footer
   ========================================================================== */
.footer { border-top: 1px solid var(--border-soft); background: var(--bg-elevated); padding-block: 44px; }
.footer-inner { display: flex; flex-wrap: wrap; gap: 20px; align-items: center; justify-content: space-between; }
.footer p { color: var(--text-faint); font-size: .88rem; }
.footer-links { display: flex; gap: 20px; }
.footer-links a { color: var(--text-muted); font-size: .88rem; }
.footer-links a:hover { color: var(--primary); }

/* ==========================================================================
   scroll reveal
   ========================================================================== */
.reveal { opacity: 0; transform: translateY(26px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.reveal.in { opacity: 1; transform: none; }
.reveal[data-d='1'] { transition-delay: .08s; }
.reveal[data-d='2'] { transition-delay: .16s; }
.reveal[data-d='3'] { transition-delay: .24s; }
.reveal[data-d='4'] { transition-delay: .32s; }
.reveal[data-d='5'] { transition-delay: .40s; }

/* ==========================================================================
   responsive
   ========================================================================== */
@media (max-width: 980px) {
  .hero-grid { grid-template-columns: 1fr; text-align: center; }
  .hero-sub { margin-inline: auto; }
  .hero-cta, .hero-note { justify-content: center; }
  .phone-stage { margin-top: 12px; }
  .hero-rings { --cx: 50%; --cy: 64%; }
  .frow, .cta-panel { grid-template-columns: 1fr; }
  .cta-rings { --cx: 50%; --cy: 76%; }
  .frow:nth-child(even) .frow-media { order: 0; }
  .frow-text { text-align: center; }
  .cards { grid-template-columns: repeat(2, 1fr); }
  .team-grid { grid-template-columns: repeat(3, 1fr); gap: 32px; }
  .nav { display: none; }
  /* the nav carried margin-left:auto; without it the actions need their own */
  .header-actions { margin-left: auto; }
}
@media (max-width: 620px) {
  .stats-grid { grid-template-columns: repeat(2, 1fr); gap: 30px; }
  .cards { grid-template-columns: 1fr; }
  .team-grid { grid-template-columns: repeat(2, 1fr); gap: 30px; }
  .chip-1, .chip-2, .chip-3 { display: none; }
  .footer-inner { flex-direction: column; text-align: center; }
}

/* ==========================================================================
   motion & print
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
}
@media print {
  .header, .blob, .theme-toggle { display: none; }
  body { background: #fff; color: #000; }
}

/* Between the 3-column breakpoint and ~1150px, five portraits across leave each
   one narrower than the 3-up layout does (171px at 1024 vs 204px at 768).
   Hold 3-up until there is room for five to be worth it. */
@media (min-width: 621px) and (max-width: 1150px) {
  .team-grid { grid-template-columns: repeat(3, 1fr); gap: 28px; }
}
