/* ═══════════════════════════════════════════
   RATAN BIO — design tokens
   ═══════════════════════════════════════════ */
:root{
  --bone:#EFEFEC;
  --bone-2:#E6E6E1;
  --ink:#0C0C0C;
  --ink-2:#161616;
  --sage:#C2D69B;
  /* These MUST track the palette in protein.js / thumbs.js. They drifted once:
     the renders were saturated and these were left muted, so every 3D object
     was vivid and every piece of chrome around it was drained — the page read
     as two brands sharing a scroll. If you retune one, retune both. */
  --jade:#2ED06E;        /* the real Ratan Bio brand green — use it, not a substitute */
  --jade-ink:#12703A;    /* jade fails contrast on bone; this is jade for TEXT only */
  --ember:#FF5F1F;
  --violet:#5B2FC9;
  --magenta:#B026FF;
  --mist:#D8D8D2;
  --hair:rgba(12,12,12,.14);
  --hair-ink:rgba(239,239,236,.16);
  --mute:rgba(12,12,12,.52);
  --mute-ink:rgba(239,239,236,.5);

  --display:"Inter Tight",-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --techno:"Michroma","Inter Tight",sans-serif;

  --pad:clamp(20px,4.2vw,64px);
  --ease:cubic-bezier(.22,1,.36,1);
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* Lenis drives scrolling from rAF and needs this to stay `auto`;
   native smooth-scroll fights it. Anchors go through lenis.scrollTo(). */
html{scroll-behavior:auto;-webkit-text-size-adjust:100%}
body{
  background:var(--bone);color:var(--ink);
  font-family:var(--display);font-size:16px;line-height:1.5;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img,canvas{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
::selection{background:var(--jade);color:var(--ink)}

:focus-visible{outline:2px solid var(--jade);outline-offset:3px;border-radius:2px}

.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--ink);color:var(--bone);
  padding:12px 18px;font:500 13px/1 var(--mono)}
.skip:focus{left:8px;top:8px}

/* ── shared atoms ─────────────────────────── */
.eyebrow{
  font:500 10px/1 var(--mono);letter-spacing:.22em;text-transform:uppercase;
  color:var(--mute);display:inline-flex;align-items:center;gap:8px;
}
.eyebrow--jade{color:var(--jade-ink)}
.eyebrow--violet{color:var(--violet)}
.dot{width:5px;height:5px;border-radius:50%;background:var(--jade);
  box-shadow:0 0 0 0 rgba(46,208,110,.6);animation:pulse 2.4s var(--ease) infinite}
@keyframes pulse{
  0%{box-shadow:0 0 0 0 rgba(46,208,110,.55)}
  70%{box-shadow:0 0 0 7px rgba(46,208,110,0)}
  100%{box-shadow:0 0 0 0 rgba(46,208,110,0)}
}

.num{font-family:var(--techno);font-size:13px;letter-spacing:.06em;color:rgba(12,12,12,.3)}
.num--ink{color:rgba(239,239,236,.34)}

.h2{
  font-family:var(--display);font-weight:600;
  font-size:clamp(34px,5.4vw,74px);line-height:.94;letter-spacing:-.035em;
}
/* SplitText line wrapper — the clip box each character rises out of.
   Needs slack or .94 leading shears the descenders, same as the hero. */
.h2 .sline{overflow:hidden;padding-bottom:.1em;margin-bottom:-.1em}

.panel{position:relative;padding:clamp(72px,10vw,140px) var(--pad)}
.panel--bone{background:var(--bone);color:var(--ink)}
.panel--ink{background:var(--ink);color:var(--bone)}
.panel--ink .eyebrow{color:var(--mute-ink)}

/* Ambient chromatic wash, pulled from the same violet/jade/ember that live in
   the molecules. Painted, never animated: one composite, nothing per frame.
   These ran at .05–.10 alpha, which is below the perceptual threshold over
   bone — it did nothing and the page still read grey. Do not quietly lower
   them again; if the wash is not visible it is not doing its job. */
.panel--bone::before,.panel--ink::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
}
.panel--bone::before{
  background:
    radial-gradient(65% 60% at 88% 6%,rgba(91,47,201,.30),transparent 72%),
    radial-gradient(55% 55% at 3% 94%,rgba(46,208,110,.26),transparent 72%),
    radial-gradient(50% 45% at 42% 102%,rgba(255,95,31,.17),transparent 72%);
}
.panel--ink::before{
  background:
    radial-gradient(60% 55% at 90% 2%,rgba(176,38,255,.34),transparent 74%),
    radial-gradient(55% 50% at 1% 98%,rgba(46,208,110,.22),transparent 74%),
    radial-gradient(45% 40% at 50% 60%,rgba(255,95,31,.10),transparent 74%);
}
.panel > *{position:relative;z-index:1}

/* ═══════════ BLEED RENDERS ═══════════
   The single highest-leverage device on this page. A render sitting inside a
   padded cell reads as decoration; a render that breaks the panel bound and
   passes BEHIND the type reads as art. The reference does this everywhere —
   its molecules occlude their own headlines. These sit at z-index 0, under
   `.panel > *` (z-index 1), so type always wins legibility while the art still
   crosses it. Each bleeds off a DIFFERENT edge so the sections don't rhyme. */
/* A bleeding render must be clipped by its own panel or it widens the document
   and the whole page scrolls sideways. Scoped to the three sections that carry
   one — NOT applied to .panel generally, because #products is GSAP-pinned and
   an overflow container there would break the pin. */
.focus,.about,.contact{overflow:hidden}

