/* The Claude desktop app is drawn in its own warm palette, the same one the
   agent prompt boxes use (app/shared/styles/agent-prompt.css), so it reads as
   Claude and not as our page. */
/* The step and its controls above the window, full width. */
.storyboard {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.storyboard-side {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.storyboard-nav {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}

.storyboard-arrow {
  display: inline-grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid var(--rule, #c3cad3);
  border-radius: 999px;
  background: var(--paper, #fff);
  color: var(--ink);
  cursor: pointer;
}

.storyboard-arrow:hover:not(:disabled) {
  border-color: var(--ink);
}

.storyboard-arrow:disabled {
  opacity: 0.35;
  cursor: default;
}

.storyboard-arrow svg {
  width: 16px;
  height: 16px;
}

.storyboard-current {
  display: flex;
  gap: var(--space-4);
}

/* Five dots on a vertical line: done steps filled, the current one ringed. */
.storyboard-rail {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.storyboard-rail::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 6px;
  bottom: 6px;
  width: 1px;
  background: var(--rule, #d9dde3);
}

.storyboard-dot {
  position: relative;
  display: grid;
  place-items: center;
  width: 14px;
  height: 14px;
  cursor: pointer;
}

.storyboard-dot i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--paper, #fff);
  border: 1.5px solid var(--rule, #c3cad3);
}

.storyboard-dot.is-done i {
  background: var(--ink);
  border-color: var(--ink);
}

.storyboard-dot.is-on i {
  width: 11px;
  height: 11px;
  background: #1f8a43;
  border-color: #1f8a43;
  box-shadow: 0 0 0 3px rgba(31, 138, 67, 0.25);
}

/* One step at a time. Fixed height, so the arrows never move. */
.storyboard-text {
  flex: 1;
  min-width: 0;
  min-height: 6.5rem;
  animation: storyboard-in 350ms ease-out;
}

@keyframes storyboard-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.storyboard-count {
  display: block;
  font-size: 0.8125rem;
  font-weight: var(--weight-semibold);
  letter-spacing: 0.02em;
  color: var(--ink-faint, #8a96a3);
}

.storyboard-title {
  margin: var(--space-1) 0 var(--space-2);
  font-size: 1.375rem;
  font-weight: var(--weight-bold);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.storyboard-say {
  margin: 0;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.storyboard-app {
  display: flex;
  flex-direction: column;
  height: 38rem;
  border: 1px solid #e0ded8;
  border-radius: 14px;
  background: #faf9f7;
  box-shadow: 0 16px 40px rgba(31, 30, 27, 0.12);
  overflow: hidden;
  color: #1f1e1b;
  cursor: pointer;
  font-size: 0.9375rem;
}

.storyboard-app svg {
  width: 17px;
  height: 17px;
  flex: none;
}

.sb-titlebar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.7rem 0.9rem;
  color: #3d3c38;
}

.sb-lights {
  display: inline-flex;
  gap: 7px;
}

.sb-lights i {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: #dcdad4;
}

.sb-tools {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
}

.sb-tools .is-dim {
  color: #b3b1aa;
}

.sb-tools.is-right {
  margin-left: auto;
  gap: 0.85rem;
}

.sb-tool-on {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 26px;
  border-radius: 6px;
  background: #dbe7fb;
  color: #2b62b8;
}

.sb-title {
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-weight: var(--weight-semibold);
  font-size: 0.9375rem;
}

.sb-title svg {
  width: 14px;
  height: 14px;
}

/* The conversation keeps its newest message in view, as a chat does. */
.storyboard-chat {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.85rem;
  padding: 1rem 1.6rem 0.75rem;
  overflow: hidden;
  line-height: 1.5;
}

.storyboard-chat > * {
  flex: none;
}

.sb-you {
  align-self: flex-end;
  max-width: 80%;
  padding: 0.55rem 0.9rem;
  border-radius: 12px;
  background: #efedea;
}

.sb-activity {
  color: #8a8880;
}

.sb-claude {
  margin: 0;
}

.sb-link {
  color: #2b62b8;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* The diagnostic rising out of the Elements panel into the conversation. */
.storyboard-payload {
  border: 1px solid #dcdad4;
  border-radius: 10px;
  background: #fff;
  overflow: hidden;
  animation: storyboard-rise 700ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

@keyframes storyboard-rise {
  from {
    opacity: 0;
    transform: translateY(120px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.storyboard-payload-head {
  padding: 0.35rem 0.75rem;
  border-bottom: 1px solid #ebe9e3;
  background: #f5f4f0;
  font-size: 0.75rem;
  font-weight: var(--weight-semibold);
  color: #6f6d67;
}

.storyboard-payload-body {
  margin: 0;
  padding: 0.55rem 0.75rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  line-height: 1.45;
  white-space: pre-wrap;
  word-break: break-word;
  color: #1f1e1b;
  background: transparent;
}

.sb-composer {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 1.1rem;
  padding: 0.75rem 1rem;
  border: 1px solid #dcdad4;
  border-radius: 14px;
  background: #fff;
  color: #8a8880;
}

.sb-plus {
  font-size: 1.25rem;
  line-height: 1;
  color: #6f6d67;
}

.sb-placeholder {
  flex: 1;
  color: #a3a19a;
}

.sb-status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.55rem 1.6rem 0.75rem;
  font-size: 0.8125rem;
  color: #6f6d67;
}

.sb-status-right {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.sb-status .is-dim {
  color: #a3a19a;
}

.sb-ring {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 2px solid #c9c7c0;
  border-top-color: #4a8fe0;
}

/* The Elements terminal panel, a white card docked under the composer. */
.sb-term {
  flex: none;
  margin: 0 0.6rem 0.6rem;
  border: 1px solid #e0ded8;
  border-radius: 12px;
  background: #fff;
}

.sb-term-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.55rem 0.9rem 0.25rem;
  color: #3d3c38;
}

.sb-term-tab {
  font-size: 0.875rem;
}

.sb-term-plus {
  font-size: 1.1rem;
  line-height: 1;
}

.sb-term-tools {
  display: inline-flex;
  gap: 0.75rem;
  margin-left: auto;
}

.sb-term-tools svg {
  width: 15px;
  height: 15px;
}

.sb-term-body {
  padding: 0.35rem 0.9rem 0.75rem;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: #3d3c38;
}

.sb-row {
  display: grid;
  grid-template-columns: 5.5em 1fr;
}

.sb-row b {
  font-weight: var(--weight-bold);
}

.sb-ok {
  color: #3a9d3a;
  font-weight: var(--weight-bold);
}

.sb-err {
  color: #c62828;
  font-weight: var(--weight-bold);
}

.sb-busy {
  color: #8a8880;
  font-weight: var(--weight-bold);
}





@media (max-width: 760px) {
  .storyboard-app {
    height: 36rem;
    font-size: 0.875rem;
  }

  .sb-tools {
    display: none;
  }

  .storyboard-chat {
    padding: 0.75rem 1rem 0.5rem;
  }

  .sb-status {
    padding: 0.5rem 1rem 0.6rem;
  }

  .storyboard-text {
    min-height: 8rem;
  }
}

/* The Elements panel in the terminal's dark theme, so it reads as a
   different surface from Claude's composer above it. */
.sb-term {
  border-color: #2a2c31;
  background: #1b1c20;
}

.sb-term-head {
  color: #c9ccd2;
}

.sb-term-body {
  color: #d7dae0;
}

.sb-ok {
  color: #4ade80;
}

.sb-err {
  color: #f87171;
}

.sb-busy {
  color: #9aa1ab;
}

/* The guidance sits in its own panel, set apart from the heading above and
   the window below. */
.storyboard-side {
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--rule, #d9dde3);
  border-radius: 12px;
  background: var(--tint, #f4f6f8);
}

.storyboard-text {
  min-height: 0;
}

.storyboard {
  gap: var(--space-5);
}

/* Clean JSON: one line per field, never wrapped. A long line runs under a
   fade on the right instead. */
.storyboard-payload-body {
  white-space: pre;
  word-break: normal;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, #000 82%, transparent);
          mask-image: linear-gradient(to right, #000 82%, transparent);
}

/* The down arrow pulses until the visitor clicks, so the next move is
   obvious. */
.storyboard-arrow.is-pulsing {
  border-color: #1f8a43;
  color: #17733a;
  animation: storyboard-pulse 1.6s ease-out infinite;
}

@keyframes storyboard-pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(31, 138, 67, 0.45);
  }

  70% {
    box-shadow: 0 0 0 10px rgba(31, 138, 67, 0);
  }

  100% {
    box-shadow: 0 0 0 0 rgba(31, 138, 67, 0);
  }
}

/* The widget as one unit: the guidance and the window on a single grey
   surface. The guidance panel turns white on it. */
.storyboard {
  --sb-pad: var(--space-6);
  padding: var(--sb-pad);
  border-radius: 18px;
  background: #eef0f3;
}

.storyboard-side {
  background: var(--paper, #fff);
  border-color: #e1e4e8;
}

@media (max-width: 760px) {
  .storyboard {
    --sb-pad: var(--space-3);
    border-radius: 14px;
  }
}

/* The guidance sits straight on the grey surface, no card of its own. */
.storyboard-side {
  padding: 0 var(--space-1);
  border: 0;
  background: transparent;
}

/* The widget's own heading, inside the grey surface. */
.storyboard-heading {
  margin: 0;
  font-family: var(--font-sans);
  font-size: clamp(1.25rem, 2.5vw, 1.5rem);
  font-weight: var(--weight-bold);
  line-height: 1.25;
  letter-spacing: -0.015em;
  color: var(--ink);
}

/* One left and right edge for everything in the window: the chat, the
   JSON card, the composer, the status row and the Elements panel all sit
   the same distance in. */
.storyboard-app {
  --sb-inset: 1.1rem;
}

.storyboard-chat {
  padding-left: var(--sb-inset);
  padding-right: var(--sb-inset);
}

.sb-composer {
  margin-left: var(--sb-inset);
  margin-right: var(--sb-inset);
}

.sb-status {
  padding-left: var(--sb-inset);
  padding-right: var(--sb-inset);
}

.sb-term {
  margin: 0 var(--sb-inset) var(--sb-inset);
}

@media (max-width: 760px) {
  .storyboard-app {
    --sb-inset: 0.75rem;
  }
}

/* Each step lights what it is about and quiets the rest: the prompt, then
   the Elements panel turning red, then the JSON, then Claude's fix, then the
   green panel and the result. The composer and status row never matter to
   the story, so they stay quiet. */
.storyboard-chat > *,
.sb-composer,
.sb-status,
.sb-term {
  transition: opacity 300ms ease;
}

.storyboard-chat > *,
.sb-term {
  opacity: 0.35;
}

.sb-composer,
.sb-status {
  opacity: 0.4;
}

.storyboard-app[data-step="0"] .sb-f0,
.storyboard-app[data-step="1"] .sb-f1,
.storyboard-app[data-step="2"] .sb-f2,
.storyboard-app[data-step="3"] .sb-f3,
.storyboard-app[data-step="4"] .sb-f4 {
  opacity: 1;
}

/* The diagnostic on its way: a track from the top of the Elements panel to
   the JSON card, with dots running up it and an arrowhead at the top. It
   crosses the composer, which is faded on that step, so it reads on top. */
.sb-bottom {
  position: relative;
}

.sb-stream {
  position: absolute;
  left: 50%;
  margin-left: -7px;
  top: -0.75rem;
  bottom: -0.25rem;
  width: 14px;
  z-index: 2;
  pointer-events: none;
  /* One pass, then the track fades away. */
  animation: sb-stream-out 0.4s ease 2.1s forwards;
}

@keyframes sb-stream-out {
  to {
    opacity: 0;
  }
}

.sb-stream::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 6px;
  bottom: 0;
  width: 2px;
  transform: translateX(-50%);
  background: linear-gradient(to top, rgba(31, 138, 67, 0.15), rgba(31, 138, 67, 0.6));
  border-radius: 2px;
}

.sb-stream::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  width: 10px;
  height: 10px;
  border-left: 2px solid #1f8a43;
  border-top: 2px solid #1f8a43;
  transform: translateX(-50%) rotate(45deg);
}

.sb-stream i {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 8px;
  height: 8px;
  margin-left: -4px;
  border-radius: 50%;
  background: #1f8a43;
  box-shadow: 0 0 0 3px rgba(31, 138, 67, 0.18);
  animation: sb-travel 1.2s cubic-bezier(0.4, 0, 0.6, 1) 1 both;
  opacity: 0;
}

.sb-stream i:nth-child(2) {
  animation-delay: 0.3s;
}

.sb-stream i:nth-child(3) {
  animation-delay: 0.6s;
}

@keyframes sb-travel {
  0% {
    bottom: 0;
    opacity: 0;
  }

  15% {
    opacity: 1;
  }

  85% {
    opacity: 1;
  }

  100% {
    bottom: calc(100% - 10px);
    opacity: 0;
  }
}

/* Experiment: white surface with a border instead of the grey. */
.storyboard {
  background: var(--paper, #fff);
  border: 1px solid var(--rule, #d9dde3);
}

/* The frame stays quieter than the window inside it: a lighter line and a
   tighter corner, so it reads as a section edge and the window reads as
   the object. */
.storyboard {
  border-color: #e6e9ed;
  border-radius: 10px;
}

/* Experiment: no frame at all. The padding goes too, so the steps and the
   window line up with the hero copy above. */
.storyboard {
  border: 0;
  padding: 0;
}

/* On the page band, the widget has no surface of its own. */
.storyboard,
.storyboard-side,
.storyboard-arrow {
  background: transparent;
}

/* Big enough to catch the eye, well under the hero's size. */
.storyboard-heading {
  font-size: clamp(1.75rem, 4.5vw, 2.75rem);
  line-height: 1.1;
  letter-spacing: -0.025em;
}

/* Tighter: the window only as tall as its busiest frame needs, and less
   air between the parts, so the next section shows on a laptop. */
.storyboard {
  gap: var(--space-4);
}

.storyboard-app {
  height: 31rem;
}

.storyboard-chat {
  gap: 0.6rem;
  padding-top: 0.5rem;
}

.storyboard-payload-body {
  line-height: 1.35;
  padding-top: 0.45rem;
  padding-bottom: 0.45rem;
}

.sb-titlebar {
  padding-top: 0.55rem;
  padding-bottom: 0.55rem;
}

.sb-composer {
  padding-top: 0.6rem;
  padding-bottom: 0.6rem;
}

.sb-status {
  padding-top: 0.4rem;
  padding-bottom: 0.55rem;
}

.sb-term-body {
  padding-bottom: 0.6rem;
}

.storyboard-text {
  min-height: 0;
}

.storyboard-rail {
  gap: 0.25rem;
}

@media (max-width: 760px) {
  .storyboard-app {
    height: 30rem;
  }
}

/* The order on this frame: the dots leave the Elements panel and run up to
   Claude, and only when they arrive does the JSON appear, so the eye
   follows the dots to it. Then the track fades. */
.storyboard-payload {
  animation: sb-arrive 450ms cubic-bezier(0.2, 0.8, 0.2, 1) 1.35s both;
}

@keyframes sb-arrive {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.98);
    box-shadow: 0 0 0 0 rgba(31, 138, 67, 0);
  }

  60% {
    box-shadow: 0 0 0 6px rgba(31, 138, 67, 0.22);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
    box-shadow: 0 0 0 0 rgba(31, 138, 67, 0);
  }
}

/* The track sits over the space the JSON is about to fill, so it reaches
   from the Elements panel to where the card lands. */
.sb-stream {
  top: -6rem;
  animation: sb-stream-out 0.25s ease 1.15s forwards;
}

.sb-stream i {
  animation: sb-travel 1s cubic-bezier(0.4, 0, 0.6, 1) 1 both;
}

.sb-stream i:nth-child(2) {
  animation-delay: 0.15s;
}

.sb-stream i:nth-child(3) {
  animation-delay: 0.3s;
}



/* The panel sending it gives a green pulse as the dots leave. */
.storyboard-app[data-step="2"] .sb-term {
  animation: sb-send 0.8s ease-out 1;
}

@keyframes sb-send {
  0% {
    box-shadow: 0 0 0 0 rgba(31, 138, 67, 0.5);
  }

  100% {
    box-shadow: 0 0 0 10px rgba(31, 138, 67, 0);
  }
}

/* The line grows out of the Elements panel toward Claude, its arrowhead
   riding the tip, and the JSON lands when it arrives. Nothing is drawn
   before it starts. */
.sb-stream {
  animation: sb-stream-out 0.2s ease 0.7s forwards;
}

.sb-stream::before {
  top: auto;
  bottom: 0;
  height: 0;
  background: #1f8a43;
  animation: sb-grow 0.6s cubic-bezier(0.3, 0, 0.2, 1) forwards;
}

.sb-stream::after {
  top: auto;
  bottom: 0;
  transform: translate(-50%, 4px) rotate(45deg);
  opacity: 0;
  animation: sb-tip 0.6s cubic-bezier(0.3, 0, 0.2, 1) forwards;
}

@keyframes sb-grow {
  from {
    height: 0;
  }

  to {
    height: 100%;
  }
}

@keyframes sb-tip {
  0% {
    bottom: 0;
    opacity: 1;
  }

  100% {
    bottom: calc(100% - 8px);
    opacity: 1;
  }
}

.storyboard-payload {
  animation-duration: 350ms;
  animation-delay: 0.65s;
}

.storyboard-app[data-step="2"] .sb-term {
  animation-duration: 0.5s;
}

/* Frame 3, in order:
   1. The Elements panel lights up with a green pulse.
   2. It fades back, and dots run up from it to the bottom edge of the
      JSON card, which waits faded.
   3. The card flashes green and comes to full weight: the eye ends on the
      JSON.
   Each part runs once. */
.storyboard-app[data-step="2"] .sb-term {
  animation:
    sb-send 0.5s ease-out 0s 1,
    sb-term-fade 0.3s ease 0.45s both;
}

@keyframes sb-term-fade {
  from {
    opacity: 1;
  }

  to {
    opacity: 0.35;
  }
}

.sb-stream {
  top: -0.75rem;
  bottom: 0;
  animation: sb-stream-out 0.2s ease 1.15s forwards;
}

.sb-stream::before {
  height: auto;
  top: 0;
  bottom: 0;
  width: 0;
  background: none;
  border-left: 2px dotted rgba(31, 138, 67, 0.35);
  animation: none;
}

.sb-stream::after {
  display: none;
}

.sb-stream i {
  animation: sb-travel 0.6s cubic-bezier(0.4, 0, 0.6, 1) 1 both;
}

.sb-stream i:nth-child(1) {
  animation-delay: 0.45s;
}

.sb-stream i:nth-child(2) {
  animation-delay: 0.57s;
}

.sb-stream i:nth-child(3) {
  animation-delay: 0.69s;
}

@keyframes sb-travel {
  0% {
    bottom: 0;
    opacity: 0;
  }

  15% {
    opacity: 1;
  }

  90% {
    opacity: 1;
  }

  100% {
    bottom: calc(100% - 4px);
    opacity: 0;
  }
}

.storyboard-app[data-step="2"] .storyboard-payload {
  opacity: 0.35;
  transform: none;
  animation: sb-focus 0.5s ease-out 1.15s both;
}

@keyframes sb-focus {
  0% {
    opacity: 0.35;
    box-shadow: 0 0 0 0 rgba(31, 138, 67, 0.55);
    border-color: #dcdad4;
  }

  40% {
    opacity: 1;
    border-color: #1f8a43;
    box-shadow: 0 0 0 6px rgba(31, 138, 67, 0.25);
  }

  100% {
    opacity: 1;
    border-color: #dcdad4;
    box-shadow: 0 0 0 0 rgba(31, 138, 67, 0);
  }
}

/* No pulse on the Elements panel: it is already lit. It stays at full
   weight while the dots travel, and steps back only as the JSON takes
   focus. */
.storyboard-app[data-step="2"] .sb-term {
  animation: sb-term-fade 0.3s ease 1.15s both;
}

/* Frame 1 starts in the composer, the prompt written and not yet sent. It
   moves into the conversation on frame 2. Nothing animates here, so the
   hero keeps the eye. */
.storyboard-app[data-step="0"] .sb-composer {
  opacity: 1;
  border-color: #b9b6ad;
  box-shadow: 0 2px 10px rgba(31, 30, 27, 0.08);
}

.sb-typed {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  color: #1f1e1b;
}

/* The step row under the window: text on the left, back, dots and next in
   one horizontal row on the right. */
.storyboard-side {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-6);
  padding: 0;
}

.storyboard-text {
  flex: 1;
  min-width: 0;
  min-height: 5.75rem;
}

.storyboard-nav {
  flex: none;
  flex-direction: row;
  align-items: center;
  gap: var(--space-3);
  padding-top: var(--space-1);
}

.storyboard-rail {
  flex-direction: row;
  gap: 0.35rem;
}

.storyboard-rail::before {
  left: 6px;
  right: 6px;
  top: 50%;
  bottom: auto;
  width: auto;
  height: 1px;
  transform: none;
}

@media (max-width: 760px) {
  .storyboard-side {
    flex-direction: column;
    gap: var(--space-3);
  }

  .storyboard-nav {
    align-self: stretch;
    justify-content: space-between;
  }
}

.storyboard-heading {
  margin-bottom: var(--space-3);
}

/* Shorter still, so the step row clears a laptop screen under the hero. */
.storyboard-app {
  height: 27rem;
}

/* Small enough that the card fits the window whole on every screen. Its
   shape says "structured message"; nobody needs to read every field. */
.storyboard-payload-body {
  font-size: 0.625rem;
  line-height: 1.4;
  padding: 0.4rem 0.7rem;
}

.storyboard-payload-head {
  padding: 0.3rem 0.7rem;
  font-size: 0.6875rem;
}

/* Upcoming steps were white rings on a white page; give them a visible
   edge. */
.storyboard-dot i {
  border-color: #aeb7c2;
}

/* The error travelling to Claude is red, like the build state it comes
   from: the dots, their track, and the flash on the JSON card. */
.sb-stream::before {
  border-left-color: rgba(220, 38, 38, 0.35);
}

.sb-stream i {
  background: #dc2626;
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.18);
}

.storyboard-app[data-step="2"] .storyboard-payload {
  animation-name: sb-focus-red;
}

@keyframes sb-focus-red {
  0% {
    opacity: 0.35;
    box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.5);
    border-color: #dcdad4;
  }

  40% {
    opacity: 1;
    border-color: #dc2626;
    box-shadow: 0 0 0 6px rgba(220, 38, 38, 0.22);
  }

  100% {
    opacity: 1;
    border-color: #dcdad4;
    box-shadow: 0 0 0 0 rgba(220, 38, 38, 0);
  }
}

/* Dark mode: the Claude window in Claude's own dark theme. */
@media (prefers-color-scheme: dark) {

  :root:not([data-theme="light"]) .storyboard-app {
    background: #262624;
    border-color: #3a3a37;
    color: #ecebe6;
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
  }

  :root:not([data-theme="light"]) .sb-titlebar {
    color: #c9c7c0;
  }

  :root:not([data-theme="light"]) .sb-lights i {
    background: #4a4a46;
  }

  :root:not([data-theme="light"]) .sb-tools .is-dim {
    color: #6f6d67;
  }

  :root:not([data-theme="light"]) .sb-tool-on {
    background: #23395c;
    color: #8db4f0;
  }

  :root:not([data-theme="light"]) .sb-you {
    background: #141413;
  }

  :root:not([data-theme="light"]) .sb-activity {
    color: #8f8d86;
  }

  :root:not([data-theme="light"]) .sb-link {
    color: #8db4f0;
  }

  :root:not([data-theme="light"]) .storyboard-payload {
    background: #1f1f1d;
    border-color: #3a3a37;
  }

  :root:not([data-theme="light"]) .storyboard-payload-head {
    background: #2b2b29;
    border-bottom-color: #3a3a37;
    color: #a3a19a;
  }

  :root:not([data-theme="light"]) .storyboard-payload-body {
    color: #ecebe6;
  }

  :root:not([data-theme="light"]) .sb-composer {
    background: #30302e;
    border-color: #45453f;
    color: #8f8d86;
  }

  :root:not([data-theme="light"]) .sb-typed {
    color: #ecebe6;
  }

  :root:not([data-theme="light"]) .storyboard-app[data-step="0"] .sb-composer {
    border-color: #6a6862;
  }

  :root:not([data-theme="light"]) .sb-status {
    color: #8f8d86;
  }

  :root:not([data-theme="light"]) .sb-term {
    background: #141413;
    border-color: #2f2f2c;
  }

  :root:not([data-theme="light"]) .storyboard-arrow {
    border-color: #3a4756;
  }

  :root:not([data-theme="light"]) .storyboard-dot i {
    border-color: #5b6878;
  }
}

:root[data-theme="dark"] .storyboard-app {
  background: #262624;
  border-color: #3a3a37;
  color: #ecebe6;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
}

:root[data-theme="dark"] .sb-titlebar {
  color: #c9c7c0;
}

:root[data-theme="dark"] .sb-lights i {
  background: #4a4a46;
}

:root[data-theme="dark"] .sb-tools .is-dim {
  color: #6f6d67;
}

:root[data-theme="dark"] .sb-tool-on {
  background: #23395c;
  color: #8db4f0;
}

:root[data-theme="dark"] .sb-you {
  background: #141413;
}

:root[data-theme="dark"] .sb-activity {
  color: #8f8d86;
}

:root[data-theme="dark"] .sb-link {
  color: #8db4f0;
}

:root[data-theme="dark"] .storyboard-payload {
  background: #1f1f1d;
  border-color: #3a3a37;
}

:root[data-theme="dark"] .storyboard-payload-head {
  background: #2b2b29;
  border-bottom-color: #3a3a37;
  color: #a3a19a;
}

:root[data-theme="dark"] .storyboard-payload-body {
  color: #ecebe6;
}

:root[data-theme="dark"] .sb-composer {
  background: #30302e;
  border-color: #45453f;
  color: #8f8d86;
}

:root[data-theme="dark"] .sb-typed {
  color: #ecebe6;
}

:root[data-theme="dark"] .storyboard-app[data-step="0"] .sb-composer {
  border-color: #6a6862;
}

:root[data-theme="dark"] .sb-status {
  color: #8f8d86;
}

:root[data-theme="dark"] .sb-term {
  background: #141413;
  border-color: #2f2f2c;
}

:root[data-theme="dark"] .storyboard-arrow {
  border-color: #3a4756;
}

:root[data-theme="dark"] .storyboard-dot i {
  border-color: #5b6878;
}

/* The step text reserves two lines for the sentence whatever its length,
   so the section never changes height between steps. */
.storyboard-say {
  min-height: calc(2 * 1.5em);
}

@media (max-width: 760px) {
  .storyboard-say {
    min-height: calc(3 * 1.5em);
  }
}

/* Tighter window: only as tall as the last step's conversation needs. The
   JSON no longer takes room in the chat. It floats over it as its own
   window, rising from the composer's edge, and may rise past the top of
   the Claude window. */
.storyboard-app {
  height: 23rem;
  overflow: visible;
}

.storyboard-chat {
  position: relative;
  overflow: visible;
}

.storyboard-chat > :not(.storyboard-payload) {
  position: relative;
  z-index: 0;
}

.storyboard-payload {
  position: absolute;
  left: 8%;
  right: 8%;
  bottom: 0.25rem;
  z-index: 3;
  box-shadow: 0 18px 44px rgba(31, 30, 27, 0.22), 0 2px 6px rgba(31, 30, 27, 0.08);
}

/* The window's own corners, now that its children are no longer clipped. */
.sb-titlebar {
  border-radius: 14px 14px 0 0;
}

@media (max-width: 760px) {
  .storyboard-app {
    height: 24rem;
  }

  .storyboard-payload {
    left: 3%;
    right: 3%;
  }
}

/* Room for the last step's conversation under the title bar. */
.storyboard-app {
  height: 25rem;
}

@media (max-width: 760px) {
  .storyboard-app {
    height: 26rem;
  }
}

/* The JSON window: a plain white card, at full strength the moment it
   lands, with a deep shadow so it stands well clear of the dimmed window
   behind it. Only the red ring flashes. */
.storyboard-app[data-step="2"] .storyboard-payload {
  opacity: 1;
  background: #fff;
  border: 1px solid #e4e2dc;
  border-radius: 10px;
  box-shadow: 0 24px 60px rgba(31, 30, 27, 0.30), 0 4px 12px rgba(31, 30, 27, 0.12);
  animation: sb-land 0.5s ease-out 1.15s both;
}

@keyframes sb-land {
  0% {
    opacity: 0;
    transform: translateY(10px);
    border-color: #dc2626;
  }

  1% {
    opacity: 1;
  }

  40% {
    transform: translateY(0);
    border-color: #dc2626;
  }

  100% {
    opacity: 1;
    transform: translateY(0);
    border-color: #e4e2dc;
  }
}

.storyboard-payload-body {
  padding: 0.75rem 0.9rem;
  color: #1f1e1b;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .storyboard-app[data-step="2"] .storyboard-payload {
    background: #fff;
    border-color: #e4e2dc;
  }

  :root:not([data-theme="light"]) .storyboard-payload-body {
    color: #1f1e1b;
  }
}

:root[data-theme="dark"] .storyboard-app[data-step="2"] .storyboard-payload {
  background: #fff;
  border-color: #e4e2dc;
}

:root[data-theme="dark"] .storyboard-payload-body {
  color: #1f1e1b;
}

/* Hidden until the dots arrive, then there all at once: no fade, no slide.
   Only the red ring flashes after it appears. */
.storyboard-app[data-step="2"] .storyboard-payload {
  animation:
    sb-appear 0s linear 1.15s both,
    sb-ring 0.6s ease-out 1.15s both;
}

@keyframes sb-appear {
  from {
    visibility: hidden;
  }

  to {
    visibility: visible;
  }
}

@keyframes sb-ring {
  0% {
    border-color: #dc2626;
    box-shadow: 0 0 0 4px rgba(220, 38, 38, 0.35), 0 24px 60px rgba(31, 30, 27, 0.30);
  }

  100% {
    border-color: #e4e2dc;
    box-shadow: 0 0 0 0 rgba(220, 38, 38, 0), 0 24px 60px rgba(31, 30, 27, 0.30), 0 4px 12px rgba(31, 30, 27, 0.12);
  }
}

/* One quick pass: three dots race up together in 0.35s, and the JSON is
   there the instant they arrive. */
.sb-stream i {
  animation: sb-travel 0.35s cubic-bezier(0.5, 0, 0.9, 0.6) 1 both;
}

.sb-stream i:nth-child(1) {
  animation-delay: 0s;
}

.sb-stream i:nth-child(2) {
  animation-delay: 0.05s;
}

.sb-stream i:nth-child(3) {
  animation-delay: 0.1s;
}

.sb-stream {
  animation: sb-stream-out 0.15s ease 0.45s forwards;
}

.storyboard-app[data-step="2"] .storyboard-payload {
  animation:
    sb-appear 0s linear 0.45s both,
    sb-ring 0.5s ease-out 0.45s both;
}

.storyboard-app[data-step="2"] .sb-term {
  animation: sb-term-fade 0.25s ease 0.45s both;
}

/* The JSON card keeps a red border: it is the error, on its way to Claude. */
.storyboard-app[data-step="2"] .storyboard-payload {
  border: 1.5px solid #dc2626;
}

@keyframes sb-ring {
  0% {
    box-shadow: 0 0 0 4px rgba(220, 38, 38, 0.35), 0 24px 60px rgba(31, 30, 27, 0.30);
  }

  100% {
    box-shadow: 0 0 0 0 rgba(220, 38, 38, 0), 0 24px 60px rgba(31, 30, 27, 0.30), 0 4px 12px rgba(31, 30, 27, 0.12);
  }
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .storyboard-app[data-step="2"] .storyboard-payload {
    border-color: #dc2626;
  }
}

:root[data-theme="dark"] .storyboard-app[data-step="2"] .storyboard-payload {
  border-color: #dc2626;
}

.storyboard-app[data-step="2"] .storyboard-payload {
  border: 1px solid rgba(220, 38, 38, 0.55);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .storyboard-app[data-step="2"] .storyboard-payload {
    border-color: rgba(220, 38, 38, 0.55);
  }
}

:root[data-theme="dark"] .storyboard-app[data-step="2"] .storyboard-payload {
  border-color: rgba(220, 38, 38, 0.55);
}

/* No flash: the card simply appears, with its shadow and thin red border. */
.storyboard-app[data-step="2"] .storyboard-payload {
  animation: sb-appear 0s linear 0.45s both;
  box-shadow: 0 24px 60px rgba(31, 30, 27, 0.30), 0 4px 12px rgba(31, 30, 27, 0.12);
}

/* Step 3: the JSON is the only thing in focus. It sits in the middle of
   the window, a plain white card with a neutral edge, and everything else
   in the window drops to a faint ghost. */
.storyboard-app {
  position: relative;
}

.storyboard-app[data-step="2"] .storyboard-chat {
  position: static;
}

.storyboard-app[data-step="2"] .storyboard-payload {
  top: 50%;
  bottom: auto;
  transform: translateY(-50%);
  border: 1px solid #e4e2dc;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .storyboard-app[data-step="2"] .storyboard-payload {
    border-color: #e4e2dc;
  }
}

:root[data-theme="dark"] .storyboard-app[data-step="2"] .storyboard-payload {
  border-color: #e4e2dc;
}

.storyboard-app[data-step="2"] .storyboard-chat > :not(.storyboard-payload),
.storyboard-app[data-step="2"] .sb-composer,
.storyboard-app[data-step="2"] .sb-status,
.storyboard-app[data-step="2"] .sb-titlebar {
  opacity: 0.12;
  transition: opacity 0.25s ease 0.45s;
}

@keyframes sb-term-fade {
  from {
    opacity: 1;
  }

  to {
    opacity: 0.12;
  }
}

/* The Elements panel ghosts with the rest once the JSON is up. */
.storyboard-app[data-step="2"] .sb-term {
  animation: none;
  opacity: 0.12;
  transition: opacity 0.25s ease 0.45s;
}

/* The JSON card sits near the top of the window, just under the title bar. */
.storyboard-app[data-step="2"] .storyboard-payload {
  top: 3.25rem;
  transform: none;
}

/* The dotted line stays after the dots have run, joining the Elements
   panel to the card, so the direction reads at a glance. */
.sb-stream {
  animation: none;
  opacity: 1;
}

.sb-stream::before {
  border-left: 2px dotted rgba(220, 38, 38, 0.7);
}

/* After the first pass, the dotted line keeps flowing upward, slowly, so
   the direction stays clear: Elements to Claude. */
.sb-stream::before {
  width: 2px;
  border-left: 0;
  background-image: radial-gradient(circle, rgba(220, 38, 38, 0.75) 1px, transparent 1.5px);
  background-size: 2px 7px;
  background-repeat: repeat-y;
  animation: sb-flow 0.9s linear 0.5s infinite;
}

@keyframes sb-flow {
  from {
    background-position: 0 0;
  }

  to {
    background-position: 0 -7px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sb-stream::before {
    animation: none;
  }
}

/* The JSON card is there the moment step 3 opens, with everything else
   already ghosted. The flowing line shows where it came from. */
.storyboard-app[data-step="2"] .storyboard-payload {
  animation: none;
  visibility: visible;
}

.storyboard-app[data-step="2"] .storyboard-chat > :not(.storyboard-payload),
.storyboard-app[data-step="2"] .sb-composer,
.storyboard-app[data-step="2"] .sb-status,
.storyboard-app[data-step="2"] .sb-titlebar,
.storyboard-app[data-step="2"] .sb-term {
  transition: none;
}

.sb-stream i {
  display: none;
}

.sb-stream::before {
  animation-delay: 0s;
}

/* Softer: one short crossfade, no delay. The card comes up and the window
   behind it settles back together in 0.2s, fast enough to read as
   immediate without snapping. */
.storyboard-app[data-step="2"] .storyboard-payload {
  animation: sb-soft-in 0.2s ease-out both;
}

@keyframes sb-soft-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.storyboard-app .storyboard-chat > *,
.storyboard-app .sb-composer,
.storyboard-app .sb-status,
.storyboard-app .sb-titlebar,
.storyboard-app .sb-term,
.storyboard-app[data-step="2"] .storyboard-chat > :not(.storyboard-payload),
.storyboard-app[data-step="2"] .sb-composer,
.storyboard-app[data-step="2"] .sb-status,
.storyboard-app[data-step="2"] .sb-titlebar,
.storyboard-app[data-step="2"] .sb-term {
  transition: opacity 0.25s ease;
}

/* The card spans the same width as the Elements panel, so their edges line
   up and the two read as sender and message. */
.storyboard-app[data-step="2"] .storyboard-payload {
  left: var(--sb-inset);
  right: var(--sb-inset);
}

/* The flowing line in a soft neutral grey: it shows direction without
   competing with the card. */
.sb-stream::before {
  background-image: radial-gradient(circle, rgba(111, 109, 103, 0.45) 1px, transparent 1.5px);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sb-stream::before {
    background-image: radial-gradient(circle, rgba(236, 235, 230, 0.35) 1px, transparent 1.5px);
  }
}

:root[data-theme="dark"] .sb-stream::before {
  background-image: radial-gradient(circle, rgba(236, 235, 230, 0.35) 1px, transparent 1.5px);
}

/* The line comes in only after the card is fully up, so its top end is
   always hidden under the card and never shows on its own. */
.storyboard-app[data-step="2"] .sb-stream {
  animation: sb-soft-in 0.2s ease-out 0.2s both;
}

/* The card and its line are both there instantly, nothing animates in. */
.storyboard-app[data-step="2"] .storyboard-payload,
.storyboard-app[data-step="2"] .sb-stream {
  animation: none;
  opacity: 1;
  visibility: visible;
}

/* The last step: the app in a browser window, the same size as the Claude
   window so nothing on the page moves. */
.storyboard-app.is-browser {
  background: #fff;
}

.sb-url {
  flex: 1;
  max-width: 22rem;
  margin: 0 auto;
  padding: 0.2rem 0.8rem;
  border: 1px solid #e3e1da;
  border-radius: 7px;
  background: #f6f5f2;
  font-size: 0.8125rem;
  color: #6f6d67;
  text-align: center;
}

.sb-page {
  flex: 1;
  display: grid;
  place-items: center;
  border-top: 1px solid #ecebe6;
  background: #f7f8fa;
}

.sb-signup {
  display: flex;
  flex-direction: column;
  width: min(20rem, 80%);
  padding: 1.5rem;
  border: 1px solid #e3e6ea;
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 6px 20px rgba(16, 40, 61, 0.06);
  color: #10283d;
  font-size: 0.875rem;
}

.sb-signup-title {
  margin: 0 0 1rem;
  font-size: 1.125rem;
  font-weight: var(--weight-bold);
}

.sb-field-label {
  margin: 0 0 0.3rem;
  font-size: 0.75rem;
  font-weight: var(--weight-semibold);
  color: #4b5d6e;
}

.sb-field {
  margin: 0 0 0.8rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid #d9dde3;
  border-radius: 7px;
  color: #10283d;
}

.sb-signup-button {
  margin-top: 0.3rem;
  padding: 0.55rem;
  border: 1px solid #1a7f37;
  border-radius: 8px;
  background: #1f8a43;
  color: #fff;
  font-weight: var(--weight-semibold);
  text-align: center;
}

.sb-signup-alt {
  margin: 0.8rem 0 0;
  font-size: 0.75rem;
  color: #4b5d6e;
  text-align: center;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .storyboard-app.is-browser {
    background: #262624;
  }

  :root:not([data-theme="light"]) .sb-url {
    background: #1f1f1d;
    border-color: #3a3a37;
    color: #a3a19a;
  }

  :root:not([data-theme="light"]) .sb-page {
    background: #1b1c20;
    border-top-color: #3a3a37;
  }
}

:root[data-theme="dark"] .storyboard-app.is-browser {
  background: #262624;
}

:root[data-theme="dark"] .sb-url {
  background: #1f1f1d;
  border-color: #3a3a37;
  color: #a3a19a;
}

:root[data-theme="dark"] .sb-page {
  background: #1b1c20;
  border-top-color: #3a3a37;
}

.sb-page {
  border-radius: 0 0 14px 14px;
}

/* Browser chrome for the last step: a pale tab strip with one tab, then
   a white toolbar with back, forward, reload and the address. */
.sb-tabs {
  display: flex;
  align-items: flex-end;
  gap: 0.6rem;
  padding: 0.5rem 0.75rem 0;
  border-radius: 14px 14px 0 0;
  background: #dde3ea;
}

.sb-tabs .sb-lights {
  align-self: center;
  margin-right: 0.4rem;
}

.sb-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-width: 11rem;
  padding: 0.45rem 0.75rem;
  border-radius: 9px 9px 0 0;
  background: #fff;
  font-size: 0.8125rem;
  color: #1f1e1b;
}

.sb-tab-icon {
  width: 13px;
  height: 13px;
  border-radius: 3px;
  background: #1f8a43;
}

.sb-tab-x {
  margin-left: auto;
  color: #8a8880;
}

.sb-tab-plus {
  align-self: center;
  color: #6f6d67;
  font-size: 1rem;
}

.sb-toolbar {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.45rem 0.75rem;
  background: #fff;
  color: #4b4a46;
}

.sb-toolbar svg {
  width: 15px;
  height: 15px;
}

.sb-toolbar .is-dim {
  color: #b3b1aa;
}

.sb-omnibox {
  flex: 1;
  padding: 0.3rem 0.9rem;
  border-radius: 999px;
  background: #eef1f5;
  font-size: 0.8125rem;
  color: #3d3c38;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sb-tabs {
    background: #1b1c20;
  }

  :root:not([data-theme="light"]) .sb-tab,
  :root:not([data-theme="light"]) .sb-toolbar {
    background: #2b2c31;
    color: #e6e7ea;
  }

  :root:not([data-theme="light"]) .sb-omnibox {
    background: #1b1c20;
    color: #c9ccd2;
  }
}

:root[data-theme="dark"] .sb-tabs {
  background: #1b1c20;
}

:root[data-theme="dark"] .sb-tab,
:root[data-theme="dark"] .sb-toolbar {
  background: #2b2c31;
  color: #e6e7ea;
}

:root[data-theme="dark"] .sb-omnibox {
  background: #1b1c20;
  color: #c9ccd2;
}

/* The dashboard on the last step. */
.sb-page {
  display: block;
  overflow: hidden;
  background: #f6f8f6;
  color: #10283d;
  font-size: 0.8125rem;
}

.sb-dash-nav {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  padding: 0.6rem 1.1rem;
  border-bottom: 1px solid #e3e8e4;
  background: #fff;
}

.sb-dash-brand {
  font-weight: var(--weight-bold);
  color: #17733a;
  margin-right: 0.4rem;
}

.sb-dash-link {
  color: #5b6b62;
}

.sb-dash-link.is-on {
  color: #10283d;
  font-weight: var(--weight-semibold);
}

.sb-dash-user {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: auto;
  color: #3d4b44;
}

.sb-dash-user i {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #dcefe2;
  color: #17733a;
  font-style: normal;
  font-size: 0.625rem;
  font-weight: var(--weight-bold);
}

.sb-dash-body {
  padding: 1rem 1.1rem;
}

.sb-dash-h {
  margin: 0 0 0.75rem;
  font-size: 1.0625rem;
  font-weight: var(--weight-bold);
}

.sb-dash-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.6rem;
  margin-bottom: 0.75rem;
}

.sb-stat {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid #e3e8e4;
  border-radius: 9px;
  background: #fff;
}

.sb-stat span {
  font-size: 0.6875rem;
  color: #5b6b62;
}

.sb-stat b {
  font-size: 1.125rem;
}

.sb-dash-list {
  border: 1px solid #e3e8e4;
  border-radius: 9px;
  background: #fff;
}

.sb-job {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.75rem;
}

.sb-job + .sb-job {
  border-top: 1px solid #eef1ef;
}

.sb-job-time {
  width: 2.6rem;
  color: #5b6b62;
  font-variant-numeric: tabular-nums;
}

.sb-job-name {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sb-pill {
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: var(--weight-semibold);
}

.sb-pill.is-paid {
  background: #e3f4e8;
  color: #17733a;
}

.sb-pill.is-done {
  background: #fdeee4;
  color: #b4541f;
}

.sb-pill.is-due {
  background: #e8eef7;
  color: #2b62b8;
}

@media (max-width: 760px) {
  .sb-dash-link:not(.is-on) {
    display: none;
  }

  .sb-stat b {
    font-size: 0.9375rem;
  }
}

/* The dashboard fills the browser, edge to edge. */
.sb-page {
  display: block;
  place-items: initial;
}

.sb-dash {
  width: 100%;
}

/* The browser and its page are plain white. */
.storyboard-app.is-browser,
.sb-page {
  background: #fff;
}

.sb-dash-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.75rem;
}

.sb-dash-head .sb-dash-h {
  margin: 0;
}

.sb-dash-new {
  padding: 0.3rem 0.7rem;
  border: 1px solid #1a7f37;
  border-radius: 7px;
  background: #1f8a43;
  color: #fff;
  font-size: 0.75rem;
  font-weight: var(--weight-semibold);
}

.sb-job-time {
  width: 3rem;
}

.sb-job-amt {
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-semibold);
}

.sb-dash-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.75rem;
}

.sb-dash-head .sb-dash-h {
  margin: 0;
}

.sb-dash-new {
  padding: 0.3rem 0.7rem;
  border: 1px solid #1a7f37;
  border-radius: 7px;
  background: #1f8a43;
  color: #fff;
  font-size: 0.75rem;
  font-weight: var(--weight-semibold);
}

.sb-job-time {
  width: 3rem;
}

.sb-job-amt {
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-semibold);
}

