/* Keepsakes and the By Heart recital (keepsakes/show, keepsakes/recitations).
   Verse keeps the breaks the poet gave it, so kept text never reflows into a
   paragraph. */
.keepsake-text {
  white-space: pre-line;
}

/* The scaffolding: whatever the current level leaves standing in place of the
   lines still to come, printed in the same measure as the lines themselves so
   the shape of what you're reaching for is still there. A spoken run crosses
   several lines in one breath, so all of what's left is on the page and the
   line you're on is the one lit. */
.by-heart-prompt {
  min-height: 2rem;
  margin-bottom: 0.5rem;
}

.by-heart-standing {
  font-family: var(--display);
  font-size: 1.25rem;
  margin-bottom: 0.25rem;
  letter-spacing: 0.04em;
  color: var(--muted);
  opacity: 0.5;
}

.by-heart-standing[data-now] {
  opacity: 1;
}

/* Held down, it's listening. Let go to breathe. */
.by-heart-mic-dot {
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  margin-right: 0.5rem;
  border-radius: 50%;
  background: currentColor;
  vertical-align: middle;
}

.by-heart-mic[data-listening] .by-heart-mic-dot {
  animation: by-heart-listening 1.2s ease-in-out infinite;
}

@keyframes by-heart-listening {
  50% { opacity: 0.25; }
}

/* Lines already said, printed as written and marked where the recital pulled
   away. The glyph in the margin is the verdict: said, near enough, or lost. */
.by-heart-said {
  white-space: pre-line;
  margin-bottom: 0.25rem;
  padding-left: 1.75rem;
  text-indent: -1.75rem;
}

.by-heart-said::before {
  display: inline-block;
  width: 1.75rem;
  text-indent: 0;
  font-size: 0.875rem;
}

.by-heart-said[data-verdict="exact"] { color: var(--ink); }
.by-heart-said[data-verdict="exact"]::before { content: "✓"; color: var(--moss); }

.by-heart-said[data-verdict="close"] { color: var(--ink); }
.by-heart-said[data-verdict="close"]::before { content: "~"; color: var(--gold); }

.by-heart-said[data-verdict="missed"] { color: var(--muted); }
.by-heart-said[data-verdict="missed"]::before { content: "×"; color: var(--rose); }

/* The words the recital never reached. */
.by-heart-drift {
  background: var(--gold-wash);
  border-bottom: 2px solid var(--gold);
  border-radius: 2px;
}

/* The stage: a dark house under a warm spotlight, with a red curtain that
   parts when you go for it. The audience is rows of heads in silhouette,
   drawn in gradient because a crowd is a texture, not a cast. The copy
   calls it the stage; the class is .theatre because stage.css already owns
   the bare .stage for the typing baseline. */
.theatre {
  position: relative;
  min-height: 18rem;
  border-radius: 0.5rem;
  overflow: hidden;
  background:
    radial-gradient(ellipse at 50% 15%, hsl(45deg 70% 40% / 35%), transparent 65%),
    linear-gradient(hsl(240deg 15% 14%), hsl(240deg 18% 7%));
}

/* Three rows of heads, nearer rows larger and lower, staggered so nobody
   sits exactly behind anybody. */
.theatre-house {
  position: absolute;
  inset: auto 0 0 0;
  height: 60%;
  background:
    radial-gradient(circle at 50% 42%, hsl(240deg 12% 20%) 0 0.85rem, transparent 0.95rem) -1rem calc(100% + 0.9rem) / 3.4rem 3rem repeat-x,
    radial-gradient(circle at 50% 45%, hsl(240deg 12% 16%) 0 0.7rem, transparent 0.8rem) 0.4rem calc(100% - 0.9rem) / 2.8rem 2.5rem repeat-x,
    radial-gradient(circle at 50% 48%, hsl(240deg 12% 12%) 0 0.55rem, transparent 0.65rem) -0.6rem calc(100% - 2.2rem) / 2.3rem 2.1rem repeat-x;
}

/* Applause is the house moving. On its feet for a clean take, warm and
   easy for the rest: the stage never boos. */
.theatre[data-applause] .theatre-house {
  animation: theatre-applause 0.7s ease-in-out infinite;
}

.theatre[data-applause="warm"] .theatre-house {
  animation-duration: 1.4s;
}

@keyframes theatre-applause {
  50% { transform: translateY(-0.25rem); }
}

.theatre-curtain {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 52%;
  background: repeating-linear-gradient(90deg,
    hsl(0deg 55% 34%) 0,
    hsl(0deg 65% 22%) 1.1rem,
    hsl(0deg 55% 34%) 2.2rem);
  box-shadow: 0 0 2rem hsl(0deg 0% 0% / 50%);
  transition: transform 1.4s cubic-bezier(0.6, 0, 0.3, 1);
}

.theatre-curtain--left { left: 0; }
.theatre-curtain--right { right: 0; }

/* The curtain never leaves the wings entirely: a sliver stays, the way a
   real house dresses its proscenium. */
.theatre[data-open] .theatre-curtain--left { transform: translateX(-94%); }
.theatre[data-open] .theatre-curtain--right { transform: translateX(94%); }