.bleed{
  position:absolute;z-index:0;pointer-events:none;height:auto;
  opacity:0;transition:opacity 1.4s var(--ease);
}
.bleed.is-ready{opacity:.92}
.bleed--focus{right:-10%;top:46%;translate:0 -50%;width:min(52vw,660px)}
.bleed--about{right:-10%;top:48%;translate:0 -50%;width:min(42vw,500px);opacity:0;
  animation:drift 14s ease-in-out infinite;
}
.bleed--about.is-ready{opacity:.7}
@keyframes drift{
  0%,100%{transform:translateY(0) rotate(0deg)}
  33%{transform:translateY(-12px) rotate(1.5deg)}
  66%{transform:translateY(8px) rotate(-1deg)}
}
.bleed--contact{left:-6%;bottom:-16%;width:min(30vw,380px)}
.bleed--contact.is-ready{opacity:.85}
/* On narrow screens a bleed render sits under body copy with nowhere to go —
   there is no margin to trespass into. Hide rather than crowd the text. */
@media(max-width:900px){.bleed{display:none}}

/* section header: headline left, note right — from the video */
.secthead{
  display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:clamp(20px,4vw,60px);align-items:start;
  border-top:1px solid var(--hair);padding-top:22px;
  margin-bottom:clamp(40px,6vw,76px);
}
.secthead--ink{border-top-color:var(--hair-ink)}
.secthead .eyebrow{margin-bottom:16px}
.secthead__note{max-width:42ch;font-size:14px;line-height:1.6;color:var(--mute);padding-top:6px}
.secthead--ink .secthead__note{color:var(--mute-ink)}
@media(max-width:760px){.secthead{grid-template-columns:1fr}}

.pill{
  display:inline-flex;align-items:center;gap:10px;
  background:var(--ink);color:var(--bone);
  font:500 11px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  padding:15px 24px;border-radius:100px;
  transition:background .4s var(--ease),color .4s var(--ease),transform .4s var(--ease);
}
.pill:hover{background:var(--jade);color:var(--ink);transform:translateY(-2px)}

/* ═══════════ NAV ═══════════ */
/* No mix-blend-mode here. Blending a fixed element forces the compositor to
   re-blend that strip against everything beneath it on every scroll frame,
   which is a measurable chunk of scroll jank. The colour is swapped by an
   observer instead (.nav--on-ink), which costs nothing. */
.nav{
  position:fixed;inset:0 0 auto;z-index:100;
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:20px var(--pad);
  color:var(--ink);
  transition:transform .5s var(--ease),color .45s var(--ease),
             background .4s var(--ease),backdrop-filter .4s var(--ease);
  will-change:transform;
}
/* Frosted glass — appears after scrolling past hero */
.nav--scrolled{
  background:rgba(239,239,236,.72);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border-bottom:1px solid var(--hair);
}
.nav--scrolled.nav--on-ink{
  background:rgba(12,12,12,.72);
  border-bottom-color:var(--hair-ink);
}
.nav--on-ink{color:var(--bone)}
.nav--on-ink .nav__cta{border-color:rgba(239,239,236,.4)}
.nav--on-ink .nav__cta:hover{border-color:var(--bone)}
.nav--hidden{transform:translateY(-110%)}
.nav__mark{font-family:var(--techno);font-size:13px;letter-spacing:.02em}
.nav__links{display:flex;gap:26px}
.nav__links a,.nav__lang{
  font:400 11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;opacity:.5;
  transition:opacity .3s var(--ease),color .3s var(--ease);
}
.nav__links a:hover,.nav__lang:hover{opacity:1}
/* Active section indicator */
.nav__links a.active{opacity:1;color:var(--jade-ink)}
.nav--on-ink .nav__links a.active{color:var(--jade)}
.nav__end{display:flex;align-items:center;gap:22px}
.nav__cta{
  font:500 11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  border:1px solid rgba(12,12,12,.35);padding:10px 16px;border-radius:100px;
  transition:border-color .3s var(--ease);
}
.nav__cta:hover{border-color:var(--ink)}
@media(max-width:900px){.nav__links,.nav__lang{display:none}}

/* ═══════════ HERO ═══════════ */
.hero{
  min-height:100svh;display:flex;flex-direction:column;
  padding-top:clamp(90px,13vh,130px);padding-bottom:clamp(28px,5vh,48px);
  overflow:hidden;
}
.hero__canvas{
  position:absolute;inset:0;width:100%;height:100%;z-index:1;
  opacity:0;transition:opacity 1.6s ease-out;
}
.hero__canvas.is-live{opacity:1}

/* faint crosshair grid — the video's tick marks */
.hero__grid{position:absolute;inset:0;z-index:0;pointer-events:none}
.hero__grid i{position:absolute;width:9px;height:9px;opacity:.3}
.hero__grid i::before,.hero__grid i::after{
  content:"";position:absolute;background:var(--ink)
}
.hero__grid i::before{left:50%;top:0;width:1px;height:100%;transform:translateX(-50%)}
.hero__grid i::after{top:50%;left:0;height:1px;width:100%;transform:translateY(-50%)}
.hero__grid i:nth-child(1){left:calc(var(--pad) - 4px);top:52%}
.hero__grid i:nth-child(2){right:calc(var(--pad) - 4px);top:52%}
.hero__grid i:nth-child(3){left:50%;top:22%}
.hero__grid i:nth-child(4){right:22%;bottom:26%}

.hero__eyebrow{position:relative;z-index:3;margin-bottom:clamp(18px,3vh,30px)}