/* Frame 1 is the establishing shot and has to stand alone: the full window
   at full strength, Claude above and the Elements engine running below. */
.storyboard-app[data-step="0"] .sb-titlebar,
.storyboard-app[data-step="0"] .sb-status,
.storyboard-app[data-step="0"] .sb-term {
  opacity: 1;
}

/* Room for the longest step sentence, so the section never changes height. */
.storyboard-say {
  min-height: calc(3 * 1.5em);
}

@media (max-width: 760px) {
  .storyboard-say {
    min-height: calc(6 * 1.5em);
  }
}

@media (max-width: 760px) {
  .storyboard-title {
    min-height: calc(2 * 1.25em);
  }
}

/* The title and sentence stack tightly; the reserved space sits under the
   whole block, so the section keeps one height without gaps inside it. */
.storyboard-title,
.storyboard-say {
  min-height: 0;
}

.storyboard-text {
  min-height: 7.25rem;
}

@media (max-width: 760px) {
  .storyboard-title,
  .storyboard-say {
    min-height: 0;
  }

  .storyboard-text {
    min-height: 13rem;
  }
}

@media (max-width: 760px) {
  .storyboard-text {
    min-height: 8.5rem;
  }
}

/* The opening shot is at full strength, chat included. */
.storyboard-app[data-step="0"] .storyboard-chat > * {
  opacity: 1;
}

