@charset "UTF-8";
/* ============================================================
   TriVision Hub — theme stylesheet
   Light theme built on the official logo palette.
   ============================================================ */

/* ============================================================
   DESIGN TOKENS
   ============================================================ */
:root{
  /* Foundation */
  --bg:        #FFFFFF;
  --band:      #F4F6F9;
  --surface:   #FFFFFF;
  --line:      rgba(20,26,36,.10);
  --line-soft: rgba(20,26,36,.06);
  --text:      #171C24;
  --muted:     #4D5866;
  /* --faint must clear 4.5:1 on BOTH #FFF and the tinted --band, since
     eyebrows and form labels sit on both. #6B7280 measured 4.47:1 on the
     band — just under AA — so it is nudged one step darker. */
  --faint:     #656C79;   /* 5.27:1 on white · 4.87:1 on --band */
  --quiet:     #5A6371;   /* 6.2:1 — for the smallest tracked-out type */
  --dark:      #0C0F14;

  /* Official TriVision palette (sampled from the logo file) */
  --orange:      #F08020;  --orange-ink: #B85E0A;   /* Studios */
  --red:         #E32126;  --red-ink:    #BE1A20;   /* Event Production */
  --yellow:      #F2C300;  --yellow-ink: #8F7000;   /* Event Center */
  --blue:        #50B0E0;  --blue-ink:   #0A6FA8;   /* Creative */
  --blue-deep:   #0A80C4;
  --green:       #48A830;  --green-ink:  #157F2E;

  --display: 'Sora', system-ui, sans-serif;
  --body:    'Instrument Sans', system-ui, -apple-system, sans-serif;
  --mono:    'IBM Plex Mono', ui-monospace, monospace;

  --max: 1180px;
  --pad: clamp(20px, 5vw, 48px);

  /* Vertical rhythm.
     Sections pay padding on BOTH edges, so adjacent ones stack: two 150px
     sections put 300px of nothing between their content, which was a quarter
     of the whole page. These are half-gaps — read them as "what two stacked
     values should add up to".
       --sec       plain sections: invisible edges, so this padding IS the gap
       --sec-band  tinted/dark bands: the edge is visible, so this reads as
                   interior padding rather than dead space and can be larger
     (NB: --band is already the tinted surface COLOUR, further up. Do not
      reuse that name for a length — it silently kills every band background.) */
  --sec:      clamp(52px, 5.8vw, 84px);
  --sec-band: clamp(68px, 7.4vw, 108px);
  --ease: cubic-bezier(.16,1,.3,1);

  /* Height of the fixed nav — anchors offset by this so headings
     never hide behind the bar. */
  --nav-h: 74px;

  color-scheme: light;
}

/* ============================================================
   BASE
   ============================================================ */
*{ margin:0; padding:0; box-sizing:border-box; }
html{ scroll-behavior:smooth; scroll-padding-top: calc(var(--nav-h) + 18px); }
body{
  background:var(--bg); color:var(--text);
  font-family:var(--body); font-size:1.0625rem; line-height:1.65;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}
img,svg,picture,video{ display:block; max-width:100%; }
img{ height:auto; }
a{ color:inherit; text-decoration:none; }
ul,ol{ list-style:none; }
button,input,select,textarea{ font:inherit; color:inherit; }
::selection{ background:rgba(80,176,224,.28); }

.wrap{ max-width:var(--max); margin:0 auto; padding:0 var(--pad); }
section{ padding:var(--sec) 0; position:relative; }

/* Sections that paint a background: their padding is visibly interior, so it
   gets the larger unit. Everything else's padding is pure gap. */
.why, .contact, .belief{ padding:var(--sec-band) 0; }

h1,h2,h3{ font-family:var(--display); letter-spacing:-0.02em; }
h1{ font-size:clamp(2.5rem, 6vw, 4.7rem); font-weight:700; line-height:1.06; letter-spacing:-0.03em; }
h2{ font-size:clamp(1.9rem, 3.8vw, 2.9rem); font-weight:700; line-height:1.12; }
h3{ font-size:clamp(1.35rem, 2.2vw, 1.7rem); font-weight:600; line-height:1.2; }

.eyebrow{
  font-family:var(--mono); font-size:.72rem; font-weight:500;
  letter-spacing:.22em; text-transform:uppercase; color:var(--faint);
  margin-bottom:1.4rem;
}
/* the clients heading is an <h2> styled as an eyebrow — keep the type scale */
h2.eyebrow{ font-size:.72rem; font-weight:500; letter-spacing:.22em; line-height:1.65; }

.lede{ font-size:clamp(1.05rem, 1.6vw, 1.2rem); color:var(--muted); max-width:52ch; }

/* Focus: visible on every interactive element, never removed. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, summary:focus-visible,
details:focus-visible{
  outline:2px solid var(--blue-deep); outline-offset:3px; border-radius:2px;
}

/* ============================================================
   A11Y UTILITIES
   ============================================================ */
.screen-reader-text{
  position:absolute !important; width:1px; height:1px;
  padding:0; margin:-1px; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0;
}
/* White on the dark bar — the previous dark-on-dark was nearly invisible. */
.skip-link{
  position:absolute; top:-100px; left:12px; z-index:200;
  background:#fff; color:var(--dark);
  padding:.8rem 1.2rem; border-radius:0 0 10px 10px;
  font-size:.9rem; font-weight:600;
  transition:top .2s ease;
}
.skip-link:focus{ top:0; }

/* Honeypot — off-screen rather than display:none, which many bots skip. */
.tvh-hp{
  position:absolute !important; left:-9999px; top:auto;
  width:1px; height:1px; overflow:hidden;
}

