/* ---- The working moment ----

   The screen between the last answer and the board: four tiles assembling into
   a small board, because the thing being made IS a board of tiles and the mark
   idiom on this surface is "draw the thing that is happening" (the shield, the
   signature, the pair joining). onboarding/working.ts is the argument for the
   screen; this file is only how it moves.

   ONE CLOCK, THE WAITS INSIDE THE KEYFRAMES. The assembly runs once on the
   mark's own run token, holding through the card's entrance exactly as the
   join mark next door holds (console-settle-team.css tells the story of the
   strokes that once drew in mid-air). After the assembly, a quiet breathing
   loop takes over, so an arranger that takes longer than the dwell still
   reads as alive rather than frozen. */

.cb-work-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  block-size: var(--cb-space-9xl);
}

.cb-work-board {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--cb-space-sm);
  inline-size: var(--cb-space-8xl);
  block-size: var(--cb-space-8xl);
  /* The breath starts only after the tiles have landed: the hold is the first
     sixth of its first cycle, which the assembly has finished inside. */
  animation: cbc-work-breathe calc(var(--cbc-mark-run) * 2) var(--cb-motion-ease)
    var(--cbc-mark-run) infinite;
}

.cb-work-tile {
  border-radius: var(--cb-radius-lg);
  background: color-mix(in srgb, var(--cbc-accent) 18%, var(--cbc-surface));
  border: 1px solid color-mix(in srgb, var(--cbc-accent) 34%, transparent);
  opacity: 0;
  animation: cbc-work-place var(--cbc-mark-run) var(--cbc-spring) forwards;
}
/* The four arrive one after another, each on the same clock with its own slice
   of it: the offsets live in the keyframe percentages of ONE animation per
   tile rather than in animation-delay, for the one-clock rule every mark on
   this surface follows. Four names is the cost; a delayed first paint showing
   four finished tiles was the bug it buys out. */
.cb-work-tile:nth-child(1) {
  animation-name: cbc-work-place;
}
.cb-work-tile:nth-child(2) {
  animation-name: cbc-work-place-2;
}
.cb-work-tile:nth-child(3) {
  animation-name: cbc-work-place-3;
}
.cb-work-tile:nth-child(4) {
  animation-name: cbc-work-place-4;
}
/* One tile is the accent said louder: the board the answers build has one
   card that matters most, and a mark where every tile is equal is a spinner
   with corners. */
.cb-work-tile:nth-child(1) {
  background: color-mix(in srgb, var(--cbc-accent) 82%, var(--cbc-surface));
  border-color: transparent;
}

/* Each tile: held out through the entrance window (the card is still arriving,
   console-settle-team.css says why), then dropped into place with a small
   rise, the whole set resolved by three quarters of the clock. */
@keyframes cbc-work-place {
  0%,
  26% {
    opacity: 0;
    transform: translateY(calc(var(--cb-space-md) * -1)) scale(0.92);
  }
  44%,
  100% {
    opacity: 1;
    transform: none;
  }
}
@keyframes cbc-work-place-2 {
  0%,
  36% {
    opacity: 0;
    transform: translateY(calc(var(--cb-space-md) * -1)) scale(0.92);
  }
  54%,
  100% {
    opacity: 1;
    transform: none;
  }
}
@keyframes cbc-work-place-3 {
  0%,
  46% {
    opacity: 0;
    transform: translateY(calc(var(--cb-space-md) * -1)) scale(0.92);
  }
  64%,
  100% {
    opacity: 1;
    transform: none;
  }
}
@keyframes cbc-work-place-4 {
  0%,
  56% {
    opacity: 0;
    transform: translateY(calc(var(--cb-space-md) * -1)) scale(0.92);
  }
  74%,
  100% {
    opacity: 1;
    transform: none;
  }
}

/* The waiting breath: barely there, and only while the screen is. */
@keyframes cbc-work-breathe {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.03);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cb-work-board {
    animation: none;
  }
  .cb-work-tile {
    animation: none;
    opacity: 1;
  }
}
:root[data-motion="reduced"] .cb-work-board {
  animation: none;
}
:root[data-motion="reduced"] .cb-work-tile {
  animation: none;
  opacity: 1;
}