/* All steps' text share one grid cell; the tallest sets the height. */
.storyboard-text,
.storyboard-text-step {
  min-height: 0;
}

.storyboard-text {
  display: grid;
  animation: none;
}

@media (max-width: 760px) {
  .storyboard-text {
    min-height: 0;
  }
}

.storyboard-text-step {
  grid-area: 1 / 1;
  visibility: hidden;
}

.storyboard-text-step.is-on {
  visibility: visible;
}

.storyboard-text {
  cursor: pointer;
}

/* The window is only as tall as what each step shows, so there is no
   empty band above the conversation. */
.storyboard-app,
.storyboard-app.is-browser {
  height: auto;
}

.storyboard-app .storyboard-chat {
  flex: none;
}

@media (max-width: 760px) {
  .storyboard-app,
  .storyboard-app.is-browser {
    height: auto;
  }
}

/* The browser zoomed out and a size smaller than the Claude window, so it
   reads as a page on a screen rather than a close-up. */
.storyboard-app.is-browser {
  zoom: 0.85;
  width: 100%;
  margin-left: auto;
  margin-right: auto;
}

/* The controls sit above the window, so they stay put while the window
   changes height; the step text stays under the window. */
.storyboard-side {
  display: contents;
}

.storyboard-nav {
  order: -1;
  align-self: flex-end;
  padding-top: 0;
}

