/* «Как это работает»: three tiles that read in a few seconds. Every object shows its key state most of the time — the
   request is sent, the app is being assembled, the mini app is ready — and one 8-second choreography moves the eye
   1 → 2 → 3: send, build, order. Motion follows the classic principles: anticipation before every action, squash and
   stretch on presses, overshoot and follow-through on arrivals, an arc for the flying drink, eased timing throughout
   and small secondary actions (typing dots, ripple, the button's shine). Easings used below:
     out     cubic-bezier(.22, 1, .36, 1)     arrivals
     in      cubic-bezier(.55, 0, .75, .2)    departures and wind-ups
     in-out  cubic-bezier(.65, 0, .35, 1)     travel
     back    cubic-bezier(.34, 1.56, .64, 1)  overshooting pops */
.pipeline {
  /* Each tile loops on its own clock; different periods keep them from ever lining up into a sequence. */
  --T1: 6s;
  --T2: 7s;
  --T3: 8s;
  --tile-h: clamp(440px, 36vw, 590px);
  --label-h: 64px;
  --gap: clamp(14px, 1.5vw, 26px);
  --tg-blue: #3390ec;
  padding: clamp(72px, 7vw, 112px) 2vw clamp(56px, 5vw, 84px);
  background: var(--paper);
}
.pipeline *, .pipeline *::before, .pipeline *::after { box-sizing: border-box; }
/* The choreography only runs while the section is on screen; everything pauses together, so it stays in sync. */
.pipeline:not(.is-playing) *,
.pipeline:not(.is-playing) *::before,
.pipeline:not(.is-playing) *::after { animation-play-state: paused !important; }

.pipeline-intro { text-align: center; margin-bottom: clamp(40px, 4.5vw, 72px); }
.pipeline-intro h2 { margin: 0; font-size: var(--heading-section); font-weight: 560; letter-spacing: -.05em; line-height: 1; }
.pipeline-intro h2 span, .pipeline-label h3 span { font-family: "Source Serif 4 Hero", Georgia, serif; font-style: italic; font-weight: 600; }
.pipeline-intro p { margin: 16px 0 0; color: var(--text); font-size: 15px; text-wrap: balance; }

.pipeline-steps { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); }
.pipeline-step { position: relative; min-width: 0; }

.pipeline-label { height: var(--label-h); display: flex; align-items: flex-start; gap: 14px; margin: 0 6px 16px; }
.pipeline-num { width: 30px; height: 30px; flex: none; display: grid; place-items: center; margin-top: 2px; border-radius: 50%; background: var(--ink); color: #fff; font-size: 14px; font-weight: 600; }
.pipeline-label h3 { margin: 0; font-size: clamp(24px, 2vw, 32px); font-weight: 560; letter-spacing: -.035em; line-height: 1.05; }
.pipeline-label p { margin: 6px 0 0; color: var(--muted); font-size: clamp(14px, 1vw, 16px); line-height: 1.35; }

/* Static arrows between the tiles: the order is in the numbers and titles, not in the timing. */
.pipeline-step + .pipeline-step::before {
  content: "→";
  position: absolute;
  z-index: 3;
  left: calc(var(--gap) / -2 - 19px);
  top: calc(var(--label-h) + 16px + var(--tile-h) / 2 - 19px);
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--paper);
  border: 1px solid var(--line);
  box-shadow: 0 6px 18px rgba(20, 20, 20, .08);
  color: var(--ink);
  font-size: 17px;
}

.pipeline-tile { position: relative; height: var(--tile-h); display: flex; align-items: flex-end; justify-content: center; border-radius: clamp(24px, 2.2vw, 34px); background: var(--soft); overflow: hidden; }