/* ============================================================
   REVEAL ANIMATION
   ============================================================ */
.reveal{ opacity:0; transform:translateY(26px); transition:opacity .85s var(--ease), transform .85s var(--ease); }
.reveal.in{ opacity:1; transform:none; }
.reveal.d1{ transition-delay:.08s; } .reveal.d2{ transition-delay:.16s; }
.reveal.d3{ transition-delay:.24s; } .reveal.d4{ transition-delay:.32s; }

/* ============================================================
   NAVIGATION
   ============================================================ */
/* Dark bar with the white wordmark. On the hub front page the v3 hero is
   dark artwork, so the bar starts fully transparent and lets it show
   through; scrolling melts it into dark glass. On any other template the
   bar stays solid — a transparent bar over a light page would vanish. */
.nav{
  position:fixed; inset:0 0 auto 0; z-index:100;
  background:var(--dark);
  border-bottom:1px solid rgba(255,255,255,.08);
  transition:background .35s ease, border-color .35s ease, box-shadow .35s ease;
}
.tvh-hub .nav:not(.scrolled){
  background:transparent; border-bottom-color:transparent;
}
.nav.scrolled{
  background:rgba(12,15,20,.92);
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  box-shadow:0 10px 30px -20px rgba(0,0,0,.7);
}
.nav-inner{
  max-width:var(--max); margin:0 auto; padding:0 var(--pad);
  height:var(--nav-h); display:flex; align-items:center; justify-content:space-between; gap:2rem;
}
.logo{ display:flex; align-items:center; flex-shrink:0; }
.logo picture{ display:block; }
/* Wordmark only — the colour mark lives in the footer. The asset is cropped
   to its glyphs, so this height IS the cap height (21px + 20% = 25px). */
.logo .logo-word{ height:25px; width:auto; }