.hero__title{
  position:relative;z-index:3;
  font-weight:600;font-size:clamp(46px,9.4vw,148px);line-height:1.05;letter-spacing:-.042em;
  pointer-events:none;
}
/* On narrower screens, cap the title width so it doesn't collide with the molecule.
   On wide screens (1200px+), let the title breathe — the explicit .l spans define
   line breaks so no text reflow happens, and the extra width fills the dead space. */
@media(max-width:1200px){.hero__title{max-width:14ch}}
/* Hero line reveal — pure CSS, runs on compositor (GPU), no JS timing.
   Subtle upward drift + opacity fade, staggered per line. */
@keyframes heroIn{
  from{opacity:0;transform:translateY(14px)}
  to{opacity:1;transform:none}
}
.hero__title .l{
  display:block;
  opacity:0;
  animation:heroIn .9s cubic-bezier(.22,1,.36,1) forwards;
}
.hero__title .l:nth-child(1){animation-delay:.15s}
.hero__title .l:nth-child(2){animation-delay:.3s}
.hero__title .l:nth-child(3){animation-delay:.45s}
.hero__title .l:nth-child(4){animation-delay:.6s}
.hero__title .l>*{display:block}
.period{color:var(--jade)}

.hero__foot{
  position:relative;z-index:3;margin-top:auto;
  display:flex;align-items:flex-end;justify-content:space-between;gap:24px;
}
.hero__blurb{font-size:13px;line-height:1.55;color:var(--mute);max-width:34ch}
.hero__ctas{display:flex;gap:12px;align-items:center;flex-wrap:wrap}
/* the second CTA is production's "Partner With Us" — the actual conversion ask.
   Ghosted so it reads as secondary to Explore Products without disappearing. */
.pill--ghost{background:none;color:var(--ink);border:1px solid rgba(12,12,12,.35)}
.pill--ghost:hover{background:var(--ink);color:var(--bone);border-color:var(--ink)}

/* the KO hero h1 carries <span class="accent"> — production styles it as the
   brand green. Latin h1 has no accent span, so this only ever fires in KO. */
.hero__title .accent{color:var(--jade-ink)}

.foot__tag{font-size:13px;line-height:1.6;color:var(--mute);max-width:38ch;margin:-10px 0 22px}
.hero__scroll{
  position:absolute;left:50%;bottom:18px;transform:translateX(-50%);z-index:3;
  font:400 9px/1 var(--mono);letter-spacing:.3em;text-transform:uppercase;color:var(--mute);
}
.hero__scroll::after{
  content:"";display:block;width:1px;height:26px;background:var(--hair);margin:9px auto 0;
  animation:drop 2.2s var(--ease) infinite;transform-origin:top;
}
@keyframes drop{0%,100%{transform:scaleY(.3);opacity:.3}50%{transform:scaleY(1);opacity:1}}
@media(max-width:640px){
  .hero__foot{flex-direction:column;align-items:flex-start}
  .hero__scroll{display:none}
}

/* ═══════════ WHAT WE DO ═══════════ */
.verticals{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--hair);
  border:1px solid var(--hair)}
.vert{background:var(--bone);padding:clamp(26px,3.4vw,44px);
  transition:background .5s var(--ease)}
.vert:hover{background:#fff}
.vert__t{font-weight:600;font-size:clamp(24px,2.9vw,40px);line-height:1;letter-spacing:-.03em;
  margin:16px 0 18px}
.vert__b{font-size:14px;line-height:1.62;color:var(--mute);max-width:46ch}
@media(max-width:760px){.verticals{grid-template-columns:1fr}}

.flywheel{
  margin-top:clamp(28px,4vw,44px);padding:22px 0;border-top:1px solid var(--hair);
  display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;
  font:400 12px/1.5 var(--mono);color:var(--mute);
}
.flywheel__k{
  font-weight:500;letter-spacing:.16em;text-transform:uppercase;color:var(--ink);
  border:1px solid var(--hair);padding:7px 12px;border-radius:100px;font-size:10px;
}
.flywheel i{color:var(--jade);font-style:normal}

/* Flywheel cycle animation — steps light up sequentially like the loop is running */
@keyframes fwStep{
  0%,18%{opacity:.4;transform:translateY(2px)}
  22%,38%{opacity:1;color:var(--ink);transform:none}
  42%,100%{opacity:.4;transform:translateY(2px)}
}
@keyframes fwArrow{
  0%,18%{opacity:.3;transform:scale(.8)}
  22%,38%{opacity:1;transform:scale(1.3)}
  42%,100%{opacity:.3;transform:scale(.8)}
}
.flywheel span:not(.flywheel__k){
  animation:fwStep 6s var(--ease) infinite;
  transition:opacity .4s var(--ease);
}
.flywheel i{animation:fwArrow 6s var(--ease) infinite}

/* Stagger: 4 steps + 3 arrows across the 6s cycle */
.flywheel span:nth-child(2){animation-delay:0s}
.flywheel i:nth-of-type(1){animation-delay:.15s}
.flywheel span:nth-child(4){animation-delay:1.5s}
.flywheel i:nth-of-type(2){animation-delay:1.65s}
.flywheel span:nth-child(6){animation-delay:3s}
.flywheel i:nth-of-type(3){animation-delay:3.15s}
.flywheel span:nth-child(8){animation-delay:4.5s}

/* ═══════════ RAIL (horizontal scroll) ═══════════ */
.rail{
  display:flex;gap:1px;background:var(--hair);border:1px solid var(--hair);
  overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:none;-ms-overflow-style:none;
}
.rail::-webkit-scrollbar{display:none}
.rail--ink{background:var(--hair-ink);border-color:var(--hair-ink)}
/* While GSAP pins this section it drives scrollLeft itself; leaving the rail's
   own overflow live means two things scrolling one axis. */
.rail--pinned{overflow-x:hidden;scroll-snap-type:none}

/* grow to fill any leftover track, so a short rail never exposes its own
   background as a dead panel; overflow still scrolls when they don't fit */
.card{
  flex:1 0 clamp(240px,25vw,320px);scroll-snap-align:start;
  background:var(--bone);padding:22px;
  display:flex;flex-direction:column;position:relative;isolation:isolate;
  transition:color .45s var(--ease);
}
/* Flood inversion: the card fills with ink from the bottom on hover and the
   type flips out. Wiping a pseudo-element keeps this on the compositor —
   animating background-color would repaint the whole card every frame. */
.card::before{
  content:"";position:absolute;inset:0;z-index:-1;background:var(--ink);
  transform:scaleY(0);transform-origin:bottom;
  transition:transform .55s var(--ease);
}
.card:hover::before{transform:scaleY(1)}
.card:hover{color:var(--bone)}
.card:hover .card__t{color:var(--bone)}
.card:hover .card__b,.card:hover .card__tag{color:var(--mute-ink)}
.card:hover .num{color:rgba(239,239,236,.42)}
.card:hover .card__go{color:var(--jade);border-top-color:var(--hair-ink)}
.card__top{display:flex;justify-content:space-between;align-items:center;margin-bottom:18px}
.card__tag{font:400 9px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--mute)}