.storyboard-text {
  max-width: 40rem;
}

/* The dots already say where you are, so the step count is not shown. */
.storyboard-count {
  display: none;
}

/* The Elements panel in the same surface as the rest of the Claude window.
   Focus and dimming, not a dark panel, say which part a step is about. */
.storyboard-app .sb-term {
  background: transparent;
  border-color: #e0ded8;
}

.storyboard-app .sb-term-head,
.storyboard-app .sb-term-body {
  color: #3d3c38;
}

.storyboard-app .sb-ok {
  color: #15803d;
}

.storyboard-app .sb-err {
  color: #dc2626;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .storyboard-app .sb-term {
    background: transparent;
    border-color: #2f2f2c;
  }

  :root:not([data-theme="light"]) .storyboard-app .sb-term-head,
  :root:not([data-theme="light"]) .storyboard-app .sb-term-body {
    color: #d7d5ce;
  }

  :root:not([data-theme="light"]) .storyboard-app .sb-ok {
    color: #4ade80;
  }

  :root:not([data-theme="light"]) .storyboard-app .sb-err {
    color: #f87171;
  }
}

:root[data-theme="dark"] .storyboard-app .sb-term {
  background: transparent;
  border-color: #2f2f2c;
}

:root[data-theme="dark"] .storyboard-app .sb-term-head,
:root[data-theme="dark"] .storyboard-app .sb-term-body {
  color: #d7d5ce;
}