.nav-links{ display:flex; align-items:center; gap:1.8rem; }
.nav-links a{
  font-size:.86rem; font-weight:500; color:rgba(255,255,255,.78);
  letter-spacing:.02em; position:relative; padding:6px 0;
  transition:color .25s ease; white-space:nowrap;
}
.nav-links a:hover{ color:#fff; }
.nav-links a::after{
  content:""; position:absolute; left:0; bottom:0; height:2px; width:0;
  background:var(--hl, #fff); transition:width .3s var(--ease);
}
.nav-links a:hover::after{ width:100%; }
/* scroll-spy: the section you are actually looking at */
.nav-links a.is-active{ color:#fff; }
.nav-links a.is-active::after{ width:100%; }

/* The CTA sits outside .nav-links (see header.php) so it survives the mobile
   breakpoint and never competes with `.nav-links a` on specificity — which is
   what previously stripped its padding and rendered it as a bare black box. */
.nav-end{ display:flex; align-items:center; gap:.75rem; flex-shrink:0; }

/* White pill on the dark bar — the highest-contrast element in the header,
   which is what a primary CTA should be. */
.nav-cta{
  display:inline-flex; align-items:center; justify-content:center;
  font-size:.84rem; font-weight:600; color:var(--dark);
  background:#fff; border-radius:999px;
  padding:.68rem 1.35rem; line-height:1; white-space:nowrap;
  min-height:44px;                    /* comfortable tap target */
  transition:transform .25s ease, background .25s ease;
}
.nav-cta:hover{ transform:translateY(-1px); background:#EDEFF3; color:var(--dark); }
.cta-short{ display:none; }

.burger{
  display:none; background:none; border:0; cursor:pointer;
  width:44px; height:44px;            /* full tap target, not just the bars */
  align-items:center; justify-content:center;
  flex-direction:column; gap:5px;
}
.burger span{ width:22px; height:2px; background:#fff; transition:transform .3s ease, opacity .3s ease; }
.burger[aria-expanded="true"] span:nth-child(1){ transform:translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2){ opacity:0; }
.burger[aria-expanded="true"] span:nth-child(3){ transform:translateY(-7px) rotate(-45deg); }

/* Dark to match the bar it drops out of. */
.mobile-menu{
  position:fixed; inset:var(--nav-h) 0 0 0; z-index:99;
  background:rgba(12,15,20,.98);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:1.8rem; padding:2rem var(--pad); overflow-y:auto;
}
.mobile-menu[hidden]{ display:none; }
@keyframes rise{ from{ opacity:0; transform:translateY(14px); } to{ opacity:1; transform:none; } }
.mobile-menu:not([hidden]) a{ animation:rise .5s var(--ease) both; }
.mobile-menu:not([hidden]) a:nth-child(2){ animation-delay:.06s; }
.mobile-menu:not([hidden]) a:nth-child(3){ animation-delay:.12s; }
.mobile-menu:not([hidden]) a:nth-child(4){ animation-delay:.18s; }
.mobile-menu:not([hidden]) a:nth-child(5){ animation-delay:.24s; }
.mobile-menu:not([hidden]) a:nth-child(6){ animation-delay:.3s; }
.mobile-menu a{
  font-family:var(--display); font-size:clamp(1.15rem,4.5vw,1.4rem);
  font-weight:600; color:#fff; text-align:center;
}
.mobile-menu a small{
  display:block; font-family:var(--mono); font-size:.66rem; letter-spacing:.2em;
  text-transform:uppercase; color:rgba(255,255,255,.62); margin-top:.3rem; font-weight:400;
}
.mobile-menu a:focus-visible{ outline-color:#fff; }

/* ============================================================
   HERO
   ============================================================ */
.hero{
  position:relative; min-height:100svh;
  display:flex; align-items:center;
  padding:calc(var(--nav-h) + 76px) 0 48px;
  color:#fff; overflow:hidden;
}
.hero-bg{ position:absolute; inset:0; }
.hero-bg picture, .hero-bg img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
}
.hero-bg::after{
  content:""; position:absolute; inset:0;
  background:
    linear-gradient(100deg, rgba(5,8,13,.84) 0%, rgba(5,8,13,.52) 46%, rgba(5,8,13,.22) 100%),
    linear-gradient(180deg, rgba(5,8,13,.30) 0%, transparent 32%, transparent 68%, rgba(5,8,13,.62) 100%);
}
@keyframes kb{ from{ transform:scale(1); } to{ transform:scale(1.06); } }
.hero-bg img{ animation:kb 30s ease-in-out infinite alternate; will-change:transform; }
.hero-inner{ position:relative; z-index:2; width:100%; min-width:0; }
.hero .eyebrow{ color:rgba(255,255,255,.62); }
.hero .sub{
  margin-top:1.6rem; font-size:clamp(1.05rem, 1.7vw, 1.25rem);
  color:rgba(255,255,255,.88); max-width:58ch;
}
.hero-ctas{ display:flex; flex-wrap:wrap; gap:1rem; margin-top:2.4rem; }

.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:.55rem;
  font-weight:600; font-size:.95rem; border-radius:999px;
  padding:.95rem 1.7rem; cursor:pointer; border:0;
  transition:transform .28s var(--ease), opacity .28s ease, border-color .28s ease;
}
/* Transparent border so the solid and ghost buttons are the same height when
   they sit side by side (or stack on mobile). */
.btn-primary{ background:var(--dark); color:#fff; border:1px solid var(--dark); }
.btn-primary:hover{ transform:translateY(-2px); opacity:.92; }
.btn-primary[disabled]{ opacity:.55; cursor:progress; transform:none; }
.btn-ghost{ background:transparent; color:var(--text); border:1px solid var(--line); }
.btn-ghost:hover{ transform:translateY(-2px); border-color:rgba(20,26,36,.28); }
.btn:active{ transform:translateY(0) scale(.97); }
/* On the dark artwork the primary/ghost roles invert. The secondary gets a
   frosted-glass fill rather than a bare outline — a 42%-opacity hairline on
   this busy artwork read as a disabled control sitting next to the solid
   white primary. */
.hero .btn-primary{ background:#fff; color:var(--dark); border-color:#fff; }
.hero .btn-ghost{
  color:#fff;
  background:rgba(255,255,255,.12);
  border-color:rgba(255,255,255,.32);
  backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
}
.hero .btn-ghost:hover{
  background:rgba(255,255,255,.2);
  border-color:rgba(255,255,255,.6);
}

/* Experience-types ticker */
.ticker{
  margin-top:clamp(3rem, 7vh, 5rem); overflow:hidden; max-width:100%;
  border-top:1px solid rgba(255,255,255,.16); border-bottom:1px solid rgba(255,255,255,.16);
  padding:.95rem 0;
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image:linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.ticker-track{
  display:flex; align-items:center; gap:2.6rem; width:max-content;
  animation:tick 38s linear infinite;
}
.ticker-track span{
  font-family:var(--mono); font-size:.7rem; font-weight:500;
  letter-spacing:.22em; text-transform:uppercase;
  color:rgba(255,255,255,.72); white-space:nowrap;
}
.ticker-track i{ width:6px; height:6px; border-radius:50%; flex:none; font-style:normal; }
.ticker:hover .ticker-track{ animation-play-state:paused; }
@keyframes tick{ to{ transform:translateX(-50%); } }

/* ============================================================
   STORY + COUNT-UP STATS
   ============================================================ */
.story{ padding-bottom:calc(var(--sec) * .55); }
.story-grid{ display:grid; grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr); gap:clamp(2rem,6vw,5rem); align-items:start; }
.story p + p{ margin-top:1.1rem; }

.stats{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; }

.stat{
  background:var(--surface); border:1px solid var(--line);
  border-radius:14px; padding:1.6rem 1.4rem;
  box-shadow:0 14px 34px -26px rgba(12,15,20,.35);
  transition:transform .35s var(--ease), box-shadow .35s ease;
}
.stat:hover{ transform:translateY(-3px); box-shadow:0 22px 44px -28px rgba(12,15,20,.42); }
.stat b{
  display:flex; align-items:baseline; gap:2px;
  font-family:var(--display); font-weight:700;
  font-size:clamp(1.9rem, 3vw, 2.5rem); letter-spacing:-0.02em; line-height:1;
}
/* Units are half the digit size and never split mid-unit — at .6em
   "12,000 sq ft" ran past the card edge on narrow stat columns. */
.stat b small{ font-size:.45em; font-weight:700; white-space:nowrap; letter-spacing:0; }
.stat b{ flex-wrap:wrap; row-gap:2px; }
.stat > span{
  display:block; margin-top:.55rem; font-family:var(--mono);
  font-size:.66rem; letter-spacing:.18em; text-transform:uppercase; color:var(--faint);
  overflow-wrap:anywhere;
}

/* ============================================================
   PRISM
   ============================================================ */
.prism{ padding:0; margin-top:-8px; }
.prism svg{ width:100%; height:auto; }
.prism path{
  stroke-dasharray:620; stroke-dashoffset:620;
  transition:stroke-dashoffset 1.6s cubic-bezier(.4,0,.2,1);
}
.prism.in path{ stroke-dashoffset:0; }
.prism.in path:nth-of-type(2){ transition-delay:.12s; }
.prism.in path:nth-of-type(3){ transition-delay:.24s; }
.prism.in path:nth-of-type(4){ transition-delay:.36s; }
.prism.in path:nth-of-type(5){ transition-delay:.48s; }

/* ============================================================
   BRAND GRID — the four doors
   ============================================================ */
/* The prism already carries the eye down into this section, so it needs far
   less lead-in than a standard band; the tail is trimmed so the gap before
   the "why" band does not read as a dead zone. */
.brands{ padding-top:clamp(36px, 5vw, 70px); padding-bottom:calc(var(--sec) * .72); }
.brands-head{ max-width:60ch; margin-bottom:clamp(2.5rem,5vw,4rem); }
.brand-grid{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:14px; }

.brand-card{
  --accent:var(--orange); --ink:var(--orange-ink);
  position:relative; background:var(--surface);
  border:1px solid var(--line); border-radius:14px;
  padding:1.5rem 1.35rem;
  display:flex; flex-direction:column; overflow:hidden;
  box-shadow:0 18px 44px -34px rgba(12,15,20,.35);
  transition:transform .45s var(--ease), border-color .45s ease, box-shadow .45s ease;
  scroll-margin-top: calc(var(--nav-h) + 24px);
}
.brand-card::before{
  content:""; position:absolute; top:0; left:0; right:0; height:3px;
  background:linear-gradient(90deg, transparent, var(--accent), transparent);
  opacity:.85; transition:opacity .45s ease;
}
.brand-card::after{
  content:""; position:absolute; right:-22%; bottom:-28%; width:66%; height:66%;
  background:radial-gradient(closest-side, var(--accent), transparent 70%);
  opacity:.10; transition:opacity .45s ease, transform .6s var(--ease);
  pointer-events:none;
}
.brand-card:hover{
  transform:translateY(-5px);
  border-color:rgba(20,26,36,.18);
  box-shadow:0 30px 60px -30px rgba(12,15,20,.4);
}
.brand-card:hover::before{ opacity:1; }

.brand-card:hover::after{ opacity:.16; transform:scale(1.1); }
/* keyboard parity with :hover — focus inside the card lifts it too */
.brand-card:focus-within{
  border-color:rgba(20,26,36,.18);
  box-shadow:0 30px 60px -30px rgba(12,15,20,.4);
}

.card-role{
  font-family:var(--mono); font-size:.62rem; font-weight:500;
  letter-spacing:.18em; text-transform:uppercase; color:var(--ink);
  margin-bottom:.6rem;
}
.brand-card h3{ font-size:1.08rem; line-height:1.3; margin-bottom:.6rem; }
.brand-card h3 span{ color:var(--muted); font-weight:400; }
.card-essence{ color:var(--muted); font-size:.88rem; line-height:1.55; margin-bottom:1.05rem; }
.card-caps{ margin-bottom:1.5rem; display:grid; gap:.45rem; }
.card-caps li{ position:relative; padding-left:1rem; font-size:.82rem; line-height:1.5; color:var(--muted); }
.card-caps li::before{
  content:""; position:absolute; left:0; top:.62em; width:6px; height:6px;
  border-radius:50%; background:var(--accent);
}

/* The underline is drawn with a background gradient rather than a pseudo-
   element, which frees ::after for the stretched-link overlay below. */
.card-cta{
  margin-top:auto; display:inline-flex; align-items:center; gap:.5rem;
  font-weight:600; font-size:.85rem; color:var(--text);
  width:fit-content; padding-bottom:4px;
  background-image:linear-gradient(var(--accent), var(--accent));
  background-repeat:no-repeat;
  background-position:left bottom;
  background-size:35% 2px;
  transition:background-size .35s var(--ease);
}
.brand-card:hover .card-cta,
.brand-card:focus-within .card-cta{ background-size:100% 2px; }
.card-cta .arrow{ transition:transform .35s var(--ease); }
.brand-card:hover .card-cta .arrow{ transform:translateX(5px); }

/* Stretched link — the whole card is the click target while the markup keeps
   exactly one real, keyboard-focusable anchor. The overlay sits above the
   card's decorative layers but the card itself is the positioning context. */
.card-cta.stretched::after{
  content:""; position:absolute; inset:0; z-index:3;
  border-radius:inherit;
}

.card-cta.is-soon{
  color:var(--faint); font-weight:500;
  display:flex; flex-wrap:wrap; gap:.5rem;
  background-image:none;
}
.card-cta.is-soon a{
  color:var(--ink); font-weight:600; text-decoration:underline;
  text-underline-offset:3px;
}


/* ============================================================
   ANIMATED ICONS — in-card (brands) + in-stat (story)
   The .ic-d strokes draw themselves when the parent reveals (.in);
   the looping accents all stop under prefers-reduced-motion.
   ============================================================ */
.card-icon{ width:40px; height:40px; margin-bottom:.95rem; color:var(--ink); }
.card-icon svg{ width:100%; height:100%; overflow:visible; }
.ic-d{
  fill:none; stroke:currentColor; stroke-width:2.4;
  stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:210; stroke-dashoffset:210;
  transition:stroke-dashoffset 1.2s var(--ease) .2s;
}
.brand-card.in .ic-d{ stroke-dashoffset:0; }
.ic-f{ fill:currentColor; opacity:0; transition:opacity .9s ease .7s; }
.brand-card.in .ic-f{ opacity:.16; }
.ic-blink{ animation:icblink 2.4s ease-in-out infinite; }
@keyframes icblink{ 0%,100%{ opacity:1; } 50%{ opacity:.18; } }
.ic-beam-l, .ic-beam-r{ transform-box:fill-box; transform-origin:50% 0%; }
.ic-beam-l{ animation:sweepL 5.5s ease-in-out infinite alternate; }
.ic-beam-r{ animation:sweepR 5.5s ease-in-out infinite alternate; }
@keyframes sweepL{ from{ transform:rotate(-7deg); } to{ transform:rotate(7deg); } }
@keyframes sweepR{ from{ transform:rotate(7deg); } to{ transform:rotate(-7deg); } }
.ic-halo{
  transform-box:fill-box; transform-origin:center;
  animation:halo 2.8s ease-out infinite;
}
@keyframes halo{ 0%{ transform:scale(.55); opacity:.8; } 75%,100%{ transform:scale(1.55); opacity:0; } }
.ic-eye{ transform-box:fill-box; transform-origin:center; animation:eyeblink 5.2s infinite; }
@keyframes eyeblink{ 0%,90%,100%{ transform:scaleY(1); } 94%{ transform:scaleY(.06); } }

.stat-ic{ display:block; width:28px; height:28px; margin-bottom:1rem; }
.stat-ic svg{ width:100%; height:100%; overflow:visible; }
.stat-ic .s{ fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.ic-hand{ transform-box:view-box; transform-origin:center; animation:rot 12s linear infinite; }
@keyframes rot{ to{ transform:rotate(360deg); } }
.ic-seq{ opacity:.4; animation:seq 3.6s ease-in-out infinite; }
@keyframes seq{ 0%,100%{ opacity:.4; } 16%{ opacity:1; } }

/* ============================================================
   WHY — flow infographic + pillars
   ============================================================ */
.why{ background:var(--band); border-top:1px solid var(--line-soft); border-bottom:1px solid var(--line-soft); }
.flow{ margin:clamp(2.2rem,4vw,3.2rem) 0 clamp(1rem,2vw,1.6rem); }
.flow svg{ width:100%; height:auto; }
.flow .ch{
  fill:none; stroke-linecap:round;
  stroke-dasharray:1000; stroke-dashoffset:1000;
  transition:stroke-dashoffset 1.7s cubic-bezier(.4,0,.2,1);
}
.flow.in .ch{ stroke-dashoffset:0; }
.flow.in .ch:nth-of-type(2){ transition-delay:.1s; }
.flow.in .ch:nth-of-type(3){ transition-delay:.2s; }
.flow.in .ch:nth-of-type(4){ transition-delay:.3s; }
.flow text{ font-family:var(--mono); letter-spacing:.14em; }
.flow-caption{
  text-align:center; font-family:var(--mono); font-size:.7rem;
  letter-spacing:.2em; text-transform:uppercase; color:var(--quiet);
  margin-bottom:clamp(2.2rem,4vw,3rem);
}
.flow-legend{ display:none; }

.why-grid{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:clamp(1.5rem,3vw,2.5rem); }
.pillar h3{ font-size:1.15rem; margin-bottom:.7rem; }
/* Reserve two lines for the heading so the four body copies share a baseline
   even when one title wraps ("Production-grade everything"). */
@media (min-width: 961px){
  .pillar h3{ min-height:2.4em; }
}
.pillar p{ font-size:.95rem; color:var(--muted); }
.pillar .tick{
  width:34px; height:3px; margin-bottom:1.1rem; border-radius:3px;
  /* Final comp drops yellow from the accent sweep — it vanished against the
     tinted band at 3px tall. */
  background:linear-gradient(90deg, var(--orange), var(--red), var(--green), var(--blue));
  transition:width .45s var(--ease);
}
.pillar:hover .tick{ width:58px; }

/* ============================================================
   CLIENTS
   ============================================================ */
.clients{ text-align:center; }
.client-wall{
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:.9rem; margin:2.6rem auto 0; max-width:880px;
}
.client-wall li{
  --ca:var(--text);
  font-family:var(--display); font-weight:600; font-size:clamp(.8rem, 1.05vw, .92rem);
  letter-spacing:.08em; text-transform:uppercase; color:var(--quiet);
  border:1px solid var(--line); border-radius:999px;
  padding:.78rem 1.4rem; line-height:1.3; text-align:center;
  transition:color .3s ease, border-color .3s ease, transform .3s var(--ease);
}
.client-wall li:hover{ color:var(--text); border-color:var(--ca); transform:translateY(-2px); }
.client-wall li:nth-child(4n+1){ --ca:var(--orange); }
.client-wall li:nth-child(4n+2){ --ca:var(--red); }
.client-wall li:nth-child(4n+3){ --ca:var(--yellow); }
.client-wall li:nth-child(4n+4){ --ca:var(--blue); }

/* ============================================================
   BELIEF
   ============================================================ */
.belief{ position:relative; text-align:center; color:#EDEFF3; overflow:hidden; }
.belief .bg{ position:absolute; inset:0; z-index:0; }
.belief .bg img{ width:100%; height:100%; object-fit:cover; animation:kb 24s ease-in-out infinite alternate; will-change:transform; }
.belief::after{
  content:""; position:absolute; inset:0; z-index:1;
  background:linear-gradient(180deg, rgba(8,10,14,.66), rgba(8,10,14,.58));
}
.belief .wrap{ position:relative; z-index:2; }
.belief blockquote{
  font-family:var(--display); font-weight:600;
  font-size:clamp(1.7rem, 4.4vw, 3.2rem); line-height:1.2; letter-spacing:-0.02em;
  max-width:22ch; margin:0 auto;
}
.belief .bar{
  width:120px; height:2px; margin:2rem auto 0; border-radius:2px;
  background:rgba(255,255,255,.92);
}
.belief figcaption{
  margin-top:1.6rem; font-family:var(--mono); font-size:.72rem;
  letter-spacing:.2em; text-transform:uppercase; color:rgba(237,239,243,.78);
}

/* ============================================================
   FAQ
   ============================================================ */
.faq-head{ max-width:60ch; margin-bottom:clamp(2rem,4vw,3rem); }
.faq-list{ max-width:82ch; }
.faq-item{
  border-bottom:1px solid var(--line);
  padding:0;
}
.faq-item:first-child{ border-top:1px solid var(--line); }
.faq-item summary{
  display:flex; align-items:flex-start; justify-content:space-between; gap:1.5rem;
  padding:1.5rem 0; cursor:pointer; list-style:none;
  transition:color .25s ease;
}
.faq-item summary::-webkit-details-marker{ display:none; }
.faq-item summary h3{
  font-size:clamp(1.05rem,1.7vw,1.2rem); font-weight:600; line-height:1.4;
  margin:0; flex:1;
}
.faq-item summary:hover h3{ color:var(--blue-ink); }
.faq-icon{
  position:relative; flex:0 0 20px; width:20px; height:20px; margin-top:.25rem;
}
.faq-icon::before,
.faq-icon::after{
  content:""; position:absolute; left:50%; top:50%;
  background:var(--muted); border-radius:2px;
  transform:translate(-50%,-50%);
  transition:transform .3s var(--ease), opacity .3s ease;
}
.faq-icon::before{ width:14px; height:2px; }
.faq-icon::after{ width:2px; height:14px; }
.faq-item[open] .faq-icon::after{ transform:translate(-50%,-50%) rotate(90deg); opacity:0; }
.faq-answer{ padding:0 0 1.6rem; max-width:70ch; }
.faq-answer p{ color:var(--muted); font-size:1rem; }

/* ============================================================
   CONTACT
   ============================================================ */
.contact{ background:var(--band); border-top:1px solid var(--line-soft); }
.contact-grid{ display:grid; grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr); gap:clamp(2.5rem,6vw,5rem); }
.contact-info p{ color:var(--muted); max-width:44ch; }
.contact-meta{ margin-top:2.4rem; display:grid; gap:1.3rem; }
.contact-meta div b{
  display:block; font-family:var(--mono); font-size:.66rem; font-weight:500;
  letter-spacing:.2em; text-transform:uppercase; color:var(--faint); margin-bottom:.35rem;
}
.contact-meta div a{ transition:color .25s ease; }
.contact-meta div a:hover{ color:var(--blue-deep); }

.tvh-form{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:1.1rem; }
.field{ display:flex; flex-direction:column; gap:.45rem; }
.field.full{ grid-column:1 / -1; }
.field label{
  font-family:var(--mono); font-size:.66rem; font-weight:500;
  letter-spacing:.2em; text-transform:uppercase; color:var(--faint);
}
.field label em{ color:var(--red-ink); font-style:normal; }

input, select, textarea{
  background:#FFFFFF; border:1px solid var(--line); border-radius:10px;
  color:var(--text); font-family:var(--body);
  /* Exactly 16px, not 0.98rem: iOS Safari force-zooms the whole page when a
     focused field is under 16px, which throws the layout off mid-form. */
  font-size:16px;
  padding:.85rem 1rem; width:100%;
  transition:border-color .25s ease, box-shadow .25s ease;
  appearance:none; -webkit-appearance:none;
}
select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%234D5866' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 1rem center;
  padding-right:2.5rem;
}
textarea{ min-height:130px; resize:vertical; }
.field:focus-within > label{ color:var(--blue-deep); }
input:focus, select:focus, textarea:focus{
  border-color:var(--blue-deep); outline:none;
  box-shadow:0 0 0 3px rgba(10,128,196,.14);
}
input.err, select.err, textarea.err{ border-color:var(--red); }
.field .msg{ font-size:.8rem; color:var(--red-ink); display:none; }
.field.show-err .msg{ display:block; }

/* ---- Checkbox group -------------------------------------------------- */
.checks{ border:0; padding:0; margin:0; min-width:0; }
.checks legend{
  font-family:var(--mono); font-size:.66rem; font-weight:500;
  letter-spacing:.2em; text-transform:uppercase; color:var(--faint);
  padding:0; margin-bottom:.75rem;
}
.checks legend em{ color:var(--red-ink); font-style:normal; }
.checks legend .legend-hint{
  display:block; margin-top:.35rem;
  font-family:var(--body); font-size:.78rem; letter-spacing:0;
  text-transform:none; color:var(--faint);
}
.check-grid{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.6rem; }

/* These are <label> elements inside .field, so they inherit the mono/uppercase
   /tracked treatment meant for field labels. Reset it — option text is prose. */
.check{
  display:flex; align-items:flex-start; gap:.7rem;
  background:#FFFFFF; border:1px solid var(--line); border-radius:10px;
  padding:.8rem .9rem; cursor:pointer; min-height:48px;
  font-family:var(--body); text-transform:none; letter-spacing:normal;
  transition:border-color .2s ease, background .2s ease, box-shadow .2s ease;
}
.check:hover{ border-color:rgba(20,26,36,.26); }
/* The native input stays in the a11y tree and keeps keyboard behaviour;
   only its painting is replaced. */
.check input{
  position:absolute; opacity:0; width:1px; height:1px; margin:0; padding:0;
}
.check .box{
  flex:0 0 20px; width:20px; height:20px; margin-top:1px;
  border:1.5px solid rgba(20,26,36,.3); border-radius:6px;
  background:#fff; position:relative;
  transition:background .2s ease, border-color .2s ease;
}
.check .box::after{
  content:""; position:absolute; left:6px; top:2px;
  width:5px; height:10px; border:solid #fff; border-width:0 2px 2px 0;
  transform:rotate(45deg) scale(.4); opacity:0;
  transition:opacity .18s ease, transform .18s ease;
}
.check .check-label{
  font-family:var(--body); font-size:.94rem; line-height:1.35;
  letter-spacing:normal; text-transform:none; color:var(--muted);
}

.check input:checked ~ .box{ background:var(--dark); border-color:var(--dark); }
.check input:checked ~ .box::after{ opacity:1; transform:rotate(45deg) scale(1); }
.check:has(input:checked){ border-color:var(--dark); background:#FCFCFD; }
.check:has(input:checked) .check-label{ color:var(--text); font-weight:500; }
.check input:focus-visible ~ .box{
  outline:2px solid var(--blue-deep); outline-offset:3px;
}
.checks.err .check{ border-color:var(--red); }

/* ---- Maths challenge ------------------------------------------------- */
.challenge-row{ display:flex; align-items:center; gap:.85rem; flex-wrap:wrap; }
.challenge-q{
  font-family:var(--display); font-weight:600; font-size:1.05rem;
  color:var(--text); white-space:nowrap;
  background:#fff; border:1px solid var(--line); border-radius:10px;
  padding:.7rem 1rem; user-select:none;
}
.challenge-row input{ width:auto; flex:0 1 130px; }

.form-actions{ grid-column:1 / -1; display:flex; align-items:center; gap:1.2rem; flex-wrap:wrap; }
.form-note{ font-size:.82rem; color:var(--faint); }
.form-error{
  grid-column:1 / -1; font-size:.9rem; color:var(--red-ink);
  background:rgba(227,33,38,.07); border:1px solid rgba(227,33,38,.22);
  border-radius:10px; padding:.85rem 1rem;
}
.form-error[hidden]{ display:none; }

/* Jotform embed slot — a soft card so the iframe sits on the tinted band
   like the old native form did; min-height keeps the section from
   collapsing (and the page from shifting) while the iframe boots. */
.jotform-slot{
  background:#FFFFFF; border:1px solid var(--line); border-radius:14px;
  padding:clamp(.4rem, 1.5vw, 1.2rem);
  box-shadow:0 18px 44px -34px rgba(12,15,20,.35);
  min-height:520px;
}
.jotform-slot iframe{ border-radius:10px; }

.success{
  display:none; text-align:center;
  background:#FFFFFF; border:1px solid var(--line); border-radius:14px;
  padding:3rem 2rem;
}
.success.show{ display:block; }
.success .ok{
  width:56px; height:56px; margin:0 auto 1.1rem; display:block;
  stroke:var(--green-ink); stroke-width:3; stroke-linecap:round; stroke-linejoin:round;
}
.success .ok circle{ stroke-dasharray:152; stroke-dashoffset:152; }
.success .ok path{ stroke-dasharray:34; stroke-dashoffset:34; }
.success.show .ok circle{ animation:okd .7s var(--ease) forwards; }
.success.show .ok path{ animation:okd .45s var(--ease) .55s forwards; }
@keyframes okd{ to{ stroke-dashoffset:0; } }
.success p{ color:var(--muted); margin-top:.6rem; }

/* ============================================================
   SIMPLE PAGE SHELL (index.php / 404.php)
   ============================================================ */
.page-shell{ padding:calc(var(--nav-h) + 90px) 0 var(--sec); }
.page-body{ max-width:64ch; }
.page-content{ margin-top:1.5rem; color:var(--muted); }
.page-content > * + *{ margin-top:1.1rem; }

.brand-mini{
  display:grid; grid-template-columns:repeat(2,1fr); gap:1rem;
  margin-top:clamp(2.5rem,5vw,4rem);
}
.brand-mini li{ --accent:var(--orange); }
.brand-mini a{
  display:block; padding:1.4rem 1.5rem;
  border:1px solid var(--line); border-left:3px solid var(--accent);
  border-radius:12px; background:var(--surface);
  transition:transform .3s var(--ease), box-shadow .3s ease;
}
.brand-mini a:hover{ transform:translateY(-3px); box-shadow:0 20px 40px -30px rgba(12,15,20,.45); }
.brand-mini b{ display:block; font-family:var(--display); font-weight:600; font-size:1.05rem; }
.brand-mini span{
  display:block; margin-top:.3rem; font-family:var(--mono); font-size:.66rem;
  letter-spacing:.16em; text-transform:uppercase; color:var(--ink, var(--faint));
}

/* ============================================================
   FOOTER
   ============================================================ */
footer{ border-top:1px solid var(--line-soft); padding:clamp(3rem,6vw,4.5rem) 0 2.5rem; }
.foot-top{
  display:grid; grid-template-columns:minmax(0,1.2fr) minmax(0,.8fr) minmax(0,.8fr); gap:clamp(2rem,5vw,4rem);
  padding-bottom:2.8rem; border-bottom:1px solid var(--line-soft);
}
.foot-logo img{ height:120px; width:auto; }
.foot-tag{ margin-top:1.2rem; color:var(--muted); font-size:.95rem; max-width:34ch; }
.foot-col h2{
  font-family:var(--mono); font-size:.66rem; font-weight:500;
  letter-spacing:.2em; text-transform:uppercase; color:var(--faint);
  margin-bottom:1.1rem; line-height:1.65;
}
.foot-col ul{ display:grid; gap:.65rem; }
.foot-col a{ font-size:.94rem; color:var(--muted); transition:color .25s ease; }
.foot-col a:hover{ color:var(--text); }
.foot-bottom{
  display:flex; justify-content:space-between; align-items:center; gap:1.5rem; flex-wrap:wrap;
  padding-top:2.2rem; font-size:.82rem; color:var(--faint);
}
.foot-bottom a:hover{ color:var(--text); }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1080px){
  .nav-links{ gap:1.3rem; }
  .nav-links a{ font-size:.82rem; }
}
@media (max-width: 960px){
  .nav-links{ display:none; }
  .burger{ display:flex; }
  /* Header keeps a call to action on phones — just a shorter one. */
  .cta-long{ display:none; }
  .cta-short{ display:inline; }
  .nav-cta{ padding:.68rem 1.15rem; }
  /* Tablets keep two cards abreast — four full-width cards in a row is a
     lot of scrolling; they collapse to one column at phone widths below. */
  .brand-grid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .story-grid{ grid-template-columns:minmax(0,1fr); }
  .why-grid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .contact-grid{ grid-template-columns:minmax(0,1fr); }
  .foot-top{ grid-template-columns:minmax(0,1fr); }
}
@media (max-width: 700px){
  /* The viewBox is 1200 wide; at ~350px it renders at 0.29x, so NOTHING
     inside the SVG is legible — including the endpoint pills, which used to
     render as two blank black capsules. On mobile the ribbon becomes purely
     decorative and the meaning moves to the HTML key below it. */
  .flow svg text{ display:none; }
  .flow svg .endpoint rect{ opacity:.9; }

  .flow-legend{
    display:flex; flex-direction:column; align-items:center; gap:.55rem;
    margin-top:1.4rem;
  }
  .flow-legend li{
    display:flex; align-items:center; gap:.6rem;
    font-family:var(--mono); font-size:.72rem; letter-spacing:.12em;
    text-transform:uppercase; color:var(--muted);
  }
  .flow-legend i{ width:16px; height:4px; border-radius:2px; font-style:normal; flex:0 0 16px; }
  /* The two endpoints, rendered as real text instead of unreadable SVG. */
  .flow-legend li.ep{
    color:var(--text); font-weight:500; letter-spacing:.16em;
    background:var(--dark); color:#fff; border-radius:999px;
    padding:.5rem 1.1rem; font-size:.68rem;
  }
  .flow-legend li.ep::before{ content:none; }
  .flow-legend li.arrow{
    color:var(--faint); font-size:1rem; letter-spacing:0; padding:0; gap:0;
  }
  .brand-mini{ grid-template-columns:1fr; }
}
/* Touch targets: 19px text links are hard to hit with a thumb. Padding them
   out to ~36px clears the WCAG 2.2 minimum with room to spare; the list gap
   shrinks to match so the footer does not grow taller. */
@media (max-width: 960px){
  .foot-col ul{ gap:.1rem; }
  .foot-col a,
  .contact-meta a,
  .foot-bottom a{ display:inline-block; padding:.5rem 0; }
  .contact-meta{ gap:1rem; }
}

@media (max-width: 620px){
  .tvh-form{ grid-template-columns:minmax(0,1fr); }
  .check-grid{ grid-template-columns:minmax(0,1fr); }
  .challenge-row input{ flex:1 1 auto; }
  .brand-grid{ grid-template-columns:minmax(0,1fr); }
  .hero h1 br{ display:none; }
  .hero h1{ font-size:clamp(2.2rem, 10.5vw, 4.7rem); }
  .nav-inner{ gap:1rem; }
  .why-grid{ grid-template-columns:minmax(0,1fr); }
  .stats{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .foot-logo img{ height:96px; }
  .form-actions .btn{ width:100%; }
  .foot-bottom{ flex-direction:column; align-items:flex-start; gap:.6rem; }
  /* Stacked hero CTAs read as one control group when they share a width. */
  .hero-ctas{ gap:.75rem; }
  .hero-ctas .btn{ width:100%; }
}

/* Sub-400px phones (iPhone SE, small Androids): the 25px wordmark (~152px
   wide) + Contact pill + burger overflow anything narrower, so the wordmark
   steps down instead of disappearing — it is the only logo in the bar now. */
@media (max-width: 400px){
  .logo .logo-word{ height:18px; }
  .nav-end{ gap:.4rem; }
}

/* Short landscape phones: 150px of hero lead-in on a 375px-tall screen left
   the headline half below the fold. */
@media (max-height: 520px){
  .hero{ min-height:0; padding:calc(var(--nav-h) + 28px) 0 40px; }
  .hero .ticker{ margin-top:1.6rem; }
}

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *, *::before, *::after{ animation:none !important; transition:none !important; }
  .reveal{ opacity:1; transform:none; }
  .prism path{ stroke-dashoffset:0; }
  .flow .ch{ stroke-dashoffset:0; }
  .ic-d{ stroke-dashoffset:0; }
  .ic-f{ opacity:.16; }
  .success .ok circle, .success .ok path{ stroke-dashoffset:0; }
}

/* ============================================================
   PRINT
   ============================================================ */
@media print{
  .nav, .mobile-menu, .burger, .hero-ctas, .tvh-form, .skip-link, .prism, .flow{ display:none !important; }
  body{ font-size:11pt; color:#000; }
  section{ padding:1.2rem 0; break-inside:avoid; }
  .belief{ color:#000; }
  .belief::after, .belief .bg{ display:none; }
  .reveal{ opacity:1 !important; transform:none !important; }
  a[href^="http"]::after{ content:" (" attr(href) ")"; font-size:9pt; color:#444; }
}