/* Real 3D renders, one per product — see thumbs.js. Flat CSS gradients here
   were the cheapest thing on the page and made the whole section read as a
   template. Each render encodes what the tool actually does. */
.card__viz{
  width:100%;height:132px;object-fit:contain;margin-bottom:20px;
  opacity:0;transform:scale(.94);
  transition:opacity .8s var(--ease),transform .8s var(--ease);
}
.card__viz.is-ready{opacity:1;transform:none}
.card:hover .card__viz{transform:scale(1.06) rotate(-1.5deg)}

.card__t{font-weight:600;font-size:clamp(19px,2vw,26px);line-height:1.05;letter-spacing:-.03em;
  margin-bottom:10px}
.card__b{font-size:12.5px;line-height:1.6;color:var(--mute);margin-bottom:22px}
.card__go{
  margin-top:auto;font:500 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  display:inline-flex;gap:8px;align-items:center;
  border-top:1px solid var(--hair);padding-top:16px;
  transition:color .3s var(--ease),gap .3s var(--ease);
}
.card__go:hover{color:var(--jade-ink);gap:13px}

/* The dark section's render. The reference puts big molecular art between its
   numbered panels; without it this section was pure text and read as filler. */
.korea{overflow:hidden}
.korea__viz{
  position:absolute;right:-6%;top:50%;translate:0 -50%;
  width:min(48vw,660px);height:auto;z-index:0;pointer-events:none;
  opacity:0;transition:opacity 1.2s var(--ease);
}
.korea__viz.is-ready{opacity:.9}
@media(max-width:900px){.korea__viz{opacity:0!important}}

/* dark slabs */
.slab{
  flex:1 0 clamp(250px,27vw,340px);scroll-snap-align:start;
  background:var(--ink);padding:24px;
  transition:background .5s var(--ease);
}
.slab:hover{background:var(--ink-2)}
.slab__t{font-weight:600;font-size:clamp(22px,2.5vw,34px);line-height:1;letter-spacing:-.03em;
  margin:26px 0 14px}
.slab__lead{font-size:13px;font-weight:500;margin-bottom:10px;color:var(--bone)}
.slab__b{font-size:12.5px;line-height:1.62;color:var(--mute-ink)}

/* ═══════════ MARQUEE ═══════════
   The methods band. Fills the seam between panels with motion and states
   plainly what the pipeline is built from. Duplicated content + a -50%
   translate is what makes the loop seamless. */
.marquee{
  background:var(--ink);color:var(--bone);
  padding:20px 0;overflow:hidden;position:relative;
  border-top:1px solid var(--hair-ink);border-bottom:1px solid var(--hair-ink);
}
.marquee__track{
  display:flex;align-items:center;gap:26px;width:max-content;
  animation:slide 38s linear infinite;
  will-change:transform;
}
.marquee:hover .marquee__track{animation-play-state:paused}
.marquee__track span{
  font-weight:600;font-size:clamp(20px,2.5vw,34px);letter-spacing:-.03em;
  white-space:nowrap;
}
.marquee__track i{color:var(--jade);font-style:normal;font-size:12px}
@keyframes slide{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* ═══════════ SAGE ═══════════ */
.sage{
  background:var(--sage);min-height:92svh;overflow:hidden;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
}
.sage__canvas{
  position:absolute;inset:0;width:100%;height:100%;z-index:1;
  opacity:0;transition:opacity 1.6s ease-out;
}
.sage__canvas.is-live{opacity:1}
.sage__title{
  position:relative;z-index:3;text-align:center;color:var(--ink);
  font-weight:600;font-size:clamp(34px,7vw,102px);line-height:.92;letter-spacing:-.04em;
  mix-blend-mode:multiply;pointer-events:none;
}
.sage__blurb{
  position:absolute;left:var(--pad);bottom:calc(var(--pad) + 6px);z-index:3;
  font:400 11px/1.6 var(--mono);color:rgba(12,12,12,.62);
}
.tag{
  position:absolute;z-index:3;
  font:500 9px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  background:rgba(239,239,236,.72);backdrop-filter:blur(6px);
  border:1px solid rgba(12,12,12,.1);color:var(--ink);
  padding:8px 13px;border-radius:100px;white-space:nowrap;
  animation:float 7s var(--ease) infinite;
}
.tag--1{right:12%;top:38%;animation-delay:-1s}
.tag--2{left:14%;top:54%;animation-delay:-3.2s}
.tag--3{left:38%;bottom:26%;animation-delay:-5s}
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
@media(max-width:640px){.tag--3{display:none}}

/* ═══════════ ABOUT ═══════════ */
.vm{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--hair);
  border:1px solid var(--hair)}