:root[data-theme="dark"] .storyboard-app .sb-ok {
  color: #4ade80;
}

:root[data-theme="dark"] .storyboard-app .sb-err {
  color: #f87171;
}

/* Every line in the conversation is the same grey. */
.storyboard-app .sb-claude,
.storyboard-app .sb-you {
  color: #8a8880;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .storyboard-app .sb-claude,
  :root:not([data-theme="light"]) .storyboard-app .sb-you {
    color: #8f8d86;
  }
}

:root[data-theme="dark"] .storyboard-app .sb-claude,
:root[data-theme="dark"] .storyboard-app .sb-you {
  color: #8f8d86;
}

/* Step 3: room between the JSON card and the Elements panel, so the line
   the correction travels along shows. The panel stays lit: it is where the
   error comes from. */
.storyboard-app[data-step="2"] .sb-bottom {
  padding-bottom: 3rem;
}

.storyboard-app[data-step="2"] .sb-term {
  opacity: 1;
}

.sb-stream::before {
  width: 3px;
  background-image: radial-gradient(circle, rgba(111, 109, 103, 0.8) 1.3px, transparent 1.8px);
  background-size: 3px 8px;
}

@keyframes sb-flow-8 {
  from {
    background-position: 0 0;
  }

  to {
    background-position: 0 -8px;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .sb-stream::before {
    animation-name: sb-flow-8;
  }
}

/* A soft arrowhead where the line meets the card, pointing up into it. */
.storyboard-app[data-step="2"] .storyboard-payload::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -9px;
  width: 8px;
  height: 8px;
  border-left: 1.5px solid rgba(111, 109, 103, 0.8);
  border-top: 1.5px solid rgba(111, 109, 103, 0.8);
  transform: translateX(-50%) rotate(45deg);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .storyboard-app[data-step="2"] .storyboard-payload::after {
    border-color: rgba(236, 235, 230, 0.6);
  }
}

