/* Waddl case study — the interaction "windows" and case-study layout.
 * Everything consumes semantic tokens; no raw palette values. */

/* ── Live demo embed ──
 * The interactive Waddl build is bundled under /waddl-app and framed here.
 * Waddl is a three-panel desktop UI, so below a threshold we swap the frame
 * for a note that points to the full-screen build. */
.demo-embed {
  position: relative;
  /* Sits on the column like everything else. It used to break out to 1200px
   * so the three-panel app wasn't cramped, but that made it the one element
   * wider than the page — the demo read as the page's edge rather than as
   * one figure in it. */
  margin-top: var(--space-6);
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  background: var(--bg-subtle);
  box-shadow: var(--shadow-lg);
}

.demo-frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.demo-fallback {
  display: none;
}

/* The escape hatch to the standalone app, offered up front — a reader who
 * wants the real window shouldn't have to scroll past the embed to find it. */
.demo-action {
  margin-top: var(--space-3);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.demo-fullscreen {
  font-weight: var(--weight-medium);
  color: var(--accent-strong);
}

@media (max-width: 760px) {
  .demo-embed {
    aspect-ratio: 4 / 3;
    display: grid;
    place-content: center;
    border-style: dashed;
    border-color: var(--border-strong);
  }
  .demo-frame {
    display: none;
  }
  .demo-fallback {
    display: grid;
    gap: var(--space-3);
    place-items: center;
    padding: var(--space-6);
    text-align: center;
    color: var(--text-muted);
  }
}

.video-slot-glyph {
  justify-self: center;
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-full);
  background: var(--surface-default);
  border: 1px solid var(--border-default);
  box-shadow: var(--shadow-sm);
  color: var(--accent-strong);
  font-size: var(--text-lg);
}

.video-slot-note {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

/* ── Interaction breakdowns ── */
.breakdown {
  margin-top: var(--space-12);
}

.breakdown h3 {
  font-size: var(--text-xl);
}

.breakdown > p {
  margin-top: var(--space-3);
  max-width: var(--measure-prose);
  color: var(--text-secondary);
}

.breakdown > p strong {
  color: var(--text-primary);
}

/* The h3 states the problem; this green tag marks the pivot to the fix. */
.breakdown-label {
  display: inline-block;
  margin-right: var(--space-2);
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.04em;
  background: var(--status-success-soft);
  color: var(--status-success);
}

/* A mini Waddl-style window chrome around each demo frame. Fills the column,
 * matching the figures and headings around it; waddl-demos.js re-measures
 * each frame's height on resize, so the extra width costs nothing. */
.waddl-window {
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--surface-default);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}

.waddl-titlebar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--border-default);
  background: var(--bg-subtle);
}

.waddl-dot {
  width: 10px;
  height: 10px;
  border-radius: var(--radius-full);
  background: var(--accent-default);
}

.waddl-title {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}

.waddl-status {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text-muted);
}

/* ── Interaction demos ──
 * These frame the real component from the Waddl repo. They're iframes
 * because Waddl's tokens collide by name with this site's — see
 * scripts/waddl-demos.js, which also sizes them to their reported height.
 * The duck below is the exception; it's inlined. */
.demo-figure {
  margin-top: var(--space-4);
}

.demo-inline {
  display: block;
  width: 100%;
  /* A placeholder until the frame reports its real height; roughly the
   * shortest demo, so the page doesn't jump much on load. */
  height: 300px;
  border: 0;
  background: var(--bg-subtle);
}

.demo-figcaption {
  margin-top: var(--space-3);
  max-width: var(--measure-prose);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* ── The duck ──
 * The one demo not framed from the Waddl build — he lives in the app's
 * composer, not in the three exported components, so the sprite and the
 * walk timings are inlined instead. The four colours are the mascot's own
 * palette rather than this page's tokens: he's the same bird in either
 * theme, so he doesn't take the light/dark swap the surface around him does. */
.duck-stage {
  --duck-body: #edcf83;
  --duck-shade: #c8a24b;
  --duck-bill: #e1773d;
  --duck-eye: #171310;
  padding: var(--space-4);
  background: var(--bg-subtle);
}

.duck-track {
  position: relative;
  height: 42px;
}

.duck-mover {
  position: absolute;
  bottom: 0;
  left: 0;
  /* 8s out, 8s back; the flip below runs at twice the period so he turns
   * on the beat he reverses. */
  animation: duck-walk 8s linear infinite alternate;
}

.duck-flip {
  transform-origin: 50% 100%;
  animation: duck-turn 16s steps(1) infinite;
}

.duck-sprite {
  display: block;
  transform-origin: 50% 100%;
  animation: duck-trot 0.14s var(--ease-in-out) infinite alternate;
}

@keyframes duck-walk {
  0% {
    left: 0;
  }
  100% {
    left: calc(100% - 48px);
  }
}

@keyframes duck-turn {
  0%,
  100% {
    transform: scaleX(1);
  }
  50% {
    transform: scaleX(-1);
  }
}

@keyframes duck-trot {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(-1.5px);
  }
}

/* Two feet poses cross-faded on opposite halves of the same step, so one
 * foot is always planted. The idle pair only shows when motion is off. */
.duck-feet-idle {
  opacity: 0;
}

.duck-feet-left {
  animation: duck-step 0.28s steps(1) infinite;
}

.duck-feet-right {
  animation: duck-step 0.28s steps(1) -0.14s infinite;
}

@keyframes duck-step {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

/* The faux composer he paces on top of — enough of the app's input row to
 * place him, not a working control. */
.duck-composer {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  background: var(--surface-default);
}

.duck-composer-text {
  flex: 1;
  min-width: 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.duck-composer-send {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-full);
  background: var(--accent-soft);
  color: var(--accent-strong);
}

/* The arrow sprite points down; the send button points up. */
.duck-composer-send .icon {
  width: 14px;
  height: 14px;
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .duck-mover,
  .duck-flip,
  .duck-sprite,
  .duck-feet-left,
  .duck-feet-right {
    animation: none;
  }

  .duck-feet-idle {
    opacity: 1;
  }

  .duck-feet-left,
  .duck-feet-right {
    opacity: 0;
  }
}