.vm__c{background:var(--bone);padding:clamp(26px,3.4vw,44px)}
.vm__t{font-weight:500;font-size:clamp(19px,2.2vw,29px);line-height:1.28;letter-spacing:-.025em;
  margin-top:16px;max-width:26ch}
@media(max-width:760px){.vm{grid-template-columns:1fr}}

/* This is the only line on the site about a person rather than a technology,
   and it was set at 14px grey — styled like a disclaimer. It is the reason the
   company has the name it has. Give it the room. */
.name{margin-top:clamp(40px,6vw,72px);border-top:1px solid var(--hair);padding-top:clamp(30px,4vw,48px)}
.name blockquote{
  font-weight:500;font-size:clamp(22px,2.6vw,38px);line-height:1.24;
  letter-spacing:-.028em;max-width:24ch;color:var(--ink);
}
.name strong{color:var(--jade-ink);font-weight:600}
.name em{font-style:normal;color:var(--mute)}
.name__k{
  display:block;font:500 10px/1 var(--mono);letter-spacing:.2em;text-transform:uppercase;
  color:var(--mute);margin-bottom:20px;
}

/* ═══════════ TEAM ═══════════ */
.people{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--hair);
  border:1px solid var(--hair)}
.person{background:var(--bone);padding:clamp(22px,2.6vw,34px);
  transition:background .5s var(--ease)}
.person:hover{background:#fff}
/* Team is the one dead section whose fix is typographic, not molecular — a
   molecule behind a person means nothing. The 46px initial was the only mark
   here and it read as a directory listing, so the names now carry the section
   at near-h2 scale and the initial becomes a quiet index letter. */
.person__i{
  display:block;width:auto;height:auto;background:none;
  color:rgba(12,12,12,.16);
  font-family:var(--techno);font-size:clamp(40px,4vw,58px);line-height:1;
  margin-bottom:14px;
}
.person:hover .person__i{color:var(--jade)}
.person__i{transition:color .5s var(--ease)}
.person__n{
  font-weight:600;font-size:clamp(26px,2.9vw,40px);
  letter-spacing:-.035em;line-height:1;
}
.person__r{font:500 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--jade-ink);margin:12px 0 16px}
.person__a{font-size:12.5px;line-height:1.5;font-weight:500;margin-bottom:14px}
.person__b{font-size:12.5px;line-height:1.62;color:var(--mute);margin-bottom:9px}
@media(max-width:900px){.people{grid-template-columns:1fr}}

/* ═══════════ FAQ ═══════════ */
.qs{border-top:1px solid var(--hair-ink)}
.q{border-bottom:1px solid var(--hair-ink)}
.q summary{
  list-style:none;cursor:pointer;padding:24px 0;
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  font-weight:500;font-size:clamp(16px,1.8vw,23px);letter-spacing:-.02em;
  transition:color .3s var(--ease);
}
.q summary::-webkit-details-marker{display:none}
.q summary:hover{color:var(--jade)}
.q summary i{position:relative;width:12px;height:12px;flex:0 0 12px}
.q summary i::before,.q summary i::after{
  content:"";position:absolute;background:currentColor;transition:transform .4s var(--ease)
}
.q summary i::before{top:50%;left:0;width:100%;height:1px;transform:translateY(-50%)}
.q summary i::after{left:50%;top:0;height:100%;width:1px;transform:translateX(-50%)}
.q[open] summary i::after{transform:translateX(-50%) rotate(90deg)}
.q[open] summary{color:var(--jade)}
.q p{padding:0 0 26px;max-width:74ch;font-size:14px;line-height:1.65;color:var(--mute-ink)}
.q a{color:var(--jade);text-decoration:underline;text-underline-offset:3px}

/* ═══════════ CONTACT ═══════════ */
.cwrap{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--hair);
  border:1px solid var(--hair)}
.cinfo,.cform{background:var(--bone);padding:clamp(26px,3.4vw,44px)}
.cmail{
  display:inline-block;font-weight:600;letter-spacing:-.035em;line-height:1;
  font-size:clamp(24px,3.4vw,46px);
  background-image:linear-gradient(var(--jade),var(--jade));
  background-size:0% 2px;background-repeat:no-repeat;background-position:0 100%;
  transition:background-size .5s var(--ease);
}
.cmail:hover{background-size:100% 2px}
.cloc{font-size:13px;line-height:1.62;color:var(--mute);margin:22px 0 20px}
.clink{
  display:inline-flex;gap:8px;font:500 10px/1 var(--mono);letter-spacing:.16em;
  text-transform:uppercase;border:1px solid var(--hair);padding:11px 17px;border-radius:100px;
  transition:border-color .3s var(--ease),color .3s var(--ease);
}
.clink:hover{border-color:var(--jade);color:var(--jade-ink)}
.cnote{font-size:12.5px;line-height:1.62;color:var(--mute);margin-top:24px;
  border-top:1px solid var(--hair);padding-top:20px;max-width:48ch}

