/*
 * The scroll-driven Telegram walkthrough on /tech/farmworkx.
 *
 * The shape: a phone sticks in the viewport while the explanations scroll
 * past it. Each explanation owns a step of the conversation. When one
 * reaches the middle of the screen, its messages appear in the phone.
 *
 * Three things this must survive, all of them from docs/17.
 *
 *   No JavaScript. Every message is in the HTML. Without the script the
 *   phone does not pin, nothing is hidden, and the whole conversation reads
 *   as a plain transcript under its heading. That is the fallback and it is
 *   a real page, not a broken one.
 *
 *   Reduced motion. No transitions, no scroll animation. Steps still swap,
 *   because swapping is content and not decoration.
 *
 *   360px wide. Below the pin breakpoint the layout is one column, the phone
 *   sits inline above its text, and nothing scrolls sideways.
 */

/* ---- The two-column stage ------------------------------------------ */

.walk { position: relative; }

.walk-stage { display: grid; gap: clamp(24px, 4vw, 56px); }

@media (min-width: 900px) {
  .walk-stage {
    grid-template-columns: minmax(300px, 380px) 1fr;
    align-items: start;
  }
}

/* The phone column. Pinned only where there is room for it, and only when
   the script has said so, so a no-script page never pins an empty frame. */
.walk-phone-col { display: flex; justify-content: center; }

@media (min-width: 900px) {
  .js .walk-phone-col {
    position: sticky;
    top: calc(68px + var(--cx-space-6));
    align-self: start;
  }
}

/* ---- The phone ------------------------------------------------------ */

.phone {
  width: 100%;
  max-width: 340px;
  background: var(--cx-brand-compost);
  border-radius: 26px;
  padding: var(--cx-space-2);
  box-shadow: 0 1px 2px rgba(28, 25, 23, .16), 0 12px 34px rgba(28, 25, 23, .18);
}

.phone-screen {
  background: var(--tg-wallpaper);
  border-radius: 19px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  /* Without the script every step shows at once and the phone is simply as
     tall as the whole transcript. The fixed height below is for the scripted
     page only, where it stops the pinned frame growing and shrinking as
     steps swap. */
  min-height: 520px;
}

