/* Sharpie on the stall door — scaffolding for tests/stall.html.

   There is no handwriting font in this project, so the marker look is built:
   heavy weight at a small size, per-phrase rotation, the ink filters from the
   HTML, and a reveal edge that stands in for the pen tip. That keeps the copy
   real selectable text rather than an image or a hand-drawn path. */

.stall {
  position: relative;
  display: grid;
  gap: var(--s-8);
  justify-items: start;
  padding: var(--s-14) var(--s-8);
  border-radius: var(--r-md, 16px);
  /* the door: a flat painted panel, faintly uneven */
  background:
    radial-gradient(120% 100% at 30% 20%, rgba(255,255,255,.03), transparent 60%),
    color-mix(in srgb, var(--fg) 5%, transparent);
  box-shadow: inset 0 0 0 1px var(--rule);
}

.scrawl {
  position: relative;
  margin: 0;
  /* small: this is something muttered in a margin, never a headline */
  font-size: clamp(22px, 2.6vw, 34px);
  line-height: 1.15;
  letter-spacing: -.01em;
  /* the ink sits a touch under full white — marker on a painted surface never
     reads as bright as type does */
  color: color-mix(in srgb, var(--fg) 78%, transparent);
  /* all lowercase: nobody writing on a stall door reaches for the shift key, and
     it keeps these quieter than the set type around them */
  text-transform: lowercase;
  transform: rotate(var(--rot, 0deg));
  transform-origin: 0 50%;
  white-space: nowrap;
}

/* the roughening filter is what stops this reading as set type */
[data-ink], [data-chars] { filter: url(#inkRough); }
[data-bleed] { filter: url(#inkBleed); }

/* ── 01 / 04 / 05 · marker wipe ─────────────────────────────────────────── */

/* clip-path is the pen tip: the phrase is fully laid out from the start and the
   window over it opens left to right, so nothing reflows as it "writes" */
.scrawl--wipe {
  clip-path: inset(0 100% 0 0);
  transition: clip-path 1s steps(24, end);
  transition-delay: var(--d, 0ms);
}
.stall.is-writing .scrawl--wipe { clip-path: inset(0 -2% 0 0); }

/* ── 02 · bleed in ──────────────────────────────────────────────────────── */

.scrawl--bleed {
  opacity: 0;
  transition: opacity 1.1s var(--ease);
  transition-delay: var(--d, 0ms);
}
.stall.is-writing .scrawl--bleed { opacity: 1; }

/* ── 03 · letter by letter ──────────────────────────────────────────────── */

/* the spans are built in script from the text content */
.scrawl--chars .ch {
  display: inline-block;
  opacity: 0;
  /* each character gets its own tilt and baseline offset, so the line is uneven
     the way a hand is uneven rather than uniformly rotated */
  transform: translateY(var(--dy, 0px)) rotate(var(--cr, 0deg));
  transition: opacity .12s linear;
  transition-delay: var(--cd, 0ms);
}
.scrawl--chars .ch--space { width: .32em; }
.stall.is-writing .scrawl--chars .ch { opacity: 1; }

/* ── 04 · struck through ────────────────────────────────────────────────── */

/* the crossing-out stroke: drawn after the phrase has finished writing */
.scrawl--struck::after {
  content: "";
  position: absolute;
  left: -2%;
  right: -2%;
  top: 52%;
  height: 3px;
  background: currentColor;
  border-radius: 2px;
  transform: scaleX(0) rotate(-1.2deg);
  transform-origin: 0 50%;
  transition: transform .42s var(--ease);
  /* the phrase's own wipe finishes at 1s + its delay; the stroke follows it */
  transition-delay: calc(var(--d, 0ms) + 1.15s);
}
.stall.is-writing .scrawl--struck::after { transform: scaleX(1) rotate(-1.2deg); }

/* ── 05 · the reply ─────────────────────────────────────────────────────── */

/* a second hand: smaller, lighter, indented, and lowercase in the copy itself */
.scrawl--reply {
  margin-left: var(--s-14);
  font-size: clamp(16px, 1.7vw, 22px);
  color: color-mix(in srgb, var(--fg) 55%, transparent);
}

/* ── 06 · placed in the real section ────────────────────────────────────── */

.stalldemo { border-top: 1px solid var(--rule); }

/* absolutely positioned so the scrawls sit in the column's dead space and never
   push the section's own copy around */
.stall--placed {
  position: relative;
  min-height: 340px;
  margin-top: var(--s-12);
  padding: 0;
  background: none;
  box-shadow: none;
  display: block;
}
.stall--placed .scrawl {
  position: absolute;
  left: var(--x, 0);
  top: var(--y, 0);
}

@media (max-width: 767px) {
  /* stacked on a phone: absolute placement in a narrow column collides */
  .stall--placed { min-height: 0; display: grid; gap: var(--s-6); justify-items: start; }
  .stall--placed .scrawl { position: static; }
}

@media (prefers-reduced-motion: reduce) {
  /* the writing is the whole effect, so with motion off it is simply already
     written rather than animated more cheaply */
  .scrawl--wipe { clip-path: none; transition: none; }
  .scrawl--bleed { opacity: 1; transition: none; }
  .scrawl--chars .ch { opacity: 1; transform: none; transition: none; }
  .scrawl--struck::after { transform: scaleX(1) rotate(-1.2deg); transition: none; }
}