.cform{display:flex;flex-direction:column;gap:16px}
.cform[hidden]{display:none!important}
.cform label{
  display:flex;flex-direction:column;gap:8px;
  font:500 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--mute)
}
.cform input,.cform textarea{
  font:400 14px/1.5 var(--display);color:var(--ink);
  background:transparent;border:0;border-bottom:1px solid var(--hair);
  padding:11px 0;resize:vertical;transition:border-color .3s var(--ease);
}
.cform input:focus,.cform textarea:focus{outline:0;border-bottom-color:var(--jade)}
.cform button{
  align-self:flex-start;margin-top:8px;cursor:pointer;border:0;
  background:var(--ink);color:var(--bone);
  font:500 11px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  padding:16px 26px;border-radius:100px;
  transition:background .4s var(--ease),color .4s var(--ease),transform .4s var(--ease);
}
.cform button:hover{background:var(--jade);color:var(--ink);transform:translateY(-2px)}
.cform__status,.sub__status{font:400 11px/1.4 var(--mono);color:var(--jade-ink);min-height:14px}

/* honeypot: must be reachable by a bot parsing the DOM but never by a human or
   a screen reader. display:none would let smarter bots skip it. */
.honey{position:absolute;left:-9999px;width:1px;height:1px;opacity:0;pointer-events:none}

/* success state — a sibling of the form, not a replacement for it */
.csent[hidden]{display:none!important}
.csent:not([hidden]){
  display:flex;flex-direction:column;justify-content:center;
  background:var(--bone);padding:clamp(26px,3.4vw,44px);
  border-left:2px solid var(--jade);
}
.csent:focus{outline:none}
.csent__t{font-weight:600;font-size:clamp(20px,2.2vw,28px);letter-spacing:-.03em;
  line-height:1.15;color:var(--jade-ink)}
.csent__b{font-size:13px;color:var(--mute);margin-top:10px}

/* the language toggle is a <button> now (it performs an action, it is not a link) */
.nav__lang{
  background:none;border:0;cursor:pointer;color:inherit;
  font:400 11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  opacity:.7;padding:6px 2px;transition:opacity .3s var(--ease);
}
.nav__lang:hover{opacity:1}
@media(max-width:900px){.nav__lang{display:inline-block;opacity:1}}

/* Korean needs a face that actually has the glyphs; Inter Tight does not.
   The stack falls back to the system Korean fonts rather than shipping a
   webfont — matching what production already does. */
html[lang="ko"] body,
html[lang="ko"] .h2,
html[lang="ko"] .hero__title,
html[lang="ko"] .vert__t,
html[lang="ko"] .card__t,
html[lang="ko"] .slab__t,
html[lang="ko"] .person__n{
  font-family:"Inter Tight",-apple-system,BlinkMacSystemFont,"Apple SD Gothic Neo",
    "Noto Sans KR","Malgun Gothic","맑은 고딕",sans-serif;
}
/* Korean has no ascender/descender drama and does not tolerate the tight tracking
   the Latin display face is set at — it collapses the counters. */
html[lang="ko"] .h2,
html[lang="ko"] .hero__title{letter-spacing:-.01em;line-height:1.12}
html[lang="ko"] .hero__title{font-size:clamp(40px,9.4vw,148px)}
@media(max-width:860px){.cwrap{grid-template-columns:1fr}}

/* ═══════════ FOOTER ═══════════ */
.foot{background:var(--bone-2);color:var(--ink);padding:clamp(48px,6vw,72px) var(--pad) 22px;
  overflow:hidden}
.foot__top{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);
  gap:clamp(28px,5vw,64px);align-items:start;
  border-top:1px solid var(--hair);padding-top:30px;
}
.foot__t{font-weight:600;font-size:clamp(20px,2.4vw,32px);line-height:1.08;letter-spacing:-.03em;
  margin-bottom:22px}
.sub{display:flex;gap:10px;max-width:400px}
.sub input{
  flex:1;min-width:0;font:400 13px/1 var(--display);
  background:transparent;border:0;border-bottom:1px solid var(--hair);padding:12px 0;
  transition:border-color .3s var(--ease);
}
.sub input:focus{outline:0;border-bottom-color:var(--jade)}
.sub button{
  cursor:pointer;border:0;background:var(--ink);color:var(--bone);
  font:500 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  padding:13px 20px;border-radius:100px;white-space:nowrap;
  transition:background .4s var(--ease),color .4s var(--ease);
}
.sub button:hover{background:var(--jade);color:var(--ink)}
.sub__status{margin-top:10px}

.foot__cols{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
.foot__cols div{display:flex;flex-direction:column;gap:11px}
.foot__cols h4{
  font:500 10px/1 var(--mono);letter-spacing:.2em;text-transform:uppercase;
  color:var(--mute);margin-bottom:5px;font-weight:500;
}
.foot__cols a,.foot__cols span{font-size:13px;color:var(--ink);opacity:.78;
  transition:opacity .3s var(--ease),color .3s var(--ease)}
.foot__cols a:hover{opacity:1;color:var(--jade-ink)}
@media(max-width:860px){
  .foot__top{grid-template-columns:1fr}
  .foot__cols{grid-template-columns:1fr 1fr}
}

/* The signature: giant wordmark spanning the full measure.
   "RATANBIO" in Michroma at -.02em tracking measures 7.2536em, so the size is
   derived from the real available width — a plain vw value only holds at one
   viewport, because --pad is clamped and stops scaling with vw. The 7.4
   divisor leaves ~2% slack for platforms whose 100vw includes the scrollbar. */
.wordmark{
  font-family:var(--techno);
  font-size:calc((100vw - 2 * var(--pad)) / 7.4);
  line-height:.8;letter-spacing:-.02em;
  margin:clamp(40px,6vw,80px) 0 0;
  text-align:center;white-space:nowrap;
  color:var(--ink);
  user-select:none;
}

.foot__legal{
  display:flex;flex-wrap:wrap;justify-content:space-between;gap:10px 24px;
  border-top:1px solid var(--hair);margin-top:26px;padding-top:18px;
  font:400 10px/1.4 var(--mono);letter-spacing:.06em;color:var(--mute);
}

/* ═══════════ scroll reveal ═══════════ */
.reveal{opacity:0;transform:translateY(22px);
  transition:opacity .9s var(--ease),transform .9s var(--ease)}
.reveal.in{opacity:1;transform:none}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;
  }
  .reveal{opacity:1;transform:none}
  .hero__title .l{opacity:1;transform:none}
}