:root[data-theme="dark"] .storyboard-app[data-step="2"] .storyboard-payload::after {
  border-color: rgba(236, 235, 230, 0.6);
}

.storyboard-app[data-step="2"] .storyboard-payload {
  overflow: visible;
}

.storyboard-app[data-step="2"] .storyboard-payload-body {
  overflow: hidden;
}

.storyboard-app[data-step="2"] .storyboard-payload::after {
  bottom: -16px;
  width: 10px;
  height: 10px;
  border-left-width: 2px;
  border-top-width: 2px;
  z-index: 3;
}

/* The line and arrowhead sit in the gap and stop short of the card. */
.storyboard-app[data-step="2"] .storyboard-payload::after {
  bottom: -14px;
}

.storyboard-app[data-step="2"] .sb-stream {
  top: auto;
  height: 1.5rem;
}

/* The line hangs from the arrowhead and runs down behind the Elements
   panel, so it always meets the arrow whatever the gap at this width. */
.storyboard-app[data-step="2"] .sb-stream {
  display: none;
}

.storyboard-app[data-step="2"] .storyboard-payload::before {
  content: "";
  position: absolute;
  left: 50%;
  top: calc(100% + 10px);
  width: 3px;
  height: 8rem;
  margin-left: -1.5px;
  background-image: radial-gradient(circle, rgba(111, 109, 103, 0.8) 1.3px, transparent 1.8px);
  background-size: 3px 8px;
  background-repeat: repeat-y;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .storyboard-app[data-step="2"] .storyboard-payload::before {
    animation: sb-flow-8 0.9s linear infinite;
  }
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .storyboard-app[data-step="2"] .storyboard-payload::before {
    background-image: radial-gradient(circle, rgba(236, 235, 230, 0.6) 1.3px, transparent 1.8px);
  }
}

