/* TEST landing page (index-test.html) — standalone; doesn't use landing.css.
   Look: white page, Helvetica (caps for display), hairline rules, pill-shaped
   buttons/tags, a fixed footer bar; the selected-works list stacks huge names that
   turn a pastel colour (with the project's film) on hover. */

@font-face { font-family: "PretendardL"; src: url("../fonts/Pretendard-Light.otf") format("opentype"); font-weight: 300; font-display: swap; }
@font-face { font-family: "PretendardL"; src: url("../fonts/Pretendard-Regular.otf") format("opentype"); font-weight: 400; font-display: swap; }
@font-face { font-family: "PretendardL"; src: url("../fonts/Pretendard-Medium.otf") format("opentype"); font-weight: 500; font-display: swap; }

:root {
  --bg: #fff;
  --ink: #111;
  --sky: #c9def3;           /* landing background */
  --pink: #f7b9cb;          /* name pill */
  --mute: #6b6b6b;
  --line: 1px solid var(--ink);
  --gutter: clamp(20px, 3.2vw, 60px);
  --ease: cubic-bezier(.2,.7,.1,1);
  /* everything is set in Helvetica; Korean falls back to Pretendard */
  --wide: "Helvetica Neue", Helvetica, Arial, "PretendardL", sans-serif;
  --foot-h: 26px;
}

* { box-sizing: border-box; }
/* the page snaps from slide to slide; a slide taller than the screen (the works
   list) scrolls freely inside before snapping on to the next one */
html { scroll-behavior: smooth; scroll-snap-type: y mandatory; }
.tl-hero, .tl-slide { scroll-snap-align: start; scroll-snap-stop: always; }
html, body { margin: 0; padding: 0; }
body.tl {
  background: var(--sky); color: var(--ink);   /* blended between the sections' colours by js (data-bg) */
  font-family: var(--wide); font-weight: 400;
  -webkit-font-smoothing: antialiased; overflow-x: hidden;
  padding-bottom: var(--foot-h);
}
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
img, video { display: block; max-width: 100%; }
[hidden] { display: none !important; }   /* e.g. Instagram / LinkedIn pills with no link yet */
sup { font-size: .55em; vertical-align: .62em; line-height: 0; margin-left: .02em; }


/* ---------------- pills ---------------- */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 12px; border: var(--line); border-radius: 999px; background: var(--bg);
  font-size: 15px; font-weight: 400; text-transform: uppercase; letter-spacing: -.005em; white-space: nowrap;
  transition: background .2s, color .2s;
}
a.pill:hover { background: var(--ink); color: var(--bg); }
.pill--name { background: var(--pink); font-size: 17px; height: 34px; padding: 0 14px; }
a.pill--name:hover { background: var(--ink); color: var(--pink); }
/* landing page: the name pill shows up only after the intro (js toggles .past-intro) */
body.tl:not(.tl-detail) .tl-head .pill--name { opacity: 0; transform: translateY(-6px); pointer-events: none; transition: opacity .35s ease, transform .35s var(--ease), background .2s, color .2s; }
body.tl.past-intro .tl-head .pill--name { opacity: 1; transform: none; pointer-events: auto; }
.pill--static { height: 26px; font-size: 12px; padding: 0 10px; }
/* phone menu: a round pill with three lines (hidden on wide screens, where the
   section pills show); the lines turn into an × while the menu is open */