/* ═══════════ THE PATH TO 2029 (data section) ═══════════ */
/* ═══════════════════════════════════════════
   ENGINE — "The Path to 2029"
   Evidence bento (what is true today) + roadmap (what is not true yet).

   The section's whole grammar is one binary, stated three ways so it never
   depends on colour alone:
     LIVE    filled ink figure · solid jade mark · the word "Live"
     TARGET  outlined figure   · hollow dashed mark · the word "Target"
   No fabricated series, no fabricated scale. The only chart here is a unit
   chart of five real products; everything else is a stat tile, which is the
   correct form when the data is this sparse.
   ═══════════════════════════════════════════ */

:root{
  /* Brand jade fails contrast as TEXT on bone: #2ED06E on #EFEFEC is 1.76:1.
     Rather than muting the brand token globally (which is how #1b8d4b got
     scattered through this file), this is ONE darkened instance, used only for
     type and marks sitting on a light panel. Full-strength var(--jade) is kept
     for everything on ink, where it measures 9.65:1. */
  --jade-ink:#0F7440;   /* 5.07:1 on --bone */
}

.engine{overflow:hidden}

/* ── header ───────────────────────────────────
   Deliberately NOT .secthead. Every other section on the page is
   headline-left / note-right; this one stacks full-measure and drops the
   note + legend beneath a second hairline, so the eye doesn't land where it
   landed in the last six sections. */
.engine__head{
  border-top:1px solid var(--hair);padding-top:22px;
  margin-bottom:clamp(30px,4vw,54px);
}
.engine__eyebrow{color:var(--jade-ink);margin-bottom:18px}
.engine__h2{
  font-size:clamp(40px,7.4vw,104px);
  margin-bottom:clamp(24px,3vw,40px);
}
.engine__meta{
  display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:clamp(16px,3vw,48px);align-items:end;
  border-top:1px solid var(--hair);padding-top:20px;
}
.engine__note{max-width:62ch;font-size:14px;line-height:1.6;color:var(--mute)}
@media(max-width:760px){.engine__meta{grid-template-columns:1fr;align-items:start}}

/* legend — two states, so it is always present */
.key{list-style:none;display:flex;flex-wrap:wrap;gap:10px 22px}
.key__i{
  display:inline-flex;align-items:center;gap:9px;white-space:nowrap;
  font:500 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--mute);
}
.key__m{width:11px;height:11px;flex:0 0 11px;border-radius:2px}
.key__m--live{background:var(--jade-ink)}
.key__m--target{border:1.5px dashed rgba(12,12,12,.5)}

/* ── the block ────────────────────────────────
   One hairline-gridded slab, bone on the left and ink on the right, running
   off the right edge of the viewport. The negative margin only eats the
   panel's own padding, so nothing overflows. */
.engine__grid{
  display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:1px;background:var(--hair);border:1px solid var(--hair);
}
@media(min-width:1001px){
  .engine__grid{margin-right:calc(var(--pad) * -1);border-right:0}
}
@media(max-width:1000px){.engine__grid{grid-template-columns:1fr}}

/* ── bento ────────────────────────────────────
   2x2, but never four equal beige boxes: the columns are 1.25fr/1fr, the lead
   figure is ~2.7x the others, and the bottom-left cell is ink. */