:root[data-theme="dark"] .storyboard-app[data-step="2"] .storyboard-payload::before {
  background-image: radial-gradient(circle, rgba(236, 235, 230, 0.6) 1.3px, transparent 1.8px);
}

.storyboard-app[data-step="2"] .sb-term {
  position: relative;
  z-index: 4;
  background: inherit;
}

.storyboard-app[data-step="2"] .storyboard-payload::after {
  bottom: -19px;
}

.storyboard-app[data-step="2"] .storyboard-payload::before {
  top: calc(100% + 16px);
}

/* The arrowhead brightens and fades in place, in time with the dots below
   it, as if each one lands in the card. */
@keyframes sb-arrow-nudge {
  0%, 100% {
    opacity: 0.35;
  }

  50% {
    opacity: 0.85;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .storyboard-app[data-step="2"] .storyboard-payload::after {
    animation: sb-arrow-nudge 0.9s ease-in-out infinite;
  }
}

/* Drawn at the weight of the dots, so it reads as the head of the same line. */
.storyboard-app[data-step="2"] .storyboard-payload::after {
  border-left-width: 1.5px;
  border-top-width: 1.5px;
}

/* A smaller head, with air above it and between it and the dots. */
.storyboard-app[data-step="2"] .storyboard-payload::after {
  width: 7px;
  height: 7px;
  bottom: -16px;
}

.storyboard-app[data-step="2"] .storyboard-payload::before {
  top: calc(100% + 15px);
}

/* Step 3 has a fixed layout: the card's bottom edge and the Elements panel's
   top edge sit a set distance apart at every width, so the arrow and its
   line fit between them with even space above and below. */
.storyboard-app[data-step="2"] .sb-bottom {
  display: none;
}

.storyboard-app[data-step="2"] .storyboard-chat {
  flex: none;
  height: 230px;
  padding-bottom: 0;
  overflow: hidden;
}

@media (max-width: 760px) {
  .storyboard-app[data-step="2"] .storyboard-chat {
    height: 234px;
  }
}

.storyboard-app[data-step="2"] .storyboard-payload::before {
  height: 33px;
}

.storyboard-app[data-step="2"] .storyboard-chat > :not(.storyboard-payload) {
  visibility: hidden;
}

/* More air under the arrowhead, and the dots fade in at the top of the line
   instead of appearing cut in half. */
.storyboard-app[data-step="2"] .storyboard-payload::before {
  top: calc(100% + 20px);
  height: 28px;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 8px);
          mask-image: linear-gradient(to bottom, transparent, #000 8px);
}

/* The first dot sits one dot-gap below the arrowhead's arms. */
.storyboard-app[data-step="2"] .storyboard-payload::before {
  top: calc(100% + 16px);
  height: 32px;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 3px);
          mask-image: linear-gradient(to bottom, transparent, #000 3px);
}

/* Inside the demo the page only scrolls up and down: a sideways swipe steps
   the sequence instead of panning the page, and quick taps on the arrows
   or the window never zoom it. */
.storyboard {
  touch-action: pan-y;
}

/* The step text is only as tall as the current step: the controls are above
   the window and never move, so nothing needs to hold the height. */
.storyboard-text,
.storyboard-title,
.storyboard-say {
  min-height: 0;
}

.storyboard-text-step:not(.is-on) {
  display: none;
}

@media (max-width: 760px) {
  .storyboard-text,
  .storyboard-title,
  .storyboard-say {
    min-height: 0;
  }
}

/* Set on every element in the demo too: Safari reads touch-action from the
   element under the finger, and a double tap there must never zoom. */
.storyboard *,
.storyboard-app {
  touch-action: pan-y;
}

/* The Elements tab carries the same weight as the window's Claude title. */
.sb-term-tab {
  font-weight: var(--weight-semibold, 600);
}

/* The step's title and text sit above the window, then the controls. Every
   step is laid out in the same cell, so the block is as tall as the longest
   step and the window under it never moves when the step changes. */
.storyboard-text {
  order: -2;
  display: grid;
  margin-bottom: var(--space-4);
}

.storyboard-text-step:not(.is-on) {
  display: block;
}

.storyboard-text-step {
  grid-area: 1 / 1;
  visibility: hidden;
}

.storyboard-text-step.is-on {
  visibility: visible;
}

/* The controls lead, above the step text, so they hold one spot. */
.storyboard-nav {
  order: -3;
  margin-bottom: var(--space-3);
}

/* Right-aligned, so the controls read apart from the step title. */
.storyboard-nav {
  align-self: flex-end;
  justify-content: flex-end;
}

@media (max-width: 760px) {
  .storyboard-nav {
    align-self: flex-end;
    justify-content: flex-end;
  }
}

/* Wide screens: the controls stand in a vertical column in the margin to
   the left of the window, up, the dots, down. The text and the window keep
   the full content width. */
@media (min-width: 1121px) {
  .storyboard {
    display: grid;
    grid-template-columns: 2.25rem minmax(0, 1fr);
    column-gap: 1.25rem;
    margin-left: -3.5rem;
  }

  .storyboard-text {
    grid-column: 2;
    grid-row: 1;
  }

  .storyboard-app {
    grid-column: 2;
    grid-row: 2;
  }

  .storyboard .storyboard-nav {
    grid-column: 1;
    grid-row: 2;
    align-self: start;
    flex-direction: column;
    justify-content: flex-start;
    margin: var(--space-4) 0 0;
    padding: 0;
  }

  .storyboard-nav .storyboard-arrow svg {
    transform: rotate(90deg);
  }

  .storyboard .storyboard-rail {
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
  }

  .storyboard .storyboard-rail::before {
    left: 50%;
    right: auto;
    top: 6px;
    bottom: 6px;
    width: 1px;
    height: auto;
    transform: translateX(-50%);
  }
}

/* The vertical controls sit beside the step's title and text, where the
   eye already is. */
@media (min-width: 1121px) {
  .storyboard .storyboard-nav {
    grid-row: 1;
    margin-top: 0;
  }
}

/* The controls run down beside the window rather than pushing it down: the
   column spans both rows, so the text alone sets the gap above the window. */
@media (min-width: 1121px) {
  .storyboard .storyboard-nav {
    grid-row: 1 / span 2;
  }
}

/* The window sits right under the current step's text. The controls are in
   the margin, so nothing the visitor clicks moves when the text changes. */
@media (min-width: 1121px) {
  .storyboard-text-step:not(.is-on) {
    display: none;
  }
}

/* Every width: the window sits right under the current step's text. The
   controls are above the text, so they never move. */
.storyboard-text-step:not(.is-on) {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sb-dash-h { color: #e6ecf2; }
}

:root[data-theme="dark"] .sb-dash-h { color: #e6ecf2; }

/* Narrow screens: the controls stay above the step. The windows differ in
   height, so controls under them would jump on every step. */
@media (max-width: 1120px) {
  .storyboard .storyboard-nav {
    order: -3;
    margin: 0 0 var(--space-3);
  }
}

/* Phones: one step, its text, the window and the controls fit an iPhone
   screen together. The window is drawn a size smaller and the text is
   body size. */
@media (max-width: 700px) {
  .storyboard .storyboard-app:not(.is-browser) {
    zoom: 0.84;
  }

  .storyboard .storyboard-app.is-browser {
    zoom: 0.72;
  }

  .storyboard-title {
    font-size: 1.1875rem;
    line-height: 1.25;
  }

  .storyboard-say {
    font-size: 0.9375rem;
    line-height: 1.5;
  }

  .storyboard-text {
    margin-bottom: var(--space-3);
  }

  .storyboard .storyboard-nav {
    margin-bottom: var(--space-3);
  }
}

/* Nothing moves between steps. Every step's text shares one cell, so the
   block is as tall as the longest step, and both windows are drawn at one
   height with the composer held at the bottom, as in the real app. */
.storyboard .storyboard-text-step:not(.is-on) {
  display: block;
}

.storyboard-app .sb-bottom {
  margin-top: auto;
}

.storyboard .storyboard-app:not(.is-browser) {
  height: var(--sb-window);
}

.storyboard .storyboard-app.is-browser {
  height: calc(var(--sb-window) / 0.85);
}

@media (max-width: 700px) {
  .storyboard .storyboard-app:not(.is-browser) {
    height: calc(var(--sb-window) / 0.84);
  }

  .storyboard .storyboard-app.is-browser {
    height: calc(var(--sb-window) / 0.72);
  }
}

.storyboard {
  --sb-window: 390px;
}

@media (max-width: 700px) {
  .storyboard {
    --sb-window: 330px;
  }
}