.tl-menu-btn { display: none; width: 34px; height: 34px; padding: 0; flex-direction: column; justify-content: center; align-items: center; gap: 4px; }
.tl-menu-btn i { display: block; width: 14px; height: 1.5px; background: currentColor; transition: transform .3s var(--ease), opacity .2s; }
.menu-open .tl-menu-btn { background: var(--ink); color: var(--bg); }
.menu-open .tl-menu-btn i:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.menu-open .tl-menu-btn i:nth-child(2) { opacity: 0; }
.menu-open .tl-menu-btn i:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }
.tl-menu {
  position: fixed; inset: 0; z-index: 39; display: flex; flex-direction: column; justify-content: center;
  padding: 80px var(--gutter) 60px; background: var(--pink);
  opacity: 0; visibility: hidden; transition: opacity .3s ease, visibility 0s linear .3s;
}
.menu-open .tl-menu { opacity: 1; visibility: visible; transition: opacity .3s ease; }
.tl-menu a {
  display: flex; align-items: baseline; gap: 14px; padding: 10px 0 12px; border-top: var(--line);
  font-size: clamp(44px, 13vw, 96px); line-height: 1; letter-spacing: -.035em; text-transform: uppercase;
  transform: translateY(16px); transition: transform .45s var(--ease);
}
.tl-menu a:last-child { border-bottom: var(--line); }
.menu-open .tl-menu a { transform: none; }
.tl-menu-no { font-size: 13px; letter-spacing: 0; }
.menu-open { overflow: hidden; }
.small-pill {
  display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border: var(--line); border-radius: 999px;
  font-family: var(--wide); font-size: 11.5px; font-weight: 400; letter-spacing: 0; text-transform: none; white-space: nowrap;
  background: var(--bg);
}

/* ---------------- header / footer ---------------- */
.tl-head {
  position: fixed; inset: 0 0 auto 0; z-index: 40;
  display: flex; justify-content: space-between; align-items: center; padding: 10px var(--gutter);
  pointer-events: none;
}
.tl-head > * { pointer-events: auto; }
.tl-head-right { display: flex; gap: 6px; }
.tl-foot {
  position: fixed; inset: auto 0 0 0; z-index: 40; height: var(--foot-h);
  display: flex; justify-content: space-between; align-items: center; padding: 0 var(--gutter);
  background: var(--bg); border-top: var(--line);
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .01em;
}
.tl-foot a:hover { text-decoration: underline; }

/* ---------------- 01. intro ---------------- */
.tl-hero {
  position: relative; min-height: calc(100svh - var(--foot-h));
  padding: 64px var(--gutter) clamp(28px, 5vh, 60px); display: flex; flex-direction: column;
}
/* grainy gradient laid across the intro / second-slide boundary (top and height set
   by js), behind the content, scrolling with the page: soft white and pastel light
   rolling like waves, faded out at both ends, with a fine moving film grain on top */
main { position: relative; }
.tl-glow {
  position: absolute; left: 0; top: 0; z-index: 0; width: 100%; height: 70vh; pointer-events: none; overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 50%, #000 72%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 50%, #000 72%, transparent 100%);
}
/* two layers of light rolling past each other like waves: each sweeps sideways while
   rising and sinking, at different speeds, so the crests keep breaking differently */
.tl-glow i { position: absolute; inset: 0 -30%; will-change: transform; }
.tl-glow i:nth-child(1) {
  background:
    radial-gradient(30% 44% at 20% 70%, rgba(255,255,255,.95), transparent 72%),
    radial-gradient(26% 38% at 52% 64%, rgba(247,185,203,.75), transparent 70%),
    radial-gradient(30% 44% at 82% 72%, rgba(255,255,255,.9), transparent 72%);
  animation: tl-wave-a 3.2s ease-in-out infinite alternate;
}
.tl-glow i:nth-child(2) {
  background:
    radial-gradient(34% 40% at 35% 78%, rgba(185,166,242,.6), transparent 70%),
    radial-gradient(28% 36% at 68% 74%, rgba(255,255,255,.8), transparent 72%),
    radial-gradient(30% 40% at 95% 66%, rgba(247,185,203,.55), transparent 70%);
  animation: tl-wave-b 2.6s ease-in-out infinite alternate;
}
.tl-glow::after {
  content: ""; position: absolute; inset: -50%; opacity: .55; mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1.4 -.2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: tl-grain .8s steps(6) infinite;
}
@keyframes tl-wave-a {
  0%   { transform: translate(-12%, 6%) scale(1, .9); }
  50%  { transform: translate(-2%, -8%) scale(1.06, 1.15); }
  100% { transform: translate(10%, 4%) scale(1, .95); }
}
@keyframes tl-wave-b {
  0%   { transform: translate(12%, -4%) scale(1.04, 1.1); }
  50%  { transform: translate(2%, 9%) scale(.96, .88); }
  100% { transform: translate(-10%, -6%) scale(1.05, 1.12); }
}
@keyframes tl-grain {
  0% { transform: translate(0, 0); } 20% { transform: translate(-8%, 6%); } 40% { transform: translate(6%, -10%); }
  60% { transform: translate(-12%, -4%); } 80% { transform: translate(10%, 8%); } 100% { transform: translate(0, 0); }
}
.tl-hero > *, .tl-achieve > * { position: relative; z-index: 1; }
/* the introduction fills the left three quarters of the screen (full width on phones) */
.tl-hero-text {
  margin: 0; max-width: 75%; text-align: left;
  font-family: var(--wide); font-weight: 400;
  font-size: clamp(32px, 2.6vw, 70px); line-height: 1.14; letter-spacing: -.025em;
  opacity: 0; transform: translateY(20px); transition: opacity 1s ease, transform 1s var(--ease);
}
.is-loaded .tl-hero-text { opacity: 1; transform: none; }
/* the * after the name, drawn like the one after "SCENE" in Contact: a big asterisk hung from the cap line */
.tl-star { font-size: 1.25em; line-height: 0; vertical-align: .05em; margin-left: .02em; }