.bento{
  display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);
  gap:1px;background:var(--hair);
}
.tile{
  --tp:clamp(22px,2.6vw,38px);
  background:var(--bone);padding:var(--tp);
  display:flex;flex-direction:column;gap:clamp(20px,2.6vw,34px);
  transition:background .5s var(--ease);
}
.tile:hover{background:#fff}
.tile__k{
  font:500 10px/1 var(--mono);letter-spacing:.2em;text-transform:uppercase;color:var(--mute);
}
.tile__t{font-weight:600;font-size:clamp(17px,1.6vw,22px);line-height:1.15;letter-spacing:-.028em}
.tile__b{font-size:12.5px;line-height:1.62;color:var(--mute);max-width:40ch}
/* tighten the label→figure→title cluster; the flex gap is for the big joints */
.tile__k + .fig{margin-top:calc(clamp(20px,2.6vw,34px) * -.4)}
.fig + .tile__t{margin-top:calc(clamp(20px,2.6vw,34px) * -.55)}
.tile__t + .tile__b{margin-top:calc(clamp(20px,2.6vw,34px) * -.62)}
@media(max-width:760px){.bento{grid-template-columns:1fr}}

/* ── the figure tier ──────────────────────────
   Michroma. README:58 designates it the numeral face and until now it never
   set a numeral that mattered. Proportional figures — tabular would make a
   standalone "50" look loose at this size. */
.fig{
  font-family:var(--techno);font-weight:400;
  font-size:clamp(60px,10vw,164px);line-height:.86;letter-spacing:.005em;
  color:var(--ink);font-variant-numeric:proportional-nums;
}
.fig--sm{font-size:clamp(34px,4.2vw,60px);line-height:.9}
/* ₩ is not in Michroma's charset — set it and the unit in the display face on
   purpose rather than letting the fallback pick for us. */
.fig__p,.fig__u{font-family:var(--display);font-weight:600;font-size:.6em;letter-spacing:-.02em}
.fig__p{margin-right:.18em}
.fig__u{margin-left:.04em}

/* TARGET figures are hollow. This is the load-bearing honesty mark: a target
   can never be mistaken for an achievement, at any glance speed, in greyscale,
   or with colour vision deficiency. */
.fig--target{color:var(--mute-ink)}
@supports (-webkit-text-stroke:1px #000){
  .fig--target{color:transparent;-webkit-text-stroke:1.6px var(--bone)}
}

/* ── unit chart ───────────────────────────────
   Five real products as five marks, grouped by domain. Identity is carried by
   grouping and by the printed count, never by hue — so all five marks stay one
   colour and jade means exactly one thing in this section: live.
   The cell is ink because jade on bone is 1.7:1 and jade on ink is 9.3:1;
   it also stops the bento reading as four equal beige boxes. */
.tile--units{background:var(--ink);color:var(--bone)}
.tile--units:hover{background:var(--ink)}
.tile--units .tile__k,.tile--units .tile__b{color:var(--mute-ink)}
.units__g{display:flex;flex-direction:column;gap:14px;margin:auto 0}
.units__d{display:flex;align-items:center;gap:16px}
.units__row{display:flex;gap:4px;flex:0 0 auto;min-width:40px}  /* gap is the ink surface, not a border */
.u{display:block;width:18px;height:18px;border-radius:2px;background:var(--jade)}
.units__l{
  flex:1;display:flex;justify-content:space-between;align-items:baseline;gap:12px;
  border-bottom:1px solid var(--hair-ink);padding-bottom:5px;
  font:500 10px/1.4 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--mute-ink);
}
.units__l b{color:var(--bone);font-weight:500}

/* ── road ─────────────────────────────────────
   A timeline, not a bar chart. "5 products / 50 hospitals / 2 therapeutics"
   are three different units — putting them on one bar scale would invent a
   comparison that does not exist. */
.road{
  background:var(--ink);color:var(--bone);
  padding:clamp(26px,3vw,44px) clamp(22px,3vw,44px) clamp(30px,4vw,54px);
}
.road__k{
  font:500 10px/1 var(--mono);letter-spacing:.22em;text-transform:uppercase;
  color:var(--mute-ink);margin-bottom:clamp(24px,3vw,36px);
}
.road__l{list-style:none}
.stop{position:relative;padding:0 0 clamp(30px,3.4vw,44px) clamp(28px,2.6vw,38px)}
.stop:last-child{padding-bottom:0}
/* the track is dashed for its whole length: everything below the first node
   is a plan, and dashing is the one place where "projection" is the honest
   read rather than noise. */
.stop::before{
  content:"";position:absolute;left:5px;top:24px;bottom:0;
  border-left:1px dashed rgba(239,239,236,.42);  /* 3.67:1 on ink */
}
.stop:last-child::before{content:none}
.stop__n{
  position:absolute;left:0;top:9px;width:11px;height:11px;border-radius:50%;
  box-sizing:border-box;
}
.stop--live .stop__n{background:var(--jade)}
.stop--target .stop__n{border:1.5px dashed rgba(239,239,236,.6)}

.stop__d{
  display:flex;flex-wrap:wrap;align-items:center;gap:10px;
  font:500 10px/1 var(--mono);letter-spacing:.2em;text-transform:uppercase;
  color:var(--bone);margin-bottom:14px;padding-top:4px;
}
.stop__s{
  font-weight:500;letter-spacing:.16em;padding:4px 9px;border-radius:100px;
  border:1px dashed rgba(239,239,236,.4);color:var(--mute-ink);
}
.stop__s--live{background:var(--jade);border:1px solid var(--jade);color:var(--ink)}
.stop__t{
  font-weight:600;font-size:clamp(19px,1.9vw,26px);line-height:1.12;letter-spacing:-.028em;
  margin-bottom:10px;
}
.stop__b{font-size:12.5px;line-height:1.62;color:var(--mute-ink);max-width:46ch}

/* the 2029 pair — mono TARGET label locked above each figure, never beside it
   and never below it, so a skimmer reads the caveat before the number. */
.aims{
  display:grid;grid-template-columns:1fr 1fr;gap:1px;
  background:var(--hair-ink);border:1px solid var(--hair-ink);
  margin:20px 0 18px;
}
.aim{background:var(--ink);padding:clamp(16px,1.8vw,22px)}
.aim__k{
  font:500 9px/1 var(--mono);letter-spacing:.18em;text-transform:uppercase;
  color:var(--bone);margin-bottom:14px;
}
.aim__l{font-size:12px;line-height:1.5;color:var(--mute-ink);margin-top:14px}
@media(max-width:420px){.aims{grid-template-columns:1fr}}

@media(prefers-reduced-motion:reduce){
  .tile{transition:none}
}

/* Print: browsers drop background colours, so the ink slab goes white and a
   bone-stroked target numeral disappears — taking the live/target distinction
   with it. Investors print decks. */
@media print{
  .road{background:none;color:var(--ink)}
  .fig--target{-webkit-text-stroke-color:var(--ink)}
  .stop__s--live{border:1px solid var(--ink);background:none;color:var(--ink)}
  .panel--bone::before,.panel--ink::before{display:none}
}