/* An iPhone rising from the bottom of the tile. */
.pipeline-phone {
  position: relative;
  width: min(74%, 336px);
  height: calc(100% - clamp(26px, 2.6vw, 44px));
  margin-bottom: -34px;
  display: flex;
  flex-direction: column;
  border: 9px solid #161617;
  border-bottom-width: 0;
  border-radius: 52px 52px 0 0;
  background: #fff;
  box-shadow: 0 40px 80px rgba(20, 20, 20, .16);
  overflow: hidden;
}
.pipeline-island { position: absolute; z-index: 9; top: 9px; left: 50%; width: 88px; height: 25px; margin-left: -44px; border-radius: 999px; background: #161617; }

/* ── 1 · Telegram chat ─────────────────────────────────────────────────────────────────────────────────────────── */
/* The screen clips itself: Chrome lets layers with backdrop-filter escape a parent's rounded overflow clip. */
.tg-screen, .tma { border-radius: 43px 43px 0 0; clip-path: inset(0 round 43px 43px 0 0); }
.tg-screen { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
/* Telegram's default wallpaper: its four-colour gradient (#dbddbb #6ba587 #d5d88d #88b884, rendered with Telegram's
   own algorithm) under the doodle pattern in black, soft-light, 50%. On send Telegram shifts the gradient a phase. */
.tg-wall { position: absolute; inset: 0; isolation: isolate; background: url("pipeline/tg-gradient-a.webp") center / cover; }
.tg-wall-b { position: absolute; inset: 0; background: url("pipeline/tg-gradient-b.webp") center / cover; opacity: 0; animation: tg-wall var(--T1) linear infinite; }
.tg-wall::after {
  content: "";
  position: absolute;
  inset: 0;
  background: #000;
  mix-blend-mode: soft-light;
  opacity: .5;
  -webkit-mask: url("pipeline/tg-pattern.webp") top center / 112% auto no-repeat;
  mask: url("pipeline/tg-pattern.webp") top center / 112% auto no-repeat;
}
@keyframes tg-wall {
  0%, 44.67% { opacity: 0; animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  57.33%, 72% { opacity: 1; animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  97%, 100% { opacity: 0; }
}

.tg-head {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 40px 10px 7px;
  background: rgba(247, 247, 247, .9);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  box-shadow: 0 .5px 0 rgba(0, 0, 0, .16);
}
.tg-back { display: flex; align-items: center; gap: 3px; color: var(--tg-blue); font-size: 15px; }
.tg-back svg { width: 10px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.tg-title { display: grid; justify-items: center; line-height: 1.2; }
.tg-title b { font-size: 15.5px; font-weight: 600; }
.tg-status { display: grid; font-size: 12px; }
.tg-status > span { grid-area: 1 / 1; justify-self: center; }
.tg-status-idle { color: #8e9399; opacity: 0; animation: tg-status-idle var(--T1) linear infinite; }
.tg-status-typing { color: var(--tg-blue); animation: tg-status-typing var(--T1) linear infinite; }
.tg-status-typing i { font-style: normal; animation: tg-ellipsis 1.2s infinite; }
.tg-status-typing i:nth-child(2) { animation-delay: .2s; }
.tg-status-typing i:nth-child(3) { animation-delay: .4s; }
@keyframes tg-ellipsis { 0%, 100% { opacity: .2; } 45% { opacity: 1; } }
@keyframes tg-status-typing {
  0%, 26.67% { opacity: 1; }
  30.67% { opacity: 0; }
  66% { opacity: 0; }
  69.33%, 100% { opacity: 1; }
}
@keyframes tg-status-idle {
  0%, 26.67% { opacity: 0; }
  30.67% { opacity: 1; }
  66% { opacity: 1; }
  69.33%, 100% { opacity: 0; }
}
.tg-avatar { justify-self: end; width: 34px; height: 34px; border-radius: 50%; overflow: hidden; background: #fff; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08); }
.tg-avatar img { width: 100%; height: 100%; object-fit: cover; }

.tg-chat { position: relative; z-index: 1; flex: 1; min-height: 0; display: flex; flex-direction: column; justify-content: flex-end; gap: 6px; padding: 10px 10px 8px; overflow: hidden; }
.tg-date { align-self: center; margin-bottom: auto; padding: 2px 9px; border-radius: 999px; background: rgba(46, 86, 56, .3); color: #fff; font-size: 12px; font-weight: 600; }
.tg-msg { position: relative; margin: 0; max-width: 86%; padding: 7px 11px 7px; border-radius: 18px; font-size: clamp(14px, 1.05vw, 15.5px); line-height: 1.32; box-shadow: 0 1px .5px rgba(0, 0, 0, .13); }
/* The request: launched from the composer after the send press, it overshoots and settles (follow-through). */
.tg-out {
  align-self: flex-end;
  background: #e1fec6;
  border-bottom-right-radius: 6px;
  transform-origin: 100% 100%;
  animation: tg-out var(--T1) linear infinite;
}
.tg-out::after { content: ""; position: absolute; right: -6px; bottom: 0; width: 12px; height: 14px; background: #e1fec6; clip-path: path("M0 0 C1 8 4 12 12 14 L0 14 Z"); }
@keyframes tg-out {
  0%, 26.67% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  31.33% { opacity: 0; transform: translateY(-14px); }
  44.8% { opacity: 0; transform: translateY(34px) scale(.84); animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
  49.07% { opacity: 1; transform: translateY(-5px) scale(1.025); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  51.73% { transform: translateY(1.5px) scale(.995); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  54.4%, 100% { opacity: 1; transform: none; }
}
.tg-meta { float: right; display: inline-flex; align-items: center; gap: 3px; margin: 6px -3px -3px 9px; color: #55a84a; font-size: 11px; }
.tg-ticks { position: relative; width: 17px; height: 10px; }
.tg-ticks svg { position: absolute; inset: 0; width: 16px; height: 10px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
/* Read receipt: the second tick pops in a beat after the bubble lands (overlapping action). */
.tg-tick-2 { transform-origin: 75% 50%; animation: tg-tick var(--T1) linear infinite; }
@keyframes tg-tick {
  0%, 26.67% { opacity: 1; transform: none; }
  31.33%, 58% { opacity: 0; transform: scale(.4); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  61.33% { opacity: 1; transform: scale(1.3); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  63.33%, 100% { opacity: 1; transform: none; }
}
.tg-in { align-self: flex-start; background: #fff; border-bottom-left-radius: 6px; }
.tg-dots { display: flex; gap: 5px; padding: 12px 13px; transform-origin: 0 100%; animation: tg-dots var(--T1) linear infinite; }
.tg-dots i { width: 7px; height: 7px; border-radius: 50%; background: #9aa3ab; animation: tg-dot 1.2s ease-in-out infinite; }
.tg-dots i:nth-child(2) { animation-delay: .15s; }
.tg-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes tg-dot { 30% { transform: translateY(-4px); background: #6a747d; } 60% { transform: none; } }
@keyframes tg-dots {
  0%, 26.67% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  31.33% { opacity: 0; transform: translateY(-14px); }
  66% { opacity: 0; transform: translateY(6px) scale(.5); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  70% { opacity: 1; transform: scale(1.06); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  72.67%, 100% { opacity: 1; transform: none; }
}

.tg-compose { position: relative; z-index: 2; display: flex; align-items: center; gap: 7px; padding: 7px 9px 46px; background: rgba(247, 247, 247, .94); box-shadow: 0 -.5px 0 rgba(0, 0, 0, .16); }
.tg-menu-btn { display: flex; align-items: center; gap: 5px; height: 30px; padding: 0 10px; border-radius: 15px; background: var(--tg-blue); color: #fff; font-size: 13px; font-weight: 600; }
.tg-menu-btn svg { width: 13px; height: 10px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.tg-field { flex: 1; min-width: 0; height: 32px; display: grid; align-items: center; padding: 0 12px; border-radius: 16px; background: #fff; box-shadow: inset 0 0 0 .5px rgba(0, 0, 0, .2); font-size: 14px; overflow: hidden; }
.tg-field > span { grid-area: 1 / 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tg-placeholder { color: #9a9ea3; animation: tg-placeholder var(--T1) linear infinite; }
.tg-draft { color: var(--ink); opacity: 0; animation: tg-draft var(--T1) linear infinite; }
@keyframes tg-placeholder {
  0%, 26.67%, 32% { opacity: 1; }
  34%, 46% { opacity: 0; }
  49.33%, 100% { opacity: 1; }
}
@keyframes tg-draft {
  0%, 26.67%, 32% { opacity: 0; transform: translateY(6px); animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
  36%, 44.53% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  46.93%, 100% { opacity: 0; transform: translateY(-10px); }
}
.tg-action { position: relative; width: 32px; height: 32px; flex: none; }
.tg-action > span { position: absolute; inset: 0; display: grid; place-items: center; border-radius: 50%; }
.tg-mic { color: #8e9399; animation: tg-mic var(--T1) linear infinite; }
.tg-mic svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
/* Send: appears with the draft, winds up (squash) and releases (stretch) as the message leaves. */
.tg-send { background: var(--tg-blue); opacity: 0; transform: scale(.4); animation: tg-send var(--T1) linear infinite; }
.tg-send svg { width: 18px; height: 18px; fill: none; stroke: #fff; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
@keyframes tg-mic {
  0%, 26.67%, 32% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  34.67%, 50.67% { opacity: 0; transform: scale(.4); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  54.67%, 100% { opacity: 1; transform: none; }
}
@keyframes tg-send {
  0%, 26.67%, 32.67% { opacity: 0; transform: scale(.4); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  36.67% { opacity: 1; transform: scale(1.1); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  38.67%, 41.87% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  44.53% { transform: scale(.8, .76); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  46.67% { transform: scale(1.12); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  48.53%, 49.87% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  52%, 100% { opacity: 0; transform: scale(.4); }
}

/* ── 2 · Cody at work ──────────────────────────────────────────────────────────────────────────────────────────── */
.pipeline-tile-work { align-items: center; }
.work-card { width: 88%; border-radius: 20px; background: #fff; box-shadow: 0 1px 2px rgba(20, 20, 20, .06), 0 30px 70px rgba(20, 20, 20, .14); overflow: hidden; }
.work-head { display: flex; align-items: center; gap: 12px; padding: 13px 16px; border-bottom: 1px solid var(--line); }
.work-avatar { position: relative; width: 40px; height: 40px; flex: none; display: grid; place-items: center; }
.work-avatar img { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; }
.work-ring { position: absolute; inset: 0; animation: work-ring var(--T2) linear infinite; }
.work-ring span {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(var(--tg-blue) 0 30%, transparent 30% 100%);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2.5px));
  animation: pipeline-spin 1.1s linear infinite;
}
.work-done {
  position: absolute;
  right: -3px;
  bottom: -3px;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  border: 2px solid #fff;
  background: #28c840 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 12.5 4 4 8-9'/%3E%3C/svg%3E") center / 11px no-repeat;
  opacity: 0;
  transform: scale(0);
  animation: work-done var(--T2) linear infinite;
}
@keyframes work-ring {
  0%, 5.14%, 65.71% { opacity: 1; }
  68.57%, 96.42% { opacity: 0; }
  98.57%, 100% { opacity: 1; }
}
@keyframes work-done {
  0%, 5.14%, 66.29% { opacity: 0; transform: scale(0); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  69.71% { opacity: 1; transform: scale(1.25); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  72%, 96.42% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  98.57%, 100% { opacity: 0; transform: scale(0); }
}
.work-title { flex: 1; min-width: 0; display: grid; gap: 2px; }
.work-titles { display: grid; }
.work-titles b { grid-area: 1 / 1; font-size: clamp(15px, 1.15vw, 17px); font-weight: 600; }
.work-doing { animation: work-doing var(--T2) linear infinite; }
.work-finished { opacity: 0; animation: work-finished var(--T2) linear infinite; }
@keyframes work-doing {
  0%, 5.14%, 66.86% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  69.14%, 97.13% { opacity: 0; transform: translateY(-7px); animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
  99.28%, 100% { opacity: 1; transform: none; }
}
@keyframes work-finished {
  0%, 5.14%, 67.43% { opacity: 0; transform: translateY(7px); animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
  70.86%, 96.78% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  98.21%, 100% { opacity: 0; transform: translateY(-7px); }
}
.work-title small { color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }

.work-body { display: grid; grid-template-columns: 42% 1fr; gap: clamp(14px, 1.4vw, 22px); align-items: center; padding: clamp(16px, 1.6vw, 22px); }
/* A small copy of the app being assembled: the same photos that appear in the finished app in tile 3. */
.work-preview { aspect-ratio: 9 / 15; display: flex; flex-direction: column; gap: 6px; padding: 7px; border-radius: 16px; background: #fbf8f4; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06); overflow: hidden; }
.wp-hero, .wp-skel { background: linear-gradient(90deg, #ece6de 0%, #f8f5f0 40%, #ece6de 80%) 0 0 / 200% 100%; animation: pipeline-shimmer 1.4s linear infinite; }
@keyframes pipeline-shimmer { to { background-position: -200% 0; } }
.wp-hero { position: relative; height: 27%; flex: none; border-radius: 10px; overflow: hidden; }
.wp-hero img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; animation: wp-hero var(--T2) linear infinite; }
@keyframes wp-hero {
  0%, 5.14%, 39.43% { opacity: 0; transform: scale(1.1); animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
  46.86%, 96.42% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  99.28%, 100% { opacity: 0; transform: scale(1.1); }
}
.wp-title { width: 56%; height: 8px; margin: 2px 2px 1px; flex: none; border-radius: 4px; background: #e2d8ca; }
.wp-row { position: relative; display: flex; align-items: center; gap: 6px; padding: 5px; flex: none; border-radius: 9px; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .06); }
.wp-row img { width: 24px; height: 24px; flex: none; border-radius: 7px; object-fit: cover; }
.wp-row b { flex: 1; height: 7px; border-radius: 4px; background: #e8dccb; }
.wp-row i { width: 13px; height: 13px; flex: none; border-radius: 50%; background: #f1ebe3; }
/* The last row materialises out of its skeleton, sliding in with a small overshoot. */
.wp-row-late > img, .wp-row-late > b, .wp-row-late > i { opacity: 0; animation: wp-row var(--T2) linear infinite; }
.wp-row-late > b { animation-delay: 40ms; }
.wp-row-late > i { animation-delay: 80ms; }
.wp-skel { position: absolute; inset: 0; border-radius: inherit; animation: pipeline-shimmer 1.4s linear infinite, wp-skel var(--T2) linear infinite; }
@keyframes wp-row {
  0%, 5.14%, 46.29% { opacity: 0; transform: translateX(-8px); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  51.43%, 96.42% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  99.28%, 100% { opacity: 0; transform: translateX(-8px); }
}
@keyframes wp-skel {
  0%, 5.14%, 45.71% { opacity: 1; }
  49.14%, 96.78% { opacity: 0; }
  99.28%, 100% { opacity: 1; }
}
.wp-button { position: relative; margin-top: auto; height: 22px; flex: none; border-radius: 7px; border: 1.5px dashed rgba(51, 144, 236, .55); overflow: hidden; animation: wp-button-squash var(--T2) linear infinite; }
.wp-button-fill { position: absolute; inset: -2px; background: var(--tg-blue); transform: scaleX(0); transform-origin: 0 50%; animation: wp-button-fill var(--T2) linear infinite; }
@keyframes wp-button-fill {
  0%, 5.14%, 55.43% { transform: scaleX(0); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  61.14%, 96.42% { transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  98.92%, 100% { transform: scaleX(0); }
}
@keyframes wp-button-squash {
  0%, 5.14%, 60.91% { transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  62.29% { transform: scale(1.04, .8); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  64.57% { transform: scale(.98, 1.08); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  66.29%, 100% { transform: none; }
}

.work-log { margin: 0; padding: 0; list-style: none; display: grid; gap: clamp(11px, 1vw, 15px); }
.work-log li { display: flex; align-items: center; gap: 10px; color: var(--ink); font-size: clamp(14px, 1.1vw, 16.5px); line-height: 1.2; }
.wl-icon { position: relative; width: 20px; height: 20px; flex: none; }
.wl-icon > span { position: absolute; inset: 0; border-radius: 50%; }
.wl-ring { box-shadow: inset 0 0 0 2px var(--line); }
.wl-spin span { position: absolute; inset: 0; border-radius: 50%; border: 2px solid rgba(51, 144, 236, .22); border-top-color: var(--tg-blue); animation: pipeline-spin .85s linear infinite; }
.wl-check { background: #28c840 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 12.5 4 4 8-9'/%3E%3C/svg%3E") center / 13px no-repeat; }
@keyframes pipeline-spin { to { transform: rotate(1turn); } }
/* Step 3 finishes: the spinner gives way to a check that pops in with an overshoot. */
.wl-3 .wl-spin { animation: wl3-spin var(--T2) linear infinite; }
.wl-3 .wl-check { opacity: 0; transform: scale(0); animation: wl3-check var(--T2) linear infinite; }
@keyframes wl3-spin {
  0%, 5.14%, 49.14% { opacity: 1; }
  50.86%, 97.13% { opacity: 0; }
  99.28%, 100% { opacity: 1; }
}
@keyframes wl3-check {
  0%, 5.14%, 49.14% { opacity: 0; transform: scale(0); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  52.23% { opacity: 1; transform: scale(1.28); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  54.29%, 96.78% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  98.92%, 100% { opacity: 0; transform: scale(0); }
}
/* Step 4 starts right after and finishes as the button fills. */
.wl-4 { animation: wl4-text var(--T2) linear infinite; }
.wl-4 .wl-ring { animation: wl4-ring var(--T2) linear infinite; }
.wl-4 .wl-spin { opacity: 0; animation: wl4-spin var(--T2) linear infinite; }
.wl-4 .wl-check { opacity: 0; transform: scale(0); animation: wl4-check var(--T2) linear infinite; }
@keyframes wl4-text {
  0%, 5.14%, 50.86% { color: var(--muted); }
  53.71%, 97.13% { color: var(--ink); }
  99.28%, 100% { color: var(--muted); }
}
@keyframes wl4-ring {
  0%, 5.14%, 50.86% { opacity: 1; }
  53.14%, 97.49% { opacity: 0; }
  99.28%, 100% { opacity: 1; }
}
@keyframes wl4-spin {
  0%, 5.14%, 51.43% { opacity: 0; }
  54.29%, 63.43% { opacity: 1; }
  65.14%, 100% { opacity: 0; }
}
@keyframes wl4-check {
  0%, 5.14%, 63.43% { opacity: 0; transform: scale(0); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  66.51% { opacity: 1; transform: scale(1.28); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  68.57%, 96.78% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  98.92%, 100% { opacity: 0; transform: scale(0); }
}
.work-bar { height: 3px; background: var(--soft); }
.work-bar span { display: block; height: 100%; width: 58%; background: var(--tg-blue); animation: work-bar var(--T2) linear infinite; }
@keyframes work-bar {
  0%, 5.14%, 37.14% { width: 58%; animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  65.71%, 96.42% { width: 100%; animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  99.28%, 100% { width: 58%; }
}

/* ── 3 · the Telegram Mini App ────────────────────────────────────────────────────────────────────────────────── */
.pipeline-tile-app { background: linear-gradient(180deg, #f4efe8 0%, #ebe3d7 100%); }
.tma { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; background: #fbf8f4; overflow: hidden; }
.tma-hero { position: relative; height: 27%; flex: none; }
.tma-hero img { display: block; width: 100%; height: 100%; object-fit: cover; }
.tma-pill {
  position: absolute;
  top: 40px;
  height: 28px;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 0 11px;
  border-radius: 14px;
  background: rgba(24, 24, 24, .34);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
}
.tma-pill svg { width: 10px; height: 10px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.tma-close { left: 10px; }
.tma-more { right: 10px; letter-spacing: 1px; }
.tma-sheet { position: relative; z-index: 1; flex: 1; min-height: 0; margin-top: -18px; padding: 14px 12px 0; display: flex; flex-direction: column; gap: 10px; border-radius: 20px 20px 0 0; background: #fbf8f4; overflow: hidden; }
.tma-title { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.tma-title > span { display: grid; gap: 2px; min-width: 0; }
.tma-title b { font-size: 21px; letter-spacing: -.02em; line-height: 1.1; }
.tma-title small { color: #8b7d6b; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tma-title em { flex: none; margin-top: 2px; padding: 4px 9px; border-radius: 999px; background: #fff; box-shadow: inset 0 0 0 1px rgba(60, 40, 20, .08); color: #5b4a38; font-size: 11.5px; font-style: normal; font-weight: 600; }
.tma-tabs { display: flex; gap: 3px; padding: 3px; border-radius: 12px; background: #f0e9df; }
.tma-tabs span { flex: 1; padding: 6px 0; border-radius: 9px; text-align: center; color: #8a7a67; font-size: 12.5px; font-weight: 600; }
.tma-tabs .is-on { background: #fff; color: var(--ink); box-shadow: 0 1px 3px rgba(60, 40, 20, .12); }
.tma-menu { margin: 0; padding: 0; list-style: none; display: grid; gap: 7px; }
.tma-menu li { position: relative; display: flex; align-items: center; gap: 10px; padding: 7px 8px 7px 7px; border-radius: 16px; background: #fff; box-shadow: 0 1px 2px rgba(60, 40, 20, .07); }
.tma-menu img { width: 48px; height: 48px; flex: none; border-radius: 12px; object-fit: cover; }
.tma-menu li > span { flex: 1; min-width: 0; display: grid; line-height: 1.25; }
.tma-menu b { font-size: 14px; font-weight: 600; }
.tma-menu small { color: #8b7d6b; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tma-menu strong { color: var(--ink); font-weight: 600; }
.tma-add { position: relative; width: 30px; height: 30px; flex: none; display: grid; place-items: center; border-radius: 50%; background: #f3ede4; color: #5e3f24; font-style: normal; font-weight: 700; font-size: 17px; }
.tma-add > span { grid-area: 1 / 1; }
/* The picked drink: highlighted row, filled counter. It is un-picked just before the tap and picked again by it. */
.tma-raf { animation: tma-row var(--T3) linear infinite; }
.tma-raf .tma-add { background: #5e3f24; color: #fff; font-size: 14px; animation: tma-add var(--T3) linear infinite; }
.tma-raf .tma-plus { opacity: 0; font-size: 17px; animation: tma-plus var(--T3) linear infinite; }
.tma-count { animation: tma-count var(--T3) linear infinite; }
@keyframes tma-row {
  0%, 11% { box-shadow: inset 0 0 0 1.5px #c9a47a, 0 1px 2px rgba(60, 40, 20, .07); }
  13%, 19% { box-shadow: inset 0 0 0 0 #c9a47a, 0 1px 2px rgba(60, 40, 20, .07); }
  21.5%, 100% { box-shadow: inset 0 0 0 1.5px #c9a47a, 0 1px 2px rgba(60, 40, 20, .07); }
}
@keyframes tma-add {
  0%, 11% { background: #5e3f24; color: #fff; transform: none; }
  13% { background: #f3ede4; color: #5e3f24; transform: none; }
  15.5% { transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  17.5% { background: #f3ede4; color: #5e3f24; transform: scale(.82, .78); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  19.5% { background: #5e3f24; color: #fff; transform: scale(1.14); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  21.5%, 100% { background: #5e3f24; color: #fff; transform: none; }
}
@keyframes tma-plus {
  0%, 11% { opacity: 0; }
  13%, 18% { opacity: 1; }
  19%, 100% { opacity: 0; }
}
@keyframes tma-count {
  0%, 10.5% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  12.5%, 18.5% { opacity: 0; transform: scale(.4); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  20.5% { opacity: 1; transform: scale(1.3); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  22.5%, 100% { opacity: 1; transform: none; }
}
/* The finger: approaches (anticipation), presses, lifts; the ripple is the secondary action. */
.tma-touch, .tma-ripple { position: absolute; top: 50%; right: 5px; width: 34px; height: 34px; margin-top: -17px; border-radius: 50%; pointer-events: none; }
.tma-touch { background: rgba(40, 30, 20, .22); opacity: 0; animation: tma-touch var(--T3) linear infinite; }
.tma-ripple { box-shadow: 0 0 0 2px rgba(94, 63, 36, .45); opacity: 0; animation: tma-ripple var(--T3) linear infinite; }
@keyframes tma-touch {
  0%, 13% { opacity: 0; transform: scale(1.6); animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
  15.5% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  17.5% { opacity: 1; transform: scale(.8); animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
  20% { opacity: .6; transform: none; }
  22.5%, 100% { opacity: 0; transform: scale(1.15); }
}
@keyframes tma-ripple {
  0%, 18% { opacity: 0; transform: scale(.7); }
  18.6% { opacity: 1; transform: scale(.85); animation-timing-function: cubic-bezier(.22, 1, .36, 1); }
  25%, 100% { opacity: 0; transform: scale(2.3); }
}

/* Telegram's MainButton: it leaves with the un-pick, comes back with the tap, takes the drink with a squash and stretch,
   then shines (Telegram's own «shine» effect). */
.tma-bottom { position: absolute; z-index: 3; left: 0; right: 0; bottom: 0; padding: 18px 12px 48px; background: linear-gradient(rgba(251, 248, 244, 0), #fbf8f4 38%); }
.tma-main { position: relative; overflow: hidden; padding: 13px; border-radius: 12px; background: var(--tg-blue); color: #fff; text-align: center; font-size: 15px; font-weight: 600; animation: tma-main var(--T3) linear infinite; }
@keyframes tma-main {
  0%, 10% { opacity: 1; transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  12.5%, 20% { opacity: 0; transform: translateY(70%); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  23.5% { opacity: 1; transform: translateY(-5%); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  25.3% { transform: none; animation-timing-function: cubic-bezier(.55, 0, .75, .2); }
  26.4% { transform: scale(1.035, .88); animation-timing-function: cubic-bezier(.34, 1.56, .64, 1); }
  28.4% { transform: scale(.99, 1.04); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  30%, 100% { opacity: 1; transform: none; }
}
.tma-shine { position: absolute; top: 0; bottom: 0; left: 0; width: 38%; background: linear-gradient(100deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, .5), rgba(255, 255, 255, 0)); transform: translateX(-130%) skewX(-14deg); animation: tma-shine var(--T3) linear infinite; }
@keyframes tma-shine {
  0%, 29% { transform: translateX(-130%) skewX(-14deg); animation-timing-function: cubic-bezier(.65, 0, .35, 1); }
  36%, 100% { transform: translateX(300%) skewX(-14deg); }
}
/* The drink flies to the button along an arc: X moves evenly, Y rises then falls (ease-out, then ease-in), and it
   shrinks as it goes. --fly-* are measured by pipeline.js. */
.tma-fly { position: absolute; z-index: 5; left: var(--fly-x0, 60px); top: var(--fly-y0, 300px); width: 0; height: 0; opacity: 0; animation: tma-fly-x var(--T3) linear infinite; }
.tma-fly-y { position: absolute; left: -18px; top: -18px; width: 36px; height: 36px; border-radius: 11px; overflow: hidden; box-shadow: 0 8px 18px rgba(60, 40, 20, .28); animation: tma-fly-y var(--T3) linear infinite; }
.tma-fly-y img { display: block; width: 100%; height: 100%; object-fit: cover; }
@keyframes tma-fly-x {
  0%, 19% { opacity: 0; transform: none; }
  19.6% { opacity: 1; transform: none; }
  25.4% { opacity: 1; transform: translateX(var(--fly-dx, 90px)); }
  26.4%, 100% { opacity: 0; transform: translateX(var(--fly-dx, 90px)); }
}
@keyframes tma-fly-y {
  0%, 19.6% { transform: none; animation-timing-function: cubic-bezier(.2, .7, .4, 1); }
  22.2% { transform: translateY(var(--fly-apex, -34px)) scale(.92) rotate(-8deg); animation-timing-function: cubic-bezier(.6, 0, .8, .4); }
  25.4%, 100% { transform: translateY(var(--fly-dy, 110px)) scale(.5) rotate(6deg); }
}

@media (max-width: 900px) {
  .pipeline { --tile-h: 480px; --label-h: auto; padding-inline: 16px; }
  .pipeline-intro p { font-size: 16px; }
  .pipeline-steps { grid-template-columns: minmax(0, 1fr); gap: 36px; }
  .pipeline-step + .pipeline-step::before { display: none; }
  .pipeline-label { height: auto; }
  .pipeline-phone { width: min(80%, 330px); }
}

@media (prefers-reduced-motion: reduce) {
  .pipeline *, .pipeline *::before, .pipeline *::after, .pipeline-step::before { animation: none !important; }
}