/* underlined phrases: hovering fills them with a project's colour and shows its film */
.tl-hl {
  text-decoration: underline; text-decoration-thickness: .06em; text-underline-offset: .14em;
  border-radius: .12em; transition: background-color .2s; cursor: default;
}
.tl-hl:hover { background: var(--c); text-decoration-color: transparent; }
/* the film that follows the cursor */
.tl-peek {
  position: fixed; left: 0; top: 0; z-index: 45; width: clamp(220px, 20vw, 380px); aspect-ratio: 16 / 10;
  overflow: hidden; background: #000; pointer-events: none; opacity: 0; transition: opacity .2s ease;
  box-shadow: 0 18px 40px rgba(0,0,0,.2);
}
.tl-peek.on { opacity: 1; }
.tl-peek img, .tl-peek video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tl-peek video { opacity: 0; transition: opacity .25s; }
.tl-peek video.playing { opacity: 1; }
/* a note instead of a film: text on a colour block, as tall as the text needs */
.tl-peek-note { display: none; }
.tl-peek.note { aspect-ratio: auto; background: var(--note, #f7b9cb); padding: 10px 12px 12px; box-shadow: 0 18px 40px rgba(0,0,0,.12); }
.tl-peek.note img, .tl-peek.note video { display: none; }
.tl-peek.note .tl-peek-note {
  display: block; margin: 0; color: var(--ink);
  font-size: clamp(12px, .8vw, 15px); line-height: 1.35; letter-spacing: 0;
}
@media (hover: none) { .tl-peek { display: none; } }

/* scroll cue right under the introduction; the arrow bobs */
.tl-scroll {
  margin-top: clamp(28px, 5vh, 56px); align-self: flex-start; display: inline-flex; align-items: center; gap: 10px;
  font-size: 13px; letter-spacing: .04em; text-transform: uppercase;
  opacity: 0; transition: opacity 1s ease .8s;
}
.is-loaded .tl-scroll { opacity: 1; }
.tl-scroll i { font-style: normal; font-size: 18px; animation: tl-bob 1.6s var(--ease) infinite; }
.tl-scroll:hover { text-decoration: underline; text-underline-offset: 4px; }
@keyframes tl-bob { 0%, 100% { transform: translateY(-2px); } 50% { transform: translateY(4px); } }

/* ---------------- slides ----------------
   every section after the intro is one full screen (a 16:9 "slide" on a
   1920×1080 display): a head row (title + slide number) at the top, content
   spread over the rest; the page colour changes per slide (data-bg) */
.tl-slide {
  min-height: calc(100svh - var(--foot-h)); display: flex; flex-direction: column;
  padding: 96px var(--gutter) clamp(40px, 6vh, 80px);
}
.tl-slide-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 20px;
  padding-bottom: 18px; margin-bottom: clamp(28px, 5vh, 64px); border-bottom: var(--line);
}
.tl-slide-head h2 {
  margin: 0; font-weight: 400; text-transform: uppercase;
  font-size: clamp(28px, 3.2vw, 64px); line-height: 1; letter-spacing: -.03em;
}
.tl-slide-no { font-size: 13px; font-variant-numeric: tabular-nums; }
.tl-count { font-size: .45em; letter-spacing: 0; vertical-align: .9em; }
.tl-sub {
  margin: 0 0 14px; font-weight: 400; text-transform: uppercase; font-size: 13px; letter-spacing: .02em;
}

/* ---------------- 02. work experience + awards ---------------- */

.tl-cv {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(30px, 4vw, 90px);
  margin-top: clamp(56px, 13vh, 180px);   /* generous space under the slide title */
}
.tl-cv ul { list-style: none; margin: 0; padding: 0; }
/* the companies and award years drop in one after another (--i = their order; js adds .in) */
.tl-exp-co, .tl-aw-year {
  opacity: 0; transform: translateY(18px);
  transition: opacity .7s ease, transform .8s var(--ease); transition-delay: calc(.1s + var(--i, 0) * .09s);
}
.tl-cv.in .tl-exp-co, .tl-cv.in .tl-aw-year { opacity: 1; transform: none; }
.tl-exp-co { border-top: var(--line); padding: 8px 0 12px; }
.tl-exp-co h4 { margin: 0 0 8px; font-weight: 400; text-transform: uppercase; font-size: clamp(17px, 1.3vw, 24px); letter-spacing: -.02em; }
.tl-exp-co li, .tl-aw-year li {
  display: flex; justify-content: space-between; gap: 16px; padding: 3px 0;
  font-size: clamp(13px, .85vw, 16px); line-height: 1.4;
}
.tl-period { color: var(--mute); white-space: nowrap; font-variant-numeric: tabular-nums; }
/* a note under a role (SBS): small, grey, indented under it, so it reads as part of that role */
.tl-exp-co li.tl-exp-sub {
  display: block; margin: 2px 0 0; padding: 0 0 0 18px; max-width: 92ch;   /* ≈ two lines */
  font-size: 11.5px; line-height: 1.5; color: var(--mute);
}
.tl-aw-year { display: grid; grid-template-columns: 64px minmax(0, 1fr); border-top: var(--line); padding: 8px 0 10px; }
.tl-aw-y { font-size: clamp(17px, 1.3vw, 24px); letter-spacing: -.02em; }
.tl-prize { text-align: right; }
.tl-prize.gp { background: var(--pink); border-radius: 999px; padding: 0 8px; }

/* ---------------- 03. core competencies (four rounded cards) + clients ---------------- */
/* the cards share four row tracks (number / title / text / results) through subgrid,
   so the rule above the results sits at the same height in every card */
/* the title on the left quarter, the four cards (slim, portrait) on the right three quarters */
.tl-comp-body { flex: 1; display: grid; grid-template-columns: minmax(max-content, 1fr) minmax(0, 3fr); gap: clamp(24px, 3vw, 64px); }
/* this slide's title sits in the left column, on two lines */
/* the number row is a fixed 16px + 18px gap; the title is pulled back up by that much so it
   starts at the same height as the other slide titles */
.tl-slide-head--bare { justify-content: flex-end; border-bottom: 0; padding-bottom: 0; margin-bottom: 18px; height: 16px; line-height: 16px; }
.tl-comp-side { margin-top: -34px; }
.tl-comp-title {
  margin: 0; font-weight: 400; text-transform: uppercase;
  font-size: clamp(28px, 3.2vw, 64px); line-height: 1; letter-spacing: -.03em;   /* = the other slide titles */
}
.tl-comp-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-template-rows: auto auto 1fr auto; gap: 0 12px;
}
.tl-comp-grid > li {
  display: grid; grid-row: span 4; grid-template-rows: subgrid; row-gap: 0; align-content: start; min-height: clamp(240px, 20vw, 380px);
  padding: 20px 22px 26px; border: var(--line); border-radius: 22px; background: var(--bg);
  transition: background-color .25s ease;
}
.tl-comp-grid > li:is(:hover, .on) { background: var(--c, #eee); }   /* .on = the centred card on phones (js) */
.tl-comp-num { font-size: 13px; font-variant-numeric: tabular-nums; }   /* (01) */
.tl-comp-grid h3 {
  margin: 22px 0 16px; font-weight: 400; text-transform: uppercase;
  font-size: clamp(22px, 1.9vw, 38px); line-height: .98; letter-spacing: -.03em;
}
.tl-comp-grid p { margin: 0; font-family: var(--wide); font-size: clamp(12px, .72vw, 14px); line-height: 1.55; word-break: keep-all; }
/* key results at the bottom of each card — small, under one rule */
.tl-wins { list-style: none; margin: clamp(28px, 4.5vh, 56px) 0 0; padding: 12px 0 0; border-top: var(--line); display: grid; gap: 8px; align-content: start; }   /* the margin is the least space between the text and the results */
.tl-wins li { display: flex; flex-direction: column; gap: 1px; }
.tl-wins b { font-weight: 700; font-size: clamp(13px, .85vw, 16px); line-height: 1.3; }
.tl-wins span { font-size: clamp(11.5px, .72vw, 13px); line-height: 1.4; color: #444; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }   /* one line */
/* the results stay hidden (their space kept, so the card doesn't change size) and slide
   up from below as the card takes its colour; the rule first, then each result a moment
   after the last. A card is "on" while hovered with a mouse, or on phones (no hover)
   while it is the one centred in the swipe row (js adds .on). */
.tl-wins { border-top-color: transparent; transition: border-color .3s ease; }
.tl-wins li { opacity: 0; transform: translateY(14px); transition: opacity .3s ease, transform .3s ease; }
.tl-comp-grid > li:is(:hover, .on) .tl-wins { border-top-color: var(--ink); }
.tl-comp-grid > li:is(:hover, .on) .tl-wins li { opacity: 1; transform: none; transition: opacity .4s ease, transform .5s var(--ease); }
.tl-comp-grid > li:is(:hover, .on) .tl-wins li:nth-child(1) { transition-delay: .05s; }
.tl-comp-grid > li:is(:hover, .on) .tl-wins li:nth-child(2) { transition-delay: .12s; }
.tl-comp-grid > li:is(:hover, .on) .tl-wins li:nth-child(3) { transition-delay: .19s; }
.tl-comp-grid > li:is(:hover, .on) .tl-wins li:nth-child(4) { transition-delay: .26s; }
.tl-comp-grid > li { opacity: 0; transform: translateY(40px); transition: opacity 1s ease, transform 1.1s var(--ease), background-color .25s ease; }
.tl-comp-grid.in > li { opacity: 1; transform: none; }
.tl-comp-grid.in > li:nth-child(1) { transition-delay: .1s, .1s, 0s; }
.tl-comp-grid.in > li:nth-child(2) { transition-delay: .3s, .3s, 0s; }
.tl-comp-grid.in > li:nth-child(3) { transition-delay: .5s, .5s, 0s; }
.tl-comp-grid.in > li:nth-child(4) { transition-delay: .7s, .7s, 0s; }

.tl-clients { margin-top: clamp(28px, 5vh, 64px); }
.tl-clients .tl-sub { margin-bottom: 8px; }
.tl-marquee { overflow: hidden; margin: 0 calc(-1 * var(--gutter)); pointer-events: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent); }
.tl-track { display: flex; width: max-content; animation: tl-roll var(--roll-dur, 40s) linear infinite; }
.tl-logo { flex: none; display: grid; place-items: center; padding: 0 clamp(20px, 2.2vw, 44px); height: clamp(44px, 5vh, 64px); }
.tl-logo img { object-fit: contain; filter: brightness(0); }
@keyframes tl-roll { to { transform: translateX(-50%); } }

/* ---------------- 04. selected works (the colour fill runs edge to edge; rules keep the side margins) ---------------- */
.tl-works { padding-left: 0; padding-right: 0; overflow-x: clip; }
.tl-works .tl-slide-head { margin: 0 var(--gutter) clamp(80px, 16vh, 190px); }   /* room before the list */
.tl-list {
  list-style: none; margin: 0; padding: 0;
  --fs: clamp(40px, 6.4vw, 118px);
}
/* the rule under the last project, inset like every other rule */
.tl-list::after { content: ""; display: block; margin: 0 var(--gutter); border-top: var(--line); }
/* one row per project: tall enough for the whole name, with even space above
   and below; the name and its pills sit on the row's centre line */
.tl-row { position: relative; z-index: 1; height: calc(var(--fs) * 1.11); background: var(--bg); }
.tl-row a { position: relative; z-index: 1; display: flex; align-items: center; gap: 14px; height: 100%; padding: 0 var(--gutter); }
.tl-name {
  font-weight: 400; text-transform: uppercase; white-space: nowrap;
  font-size: var(--fs); line-height: 1; letter-spacing: -.035em;
}
/* the rule above each project, inset to the page margins (drawn over the hover colour) */
.tl-row::after {
  content: ""; position: absolute; z-index: 2; top: 0; left: var(--gutter); right: var(--gutter);
  border-top: var(--line); pointer-events: none;
}
.tl-row:first-child::after { display: none; }   /* no rule above the first project */
/* hover: the row turns its colour across the full width */
.tl-row::before {
  content: ""; position: absolute; inset: 0; background: var(--c, #eee);
  opacity: 0; transition: opacity .18s ease;
}
.tl-row:hover, .tl-row.on { z-index: 3; }
.tl-row:hover::before, .tl-row.on::before, .tl-row.back::before { opacity: 1; }   /* .back: the row the Back motion lands on */
/* the project film pops up on the right of the hovered row (above the row's rule, ::after) */
.tl-film {
  position: absolute; z-index: 3; right: 9%; top: calc(50% + var(--dy, 0px)); width: clamp(200px, 24vw, 420px); aspect-ratio: 16 / 10;   /* --dy: js keeps it on screen */
  overflow: hidden; background: #000; pointer-events: none;
  opacity: 0; transform: translateY(-46%) scale(.92) rotate(-1.5deg); transition: opacity .2s ease, transform .35s var(--ease);
  box-shadow: 0 18px 40px rgba(0,0,0,.18);
}
.tl-film img, .tl-film video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tl-film video { opacity: 0; transition: opacity .3s; }
.tl-film video.playing { opacity: 1; }
.tl-row:hover .tl-film, .tl-row.on .tl-film { opacity: 1; transform: translateY(-50%) scale(1) rotate(-1.5deg); }
.tl-row:nth-child(even) .tl-film { right: 22%; transform: translateY(-46%) scale(.92) rotate(1.5deg); }
.tl-row:nth-child(even):hover .tl-film, .tl-row:nth-child(even).on .tl-film { transform: translateY(-50%) scale(1) rotate(1.5deg); }

/* click: the row's colour fills the screen, then the project opens */
/* (sits under the header pills, which stay put — the detail page has the same header) */
.tl-wipe { position: fixed; z-index: 35; left: 0; width: 100vw; background: var(--c, #eee); pointer-events: none; opacity: 0; }
.tl-wipe.on { opacity: 1; }   /* on the way back: full screen at once, then shrinks (.go) */
.tl-wipe.go { opacity: 1; transition: top .5s var(--ease), height .5s var(--ease); }
.tl-wipe .tl-name { position: fixed; margin: 0; transition: top .5s var(--ease); }

/* ---------------- 05. contact ---------------- */
.tl-contact { position: relative; overflow: hidden; }
.tl-contact > :not(.tl-glow) { position: relative; z-index: 1; }
/* grainy gradient rising from the bottom edge of the contact slide: anchored to
   the bottom, it slides up into place when the slide comes into view (js adds .in)
   and keeps swelling upwards like a tide; faded out towards the top */
.tl-glow--end {
  top: auto; bottom: 0; height: 62vh;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 70%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 70%);
  transform: translateY(45%); opacity: 0;
  transition: transform 1.6s cubic-bezier(.2,.7,.1,1), opacity 1.2s ease;
}
.tl-glow--end.in { transform: none; opacity: 1; }
/* on the white slide the white light wouldn't show: the intro's sky blue takes its
   place; the light sits on the bottom edge and swells up */
.tl-glow--end i { transform-origin: 50% 100%; }
.tl-glow--end i:nth-child(1) {
  background:
    radial-gradient(34% 70% at 18% 100%, rgba(201,222,243,.95), transparent 72%),
    radial-gradient(30% 62% at 52% 100%, rgba(247,185,203,.8), transparent 70%),
    radial-gradient(34% 70% at 84% 100%, rgba(201,222,243,.9), transparent 72%);
  animation: tl-rise-a 3.4s ease-in-out infinite alternate;
}
.tl-glow--end i:nth-child(2) {
  background:
    radial-gradient(36% 64% at 35% 100%, rgba(185,166,242,.65), transparent 70%),
    radial-gradient(30% 56% at 68% 100%, rgba(201,222,243,.85), transparent 72%),
    radial-gradient(32% 60% at 96% 100%, rgba(247,185,203,.6), transparent 70%);
  animation: tl-rise-b 2.8s ease-in-out infinite alternate;
}
@keyframes tl-rise-a {
  0%   { transform: translateX(-8%) scaleY(.85); }
  50%  { transform: translateX(-1%) scaleY(1.2); }
  100% { transform: translateX(7%) scaleY(.95); }
}
@keyframes tl-rise-b {
  0%   { transform: translateX(8%) scaleY(1.15); }
  50%  { transform: translateX(1%) scaleY(.85); }
  100% { transform: translateX(-7%) scaleY(1.25); }
}
/* lead + details along the top of the contact slide */
/* one item per row: label above its value */
.tl-contact-list { margin: 0; display: grid; grid-template-columns: minmax(0, 1fr); }
.tl-contact-list div { padding: 10px 0 14px; border-top: var(--line); }
.tl-contact-list div:first-child { border-top: 0; padding-top: 0; }   /* the slide title's rule is already above it */
.tl-contact-list dt { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--mute); }
.tl-contact-list dd { margin: 4px 0 0; font-size: clamp(15px, 1.1vw, 20px); }

/* ---------------- responsive ---------------- */
/* the competency cards stay four across until phone width, then go 2×2 */
@media (max-width: 1100px) {
  .tl-comp-body { grid-template-columns: 1fr; gap: 20px; }
  .tl-comp-grid > li { padding: 16px 16px 20px; border-radius: 18px; }
  .tl-comp-grid h3 { font-size: 2.6vw; }
  .tl-comp-grid p { font-size: 12.5px; }
}
@media (max-width: 800px) {
  .tl-head-right .pill:not(.tl-menu-btn) { display: none; }
  .tl-menu-btn { display: inline-flex; }
  .tl-hero-text { max-width: none; }
  .tl-slide { padding-top: 84px; }
  .tl-cv { grid-template-columns: 1fr; }
  .tl-logo { height: 48px; }
  /* phones: the cards become a sideways-swiping row that snaps card by card, the current one centred */
  .tl-comp-grid {
    display: flex; gap: 10px; overflow-x: auto; overscroll-behavior-x: contain;
    --card: min(66vw, 320px);   /* card width: two thirds of a phone, never wider than 320px (tablets) */
    margin: 0 calc(-1 * var(--gutter)); padding: 0 calc((100vw - var(--card)) / 2) 4px;   /* first and last card can sit centred too */
    scroll-snap-type: x mandatory; scrollbar-width: none;
  }
  .tl-comp-grid::-webkit-scrollbar { display: none; }
  .tl-comp-grid > li {
    display: flex; flex-direction: column; flex: 0 0 var(--card); min-height: 400px;
    padding: 16px 16px 20px; scroll-snap-align: center;   /* the card in view snaps to the middle of the screen */
  }
  .tl-wins { margin-top: auto; }
  .tl-comp-grid h3 { margin: 14px 0 16px; font-size: 26px; }
  .tl-comp-grid p { font-size: 12.5px; }
  .tl-list { --fs: 10.5vw; }
  .tl-row .small-pill { display: none; }
  .tl-film { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .tl-track, .tl-glow i, .tl-glow::after { animation: none; }
  .tl-glow--end { transform: none; opacity: 1; }
  *, *::before, *::after { transition-duration: .01ms !important; transition-delay: 0s !important; }
}