/* The Telegram chat header. Group name, member count, the bot's presence. */
.phone-bar {
  display: flex;
  align-items: center;
  gap: var(--cx-space-3);
  padding: var(--cx-space-3) var(--cx-space-3);
  background: var(--tg-bar);
  color: var(--tg-bar-text);
  border-bottom: 1px solid var(--tg-stroke);
  flex: none;
}
.phone-bar-avatar {
  width: 34px; height: 34px; flex: none;
  border-radius: 50%;
  background: var(--tg-accent);
  display: grid; place-items: center;
}
.phone-bar-text { min-width: 0; }
.phone-bar-name {
  font-size: var(--cx-text-sm);
  font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.phone-bar-sub {
  font-size: var(--cx-text-xs);
  color: var(--tg-bar-sub);
}

/* The message area. */
.js .phone-screen {
  /* Sized from the tallest transcript, measured with one step visible at a
     time: 577px of messages, plus the 62px chat header and the log's 12px
     padding top and bottom. 680 clears that with headroom for a font that
     loads a little wider than the one measured against. The v2 design drew
     640, which clips the photo step by 23px in these bubbles, so 680 stays;
     the cap against the viewport is the design's, less the sticky header
     and 32 above and below, so the pinned phone is never cut off. */
  height: 560px;
}
@media (min-width: 900px) {
  .js .phone-screen { height: min(680px, calc(100vh - 68px - 2 * var(--cx-space-6))); }
}

.phone-log {
  flex: 1;
  padding: var(--cx-space-3);
  display: flex;
  flex-direction: column;
  gap: var(--cx-space-2);
  overflow: hidden;
  justify-content: flex-end;
  min-height: 0;
}

/* One step of the conversation. All steps are in the HTML; the script hides
   all but the current one. Without the script, none is hidden. */
.js .phone-step { display: none; }
.js .phone-step.is-current { display: flex; }
.phone-step {
  display: flex;
  flex-direction: column;
  gap: var(--cx-space-2);
  justify-content: flex-end;
  /* Sized by its messages, not stretched to the log. The log already pushes
     it to the bottom, so stretching only pushed the first bubble off the
     top edge. */
  flex: 0 0 auto;
  margin-top: auto;
}

/* ---- Bubbles -------------------------------------------------------- */

.msg {
  max-width: 84%;
  padding: var(--cx-space-2) var(--cx-space-3);
  border-radius: 14px;
  font-size: var(--cx-text-sm);
  line-height: 1.45;
  background: var(--tg-bubble-in);
  color: var(--cx-ink);
  box-shadow: 0 1px 1px rgba(28, 25, 23, .12);
  align-self: flex-start;
  border-bottom-left-radius: 5px;
  position: relative;
}
/* A message from a person in the group, on the right, in Telegram's green. */
.msg-out {
  align-self: flex-end;
  background: var(--tg-bubble-out);
  border-bottom-left-radius: 14px;
  border-bottom-right-radius: 5px;
}
.msg-who {
  display: block;
  font-size: var(--cx-text-xs);
  font-weight: 500;
  color: var(--tg-accent-text);
  margin-bottom: 2px;
}
/* Telegram gives each sender a colour from a small set. Two people and a bot
   need two of them, so the outgoing name takes the deeper blue. */
.msg-out .msg-who { color: var(--tg-name-2); }
.msg p { margin: 0 0 .5em; max-width: none; font-size: inherit; }

/* A tagged username, which Telegram renders in its accent blue. The bot only
   answers a group message that mentions it, uses a command, or continues a
   session it already has open, so the tag is not decoration: it is the thing
   that makes the reply happen. docs/05. */
.tag { color: var(--tg-accent-text); }
.msg p:last-child { margin-bottom: 0; }
.msg-time {
  font-size: 10px;
  /* One step darker than --text-muted so it clears 7:1 on the green outgoing
     bubble as well as on white. Measured on both grounds. */
  color: var(--cx-ink-soft-bubble);
  float: right;
  margin: .4em 0 0 var(--cx-space-2);
}

/* The bot's confirmation block, which is a fixed-width list in real life. */
.msg-block {
  font-family: var(--cx-mono);
  font-size: var(--cx-text-xs);
  line-height: 1.6;
  white-space: pre-wrap;
  margin: var(--cx-space-2) 0;
  padding-left: var(--cx-space-3);
  border-left: 2px solid var(--cx-hair-strong);
  color: var(--cx-ink);
}

/* Telegram's inline keyboard, the row of buttons under a bot message. */
.msg-keys {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  margin-top: var(--cx-space-2);
}
.msg-key {
  flex: 1 1 auto;
  min-width: 88px;
  text-align: center;
  padding: var(--cx-space-2) var(--cx-space-2);
  background: rgba(0, 136, 255, .08);
  border-radius: 7px;
  font-size: var(--cx-text-xs);
  color: var(--tg-accent-text);
}

/* A photograph shared in the group, drawn rather than loaded: the page has
   to be usable with no images at all, and a real farm photo would break
   invariant 11 anyway. */
.msg-photo {
  width: 190px;
  height: 128px;
  border-radius: 10px;
  margin-bottom: var(--cx-space-2);
  display: block;
  background: var(--cx-paper-2);
}

/* ---- The explanation column ----------------------------------------- */

.walk-steps { display: flex; flex-direction: column; }

.walk-step { padding-block: var(--cx-space-6); }

/* With the script running, each step gets a screen's worth of travel, and
   the inactive ones dim so the active one is unmistakable. Colour is not the
   only signal: the active step also carries the accent rule at its left. */
@media (min-width: 900px) {
  .js .walk-step {
    min-height: 70vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-left: var(--cx-space-5);
    border-left: 2px solid transparent;
    opacity: .38;
    transition: opacity .35s ease, border-color .35s ease;
  }
  .js .walk-step.is-current { opacity: 1; border-left-color: var(--accent); }
}

@media (prefers-reduced-motion: reduce) {
  .js .walk-step { transition: none; }
}

.walk-step-n {
  font-family: var(--cx-mono);
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-muted);
  display: block;
  margin-bottom: var(--cx-space-3);
}
.walk-step h3 { font-size: clamp(24px, 3vw, 32px); margin-bottom: var(--cx-space-4); }
.walk-step p { color: var(--text-muted); }
.walk-step p strong { color: var(--text); font-weight: 500; }

/* The one fact under each step: what the software actually did. */
.walk-fact {
  margin-top: var(--cx-space-4);
  padding: var(--cx-space-3) var(--cx-space-4);
  background: var(--surface-sunk);
  border-radius: var(--cx-radius-card);
  font-size: var(--cx-text-sm);
  color: var(--text-muted);
  max-width: 52ch;
}
.walk-fact b { color: var(--text); font-weight: 500; }

/* ---- Without the script --------------------------------------------- */

/* The heading that only makes sense when every step is showing at once. */
.walk-plain-head { display: block; }
.js .walk-plain-head { display: none; }

/* Progress dots, drawn by the script only. */
.walk-dots {
  display: none;
  gap: var(--cx-space-2);
  justify-content: center;
  margin-top: var(--cx-space-4);
}
.js .walk-dots { display: none; }
@media (min-width: 900px) { .js .walk-dots { display: flex; } }
.walk-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--cx-hair-strong);
  transition: background-color .3s ease;
}
.walk-dot.is-current { background: var(--accent); }