/* ---- What is being done, a line at a time ----

   Under the standfirst, saying which part of the work is happening now. Every
   line is something that is actually going on while the screen is up
   (onboarding/working-words.ts is the argument, and the rule); this file is
   only how one gives way to the next.

   TWO SPANS STACKED, ONE MARKED. The script loads the waiting span and moves
   the mark; the crossover is entirely here. That is what keeps a text swap out
   of the script's hands: no inline style, no forced reflow to restart an
   animation, and one place to change how it moves.

   THE HEIGHT IS HELD, or the standfirst above it would step up and down by a
   line every time a longer sentence gave way to a shorter one. One line's
   worth, reserved, whatever is in it. */

.cb-work-words {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--cb-space-sm);
  margin-block: calc(var(--cb-space-md) * -1) var(--cb-space-lg);
  color: var(--cbc-ink-faint);
  font-size: var(--cb-type-sm-size);
}

/* ---- The sweet ----
   Rocks twice as though it were being worked loose, then rolls right over, and
   again for as long as the screen is up. One element and one keyframe set: it
   is a mark that is enjoyed rather than read, which is why it is out of the
   accessibility tree with everything else in this strip.

   The calm loop rather than a duration of its own. That token is already named
   for exactly this, "a mark that breathes rather than works", and a second
   number here would be a second rhythm to keep in step with the first. */
.cb-work-sweet {
  display: inline-flex;
  flex: none;
  color: var(--cbc-accent);
  animation: cbc-work-sweet var(--cbc-loop-calm) var(--cb-motion-ease) infinite;
}
.cb-work-sweet svg {
  /* Sized off the line it sits beside rather than off the spacing scale, so it
     holds its proportion to the words at every size the strip is drawn at. */
  inline-size: 1.15em;
  block-size: 1.15em;
}

@keyframes cbc-work-sweet {
  /* Worked loose. */
  0%,
  6% {
    transform: rotate(0deg) translateY(0);
  }
  14% {
    transform: rotate(-15deg) translateY(-8%);
  }
  23% {
    transform: rotate(13deg) translateY(0);
  }
  31% {
    transform: rotate(-9deg) translateY(-5%);
  }
  38% {
    transform: rotate(0deg) translateY(0);
  }
  /* And over it goes. */
  56% {
    transform: rotate(190deg) translateY(-14%);
  }
  72%,
  100% {
    transform: rotate(360deg) translateY(0);
  }
}

/* ---- The words ----
   THE WIDTH IS HELD, not just the height, and the sweet is why. A box that grew
   and shrank with each line would drag the mark beside it left and right on
   every turnover, which is the one thing here that should be perfectly still.

   MEASURED RATHER THAN RESERVED. Every line is drawn into the same grid cell
   and only one is shown (working.ts), so the box is exactly as wide as the
   longest line and stays there. The first version guessed a width in `ch`,
   which was both a number somebody would have to keep in step with the copy and
   wrong: it left the sweet sitting half an inch away from the words. */
.cb-work-said {
  position: relative;
  display: grid;
  min-block-size: 1lh;
  text-align: center;
}

/* All in the same cell, so none is in another's way and the strip is as tall
   as one line rather than as a stack of them. */
.cb-work-word {
  grid-area: 1 / 1;
  opacity: 0;
  /* An em rather than a step off the spacing scale: the distance a line of type
     rises should be a fraction of the line, not a fixed gap, so it holds at
     every size this strip is drawn at. */
  transform: translateY(0.4em);
  transition:
    opacity var(--cb-motion-base) var(--cbc-spring),
    transform var(--cb-motion-base) var(--cbc-spring);
}
.cb-work-word[data-show] {
  opacity: 1;
  transform: none;
}

/* Nothing crosses over and nothing rolls: the script stops rotating under
   reduced motion and the first line simply stands there, beside a sweet that
   is a picture rather than a performance. */
@media (prefers-reduced-motion: reduce) {
  .cb-work-word {
    transition: none;
  }
  .cb-work-sweet {
    animation: none;
  }
}
:root[data-motion="reduced"] .cb-work-word {
  transition: none;
}
:root[data-motion="reduced"] .cb-work-sweet {
  animation: none;
}
