/* ==========================================================================
   Vively — brand story page.
   New file (not a revision of an existing one) so no cached stylesheet can
   mask these rules. Loaded after style.work.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   3D text ribbon — one continuous band made entirely of the copy itself.

   Every character is its own element, placed at its true angular position on
   a cylinder (JS measures each glyph and converts cumulative width to
   degrees), so the text wraps the band edge-to-edge with no gaps and no
   repeated "slots". The radius is derived from the total string width, which
   is what keeps letter spacing identical at every viewport size.

   Depth: each glyph runs the same one-revolution opacity cycle as the band,
   offset by a delay proportional to its own angle — so the fade tracks the
   glyph's real position in world space with zero per-frame JavaScript.

   Motion blur: a second, blurred copy of the band spins a fraction of a
   second behind the first, leaving a soft trailing smear. Desktop only.
   -------------------------------------------------------------------------- */
.ribbon-banner{
  background:#0d0d0c; color:#fff; overflow:hidden;
  padding:64px 0 78px; text-align:center;
}
.ribbon-banner .ribbon-kicker{
  font-size:12px; font-weight:700; letter-spacing:.16em; text-transform:uppercase;
  color:rgba(255,255,255,.45);
}
.ribbon-banner h2{ margin-top:12px; font-size:clamp(26px,3.6vw,42px); color:#fff; }

.ribbon-stage{
  --fs:30px;        /* glyph size — radius is derived from this */
  --r:320px;        /* set by JS from the measured string width */
  --spin:30s;
  --tilt:-19deg;
  position:relative; margin-top:30px; height:330px;
  perspective:1000px; perspective-origin:50% 50%;
  display:flex; align-items:center; justify-content:center;
}
/* let the band melt into the background at the silhouette edges */
.ribbon-stage::before, .ribbon-stage::after{
  content:""; position:absolute; top:0; bottom:0; width:16%; z-index:2; pointer-events:none;
}
.ribbon-stage::before{ left:0;  background:linear-gradient(90deg,#0d0d0c,transparent); }
.ribbon-stage::after{  right:0; background:linear-gradient(270deg,#0d0d0c,transparent); }

.ribbon-tilt{ transform:rotateX(var(--tilt)); transform-style:preserve-3d; }

/* One row = one band of the ribbon. The row carries the vertical offset and
   the staggered start angle; the child carries the spin, because the spin
   animation writes `transform` and would otherwise overwrite them. */
.ribbon-row{
  position:absolute; left:0; top:0; width:0; height:0;
  transform-style:preserve-3d;
  transform:translateY(calc(var(--fs) * var(--ym))) rotateY(var(--rot));
}
.ribbon{
  position:absolute; left:0; top:0; width:0; height:0;
  transform-style:preserve-3d;
  animation:ribbonSpin var(--spin) linear infinite;
}
.ribbon .rc{
  position:absolute; left:0; top:0;
  transform:translate(-50%,-50%) rotateY(calc(var(--a) * 1deg)) translateZ(var(--r));
  font-size:var(--fs); font-weight:800; line-height:1; letter-spacing:0;
  white-space:pre; color:#fff;
  animation:rcDepth var(--spin) linear infinite;
  /* phase the fade to this glyph's own angle */
  animation-delay:calc((var(--a) / 360) * var(--spin) - var(--spin));
}
@keyframes ribbonSpin{ from{ transform:rotateY(0deg); } to{ transform:rotateY(-360deg); } }
@keyframes rcDepth{
  0%   { opacity:1; }     /* nearest the viewer */
  50%  { opacity:.26; }   /* far side of the band */
  100% { opacity:1; }
}

/* Trailing smear, on the middle band only. The blur lives on the glyphs
   rather than the container because a filter on a preserve-3d ancestor
   would flatten the whole cylinder. Desktop only — 3 bands is already a
   few hundred composited glyphs on mobile. */
.ribbon-row.ghost .ribbon{ animation-delay:-.055s; }
.ribbon-row.ghost .rc{ filter:blur(5px); opacity:.3; animation:none; }
@media (max-width:900px){ .ribbon-row.ghost{ display:none; } }

@media (max-width:900px){
  .ribbon-stage{ --fs:19px; height:240px; perspective:760px; }
}
@media (max-width:560px){
  .ribbon-stage{ --fs:14px; height:190px; perspective:560px; }
}
@media (prefers-reduced-motion: reduce){
  .ribbon{ animation:none; }
  .ribbon .rc{ animation:none; opacity:1; }
  .ribbon.ghost{ display:none; }
}

.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* --------------------------------------------------------------------------
   Office triptych — bigger frames, tighter gutters, caption under each
   -------------------------------------------------------------------------- */
.tri{ display:grid; grid-template-columns:repeat(3,1fr); gap:20px; }
.tri figure{ margin:0; }
.tri img{
  width:100%; height:auto; aspect-ratio:4/3; object-fit:cover; object-position:50% 45%;
  border-radius:4px; display:block;
}
.tri figcaption{ margin-top:16px; }
.tri figcaption .t{ display:block; font-size:15px; font-weight:800; letter-spacing:-.01em; }
.tri figcaption .d{ display:block; margin-top:7px; font-size:13.5px; color:var(--ink-50); line-height:1.6; }
@media (max-width:760px){ .tri{ grid-template-columns:1fr; gap:34px; } }

/* --------------------------------------------------------------------------
   Market-shift block — Kakao style: no cards, big type, plenty of air
   -------------------------------------------------------------------------- */
.kk-title{ max-width:none; }
@media (min-width:900px){ .kk-title{ white-space:nowrap; } }
.kk-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:56px 48px; }
.kk-item{ border-top:1px solid var(--line); padding-top:26px; }
.kk-item .lab{
  font-size:12px; font-weight:800; letter-spacing:.04em; color:var(--ink-30);
  display:block; margin-bottom:16px;
}
.kk-item h3{ font-size:clamp(19px,2vw,23px); line-height:1.35; margin-bottom:16px; }
.kk-item p{ font-size:14.5px; line-height:1.8; color:var(--ink-70); }
.kk-item .src{ margin-top:18px; font-size:12px; color:var(--ink-30); line-height:1.6; }
@media (max-width:980px){ .kk-grid{ grid-template-columns:1fr 1fr; gap:44px 36px; } }
@media (max-width:620px){ .kk-grid{ grid-template-columns:1fr; gap:38px; } }

/* --------------------------------------------------------------------------
   Founders carousel — dark stage, active card scaled up.
   The active card is enlarged with a transform rather than resized, so its
   layout box never changes and the track's centring maths stays exact.
   The stage's vertical padding is what the scaled card overflows into,
   so overflow:hidden clips the sides without cropping the active card.
   -------------------------------------------------------------------------- */
.founders-dark{ background:#0d0d0c; color:#fff; padding:104px 0 92px; overflow:hidden; }
.founders-dark .kicker{ color:rgba(255,255,255,.45); }
.founders-dark h2{ color:#fff; font-size:clamp(30px,4.4vw,52px); }
.f-stage{ margin-top:16px; padding:58px 0; overflow:hidden; }
.f-track{
  display:flex; gap:56px; align-items:center;
  transition:transform .65s var(--ease); will-change:transform;
}
.f-card{
  flex:0 0 260px; width:260px; padding:0; border:0; background:none;
  text-align:left; cursor:pointer; color:#fff; font-family:inherit;
  opacity:.3; filter:grayscale(1);
  transform:scale(1); transform-origin:center center;
  transition:opacity .55s var(--ease), filter .55s var(--ease), transform .55s var(--ease);
}
.f-card img{
  width:100%; aspect-ratio:1/1; object-fit:cover; border-radius:4px; display:block;
  background:#1a1a18;
}
.f-card .nm{ display:block; margin-top:16px; font-size:17px; font-weight:800; }
.f-card .rl{ display:block; margin-top:5px; font-size:12.5px; color:rgba(255,255,255,.55); }
.f-card.active{ opacity:1; filter:none; transform:scale(1.26); }
/* counter-scale the labels so type size stays constant while the photo grows */
.f-card.active .nm, .f-card.active .rl{ transform:scale(.79); transform-origin:left top; }

.f-nav{ display:flex; align-items:center; justify-content:center; gap:18px; margin-top:26px; }
.f-nav button{
  width:38px; height:38px; border-radius:50%; background:none; color:#fff;
  border:1px solid rgba(255,255,255,.25); display:flex; align-items:center; justify-content:center;
  font-size:15px; transition:background .3s, color .3s, border-color .3s;
}
.f-nav button:hover{ background:#fff; color:#0d0d0c; border-color:#fff; }
.f-count{ font-size:13px; font-weight:800; letter-spacing:.08em; color:rgba(255,255,255,.65); }
.f-count b{ color:#fff; }
.f-story{ max-width:720px; margin:40px auto 0; text-align:center; min-height:104px; }
.f-story p{ font-size:15px; line-height:1.85; color:rgba(255,255,255,.72); }
@media (max-width:760px){
  .f-track{ gap:38px; }
  .f-card{ flex-basis:190px; width:190px; }
  .f-card.active{ transform:scale(1.14); }
  .f-card.active .nm, .f-card.active .rl{ transform:scale(.88); }
  .f-stage{ padding:34px 0; }
}

/* counting numbers on the stats strip */
.stat b[data-count]{ font-variant-numeric:tabular-nums; }
