/* ─────────────────────────────────────────────
   ROOM GEOMETRY — change these four numbers and
   the walls, floor lines and doors all follow.
   ───────────────────────────────────────────── */
:root {
  --wall-left: 18%;    /* side wall depth  */
  --wall-top: 8%;      /* ceiling depth    */
  --wall-width: 64%;
  --wall-height: 78%;  /* floor starts at top + height */
  --ink: #000;
  --red: #ff0000;
  --blue: #0000ff;
  --paper: #fff;
  --wall-margin: 6%;   /* no art hangs inside this border */

  /* type — set by the Tweaks panel, override here for a permanent choice */
  --font: ui-monospace, Menlo, Consolas, monospace;  /* e.g. "BIZ UDMincho", serif */
  /* each role stretches on x and y independently */
  --wall-text-x: 1; --wall-text-y: 1;   /* the text that fills the wall */
  --hall-x: 1;      --hall-y: 1;        /* the series list */
  --nav-x: 1;       --nav-y: 1;         /* ^ hall / ^ entrance / counter */
  --floor-ink: 0.35;                      /* floorboard line strength */
  --tracking: 0.04em;                     /* letter spacing, all text */
  --hall-tracking: 0.04em;                /* the series list only */
}

html, body { margin: 0; padding: 0; background: var(--paper); overflow: hidden; -webkit-text-size-adjust: 100%; }
a { color: var(--blue); text-decoration: none; }
a:hover { color: var(--red); }
::selection { background: var(--red); color: #fff; }

.room {
  position: fixed; inset: 0;
  background: var(--paper); color: var(--ink);
  font-family: var(--font);
  letter-spacing: var(--tracking);
  overflow: hidden; touch-action: manipulation;
}

/* the four corner lines */
.room-lines { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; }
.room-lines line { stroke: var(--ink); stroke-width: 1; vector-effect: non-scaling-stroke; }
/* floorboards: rows closer together as they recede, occasional plank ends */
.room-lines .floor line { opacity: var(--floor-ink, 0.35); }

/* ── side doors: prev (red, left) / next (blue, right) ──
   .door-zone is the invisible tap target on the side wall.
   .door is the trapezoid; its bottom edge sits on the floor line. */
.door-zone { position: absolute; top: 60%; height: 40%; width: 17.5%; z-index: 5; cursor: pointer; }
.door-zone.left { left: 0; }
.door-zone.right { right: 0; }
.door { position: absolute; top: 17.5%; height: 82.5%; width: 68.57%; }
.door.prev { left: 17.14%; background: var(--red);
  clip-path: polygon(0% 11.1%, 100% 2.5%, 100% 64.7%, 0% 92.9%); }
.door.next { right: 17.14%; background: var(--blue);
  clip-path: polygon(100% 11.1%, 0% 2.5%, 0% 64.7%, 100% 92.9%); }

/* ── the guestbook pages with triangles instead of doors ── */
/* paging the guestbook: triangles drawn on the side walls, in the
   same hand as the sound switch and the gift shop sign */
.wall-arrow {
  fill: none; stroke-width: 1.5; vector-effect: non-scaling-stroke;
  /* the whole triangle is the target: with fill:none, the default
     hit-testing leaves only the stroke, which is unclickable */
  pointer-events: all;
  cursor: pointer; transition: fill 90ms linear;
}
.wall-arrow.prev { stroke: var(--red); }
.wall-arrow.next { stroke: var(--blue); }
.wall-arrow.prev:hover { fill: var(--red); }
.wall-arrow.next:hover { fill: var(--blue); }

/* ── the back wall ── */
.wall {
  position: absolute; max-width: 100%;
  left: var(--wall-left); top: var(--wall-top);
  width: var(--wall-width); height: var(--wall-height);
  border: 1px solid var(--ink); background: var(--paper);
  box-sizing: border-box; z-index: 3; overflow: hidden;
}
.wall-guide {
  position: absolute; inset: var(--wall-margin);
  border: 1px dashed #bbb; pointer-events: none; z-index: 9;
}
.layer { position: absolute; inset: 0; }

/* ── entrance: the two plain doors on the welcome wall ── */
.entry-plain { position: absolute; bottom: 0; cursor: pointer; }

/* ── the hall's single wide door: white lettering, inverts on hover ── */
.hall-door {
  position: absolute; bottom: 0; z-index: 3;
  display: flex; align-items: center; justify-content: center;
  background: var(--door); color: #fff;
  border: 1px solid var(--door);
  box-sizing: border-box; cursor: pointer;
  transition: background 90ms linear, color 90ms linear;
}
.hall-door:hover { background: #fff; color: var(--door); }
.hall-door-label {
  font-size: calc(clamp(13px, 2.3vmin, 26px) * var(--hall-y));
  letter-spacing: var(--hall-tracking);
  padding: 0 8%; text-align: center; text-wrap: balance;
}

/* ── hall: the series links, scattered but always in the same spot ── */
.hall-layer { position: absolute; inset: 0; }
.hall { position: absolute; inset: var(--wall-margin); overflow: hidden; }
/* links come out of the door: they start at the door and land
   on their fixed scattered spot */
.scatter {
  position: absolute; cursor: pointer; max-width: 60%;
  opacity: 1; z-index: 2;
  /* dead until every link has landed, and during the retract */
  pointer-events: var(--links-pe, none);
}
/* the travel is a keyframe animation, which runs on mount without
   needing the closed state to be painted first. a `from`-only
   keyframe animates from the door to the link's own resting spot. */
@keyframes emerge {
  from { left: var(--door-x); top: var(--door-y); opacity: 0; }
}
@keyframes retract {
  to { left: var(--door-x); top: var(--door-y); opacity: 0; }
}
.scatter-inner { display: block; }
.scatter:hover .scatter-inner { animation: wriggle 130ms linear infinite; }
@keyframes wriggle {
  0%   { transform: translate(0, 0) rotate(0deg); }
  25%  { transform: translate(-1px, 1px) rotate(-1.1deg); }
  50%  { transform: translate(1px, -1px) rotate(0.9deg); }
  75%  { transform: translate(1px, 1px) rotate(-0.6deg); }
  100% { transform: translate(0, 0) rotate(0deg); }
}
.scatter-label {
  display: block; text-decoration: underline; text-underline-offset: 2px;
  font-size: calc(clamp(14px, 2.5vmin, 28px) * var(--hall-y));
  letter-spacing: var(--hall-tracking);
  transform-origin: left top; transform: scaleX(var(--hall-x));
  overflow-wrap: anywhere;
}
/* the location sits under the name, in ink, not in the grey of the count */
.scatter-place {
  display: block; margin-top: 0.55em; color: var(--ink);
  font-size: calc(clamp(11px, 1.7vmin, 18px) * var(--hall-y));
  letter-spacing: var(--hall-tracking);
  transform-origin: left top; transform: scaleX(var(--hall-x));
}
.scatter-count {
  display: block; color: #999; margin-top: 0.7em;
  font-size: calc(clamp(9px, 1.35vmin, 14px) * var(--hall-y));
  letter-spacing: var(--hall-tracking);
  transform-origin: left top; transform: scaleX(var(--hall-x));
}

/* ── wall text: fills the whole wall when a piece is clicked ── */
.wall-text {
  position: absolute; inset: 0; background: var(--paper); cursor: pointer;
  z-index: 10; padding: var(--wall-margin); box-sizing: border-box;
  overflow-x: hidden; overflow-y: auto;   /* never scrolls sideways */
  display: flex; flex-direction: column; justify-content: center; justify-content: safe center; gap: 14px;
}
.wall-text p {
  /* descriptions carry their own line breaks */
  margin: 0; line-height: 1.55; text-wrap: pretty; overflow-wrap: anywhere;
  white-space: pre-wrap;
  font-size: calc(clamp(14px, 2.2vmin, 24px) * var(--wall-text-y));
  width: calc(100% / var(--wall-text-x));
  transform-origin: left top; transform: scaleX(var(--wall-text-x));
}
.wall-text .meta {
  margin: 0; color: #888;
  font-size: calc(clamp(10px, 1.4vmin, 14px) * var(--nav-y));
  width: calc(100% / var(--nav-x));
  transform-origin: left bottom; transform: scaleX(var(--nav-x));
}

/* ── the drawn sign and the side door on the right wall ── */
.wall-title polyline { fill: none; stroke: var(--ink); stroke-width: 1; vector-effect: non-scaling-stroke; }
.side-door {
  fill: #8a8a8a; stroke: none;
  cursor: pointer; transition: fill 140ms linear;
}
.side-door:hover { fill: #d8d8d8; }

/* the centre object: a png standing on the floor */
/* a mark hung on the back wall: positioned in the wall's own
   coordinates, so it sits flat on it like any other piece */
.wall-mark {
  position: absolute; z-index: 6;
  background-repeat: no-repeat; background-position: center; background-size: contain;
}

/* the gift shop's logo, centred on the wall and clickable */
.shop-mark {
  left: 50%; top: 42%; transform: translate(-50%, -50%);
  width: 18.7%; aspect-ratio: 1 / 1; cursor: pointer;
  /* the placeholder, until the object's image is set in rooms.js */
  background-image: repeating-linear-gradient(45deg, #f2f2f2 0 6px, #ffffff 6px 12px);
}

/* the mark on the index wall: small, upper right */

/* the bio, taking the wall */
.wall-bio {
  position: absolute; inset: 0; background: var(--paper); cursor: pointer;
  z-index: 10; padding: var(--wall-margin); box-sizing: border-box;
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 1.1em;
}
.wall-bio h3 {
  margin: 0.7em 0 -0.5em; font-weight: 700;
  font-size: calc(clamp(13px, 1.9vmin, 20px) * var(--wall-text-y));
  letter-spacing: var(--tracking);
}
.wall-bio h3:first-child { margin-top: 0; }
/* the contact block sits smaller and further down */
.wall-bio h3.bio-contact {
  margin-top: 2.4em;
  font-size: calc(clamp(11px, 1.5vmin, 16px) * var(--wall-text-y));
}
.wall-bio p {
  margin: 0; line-height: 1.55; text-wrap: pretty;
  font-size: calc(clamp(12px, 1.75vmin, 19px) * var(--wall-text-y));
}
.wall-bio .bio-links {
  margin: 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 4px;
}
.wall-bio .bio-links a {
  font-size: calc(clamp(10px, 1.3vmin, 14px) * var(--wall-text-y));
  text-decoration: none;
}
.wall-bio .meta { margin-top: auto; padding-top: 0.8em; color: #888; font-size: calc(clamp(10px, 1.4vmin, 14px) * var(--nav-y)); }

/* ── video works: the piece plays on entry; its text is a tap away,
      fullscreen sits under the frame's right edge ── */
/* a grid, not a flex column: a 1fr track has a definite height, so the
   frame's percentage height resolves against it. in a flex column the
   two size off each other and the frame collapses. */
/* the slot places its parts directly: flex and grid both tried to size
   the frame off its own ratio box and collapsed it */
.work-slot { display: block; }
/* filling the window, for when the browser refuses real fullscreen
   (it always does inside an embedding frame) */
.work-slot.cinema {
  position: fixed !important; inset: 0 !important;
  left: 0 !important; top: 0 !important;
  width: 100vw !important; height: 100vh !important;
  z-index: 10000; background: #000;
  justify-content: center; padding: 0;
}
.work-slot.cinema .work-frame {
  border: 0; aspect-ratio: auto !important; height: 100% !important;
  width: 100% !important; max-height: none !important; max-width: none !important;
}
.work-slot.cinema .work-asides { display: none; }
/* the emulator keeps a margin in fullscreen, and its close label
   sits in that band */
.work-slot.cinema .work-fit { inset: 0 !important; }
.work-slot.cinema .emu-note { display: none; }
.work-slot.cinema .emu-shell {
  inset: 0; padding: 0; box-sizing: border-box; background: #000;
}
/* a sibling of the shell, so the shell's overflow clip cannot eat it */
.emu-close {
  position: absolute; right: 1.1em; bottom: 0.8em; height: 2em;
  display: flex; align-items: center; justify-content: flex-end;
  cursor: pointer; color: #fff; z-index: 9;
  text-shadow: 0 0 6px #000, 0 0 2px #000;
  font-size: clamp(12px, 1.6vmin, 18px); letter-spacing: var(--tracking);
}
.emu-close:hover { color: #39ff6a; }
.work-slot.cinema .work-download { display: none; }
.work-slot.cinema .work-tools {
  position: absolute; left: 16px; right: 16px; bottom: 14px; margin: 0; z-index: 2;
}
.work-slot.cinema .work-tools .nav-link { color: #fff; }
.work-slot.cinema .work-tools .nav-link:hover { color: #ffe94d; }
/* the flexible box: it takes whatever the natural-height control rows
   leave, and the frame inside keeps its ratio without shrinking */
/* a still work stays in normal flow: the frame's ratio is what gives
   its slot a height at all */
.work-fit { display: flex; align-items: center; justify-content: center; }

/* a slot with a definite height places its parts directly instead —
   flex and grid both sized the frame off its own ratio box there */
.work-slot.fixed-h .work-fit {
  position: absolute; left: 0; right: 0; top: 0; bottom: 0;
}
.work-slot.fixed-h.video .work-fit { bottom: 2.6em; }
/* the reserve holds the asides stack and the download row in turn */
.work-slot.fixed-h.has-asides .work-fit { bottom: 8.4em; }
.work-slot.fixed-h.has-asides .work-download { bottom: 0; }
.work-slot.fixed-h .work-tools,
.work-slot.fixed-h .work-download { position: absolute; left: 0; right: 0; bottom: 0; }
.work-slot.fixed-h.has-asides .work-tools { bottom: 3.4em; }
.work-frame { position: relative; width: 100%; }
/* a video slot fills the safe area; its frame keeps the work's ratio,
   centred, with the controls tucked under the frame's own edges */
.work-slot.video { align-items: stretch; justify-content: center; }
/* the frame yields to the label rows below it */

.work-tools {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 12px; z-index: 5;
}
.work-tools .nav-link { padding: 2px 0; }
/* the emulator fills the frame, over the video. its own chrome sticks
   out past the canvas, so the shell clips it. */
.emu-shell { position: absolute; inset: 0; z-index: 4; background: #000; overflow: hidden; }
.emu-box { width: 100%; height: 100%; }
.emu-frame {
  width: 100%; height: 100%; border: 0; display: block; background: #000;
  overflow: hidden;
}
/* the emulator's own context menu cannot dismiss inside our frame, and
   the room supplies its own controls */
.emu-shell .ejs_context_menu { display: none !important; }
.work-download {
  display: flex; flex-wrap: wrap; justify-content: center;
  align-items: baseline; gap: 0 0.6em;
}
.work-download .emu-note { flex: 1 0 100%; }
/* the secondary links hang off the frame's own bottom-right corner, so
   their right edge lines up with the work rather than the wall */
.work-asides {
  position: absolute; top: 100%; right: 0; z-index: 5;
  display: flex; flex-direction: column; align-items: flex-end;
  gap: 1px; padding-top: 0.5em;
}
.work-asides .nav-link { padding: 1px 0; }
.work-asides .nav-link:hover { color: #39ff6a; }
.work-asides .aside-gap { margin-top: 0.9em; }
.download-link {
  font-size: calc(clamp(15px, 2.2vmin, 26px) * var(--nav-y));
  letter-spacing: var(--tracking);
  color: #ff2fb9; text-decoration: none; padding: 4px 8px;
}
.download-link:hover { color: #39ff6a; }
.work-tools-right {
  display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
}

/* ── play mark: only appears if the browser refused to autoplay ── */
.play-mark-hit {
  position: absolute; inset: 0; z-index: 3; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.work-media {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border: 0; background: #000; display: block;
  pointer-events: none;   /* the hit layer above owns the gesture */
}
/* never smaller than a finger, however small the frame is */
.work-hit {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: max(100%, 44px); height: max(100%, 44px);
  z-index: 2; cursor: pointer;
}
.play-mark { width: 15%; min-width: 26px; pointer-events: none; }
.play-mark polygon { fill: none; stroke: var(--ink); stroke-width: 1.5; }

/* ── the sound switch on the left wall ── */
.sound-switch { cursor: pointer; }
.sound-plate { fill: #f2f2f2; stroke: none; }
.sound-switch.on .sound-plate { fill: #ffe94d; }
.sound-switch:hover .sound-plate { fill: #fff; }
/* the note lies on the left wall: rotated about Y so its far (right)
   edge recedes, matching the wall's plane */
.sound-word { fill: none; stroke: var(--ink); stroke-width: 1; vector-effect: non-scaling-stroke; }
.sound-switch line { stroke: var(--ink); stroke-width: 1; vector-effect: non-scaling-stroke; }

/* ── gift shop: wall menu, comment form, guestbook ── */
.wall-menu {
  position: absolute; inset: var(--wall-margin);
  display: flex; flex-direction: column; align-items: flex-start;
  justify-content: flex-end; gap: 6px;
}
.wall-menu .nav-link { padding-left: 0; }
.wall-form {
  position: absolute; inset: var(--wall-margin);
  display: flex; flex-direction: column; justify-content: center; justify-content: safe center; gap: 10px;
  overflow-x: hidden; overflow-y: auto;
  width: min(46ch, 100%); margin: 0 auto; left: 0; right: 0;
}
.form-row { justify-content: flex-start; }
.field { display: flex; flex-direction: column; gap: 3px; }
.field span { font-size: calc(11px * var(--nav-y)); color: #777; }
.field input, .field textarea {
  font: inherit; font-size: calc(13px * var(--nav-y)); color: var(--ink);
  letter-spacing: var(--tracking);
  background: var(--paper); border: 1px solid var(--ink); border-radius: 0;
  padding: 6px 8px; width: 100%; box-sizing: border-box; resize: vertical;
}
.field input:focus, .field textarea:focus { outline: 1px solid var(--blue); outline-offset: 1px; }
.check { display: flex; align-items: flex-start; gap: 8px; font-size: calc(12px * var(--nav-y)); }
.check input { accent-color: var(--ink); margin: 2px 0 0; }
.form-row { display: flex; gap: 16px; margin-top: 2px; }
.form-sent { display: flex; flex-direction: column; gap: 10px; }
.form-sent p { margin: 0; font-size: calc(14px * var(--nav-y)); }
.wall-book {
  position: absolute; inset: var(--wall-margin);
  display: flex; flex-direction: column;
  overflow-x: hidden; overflow-y: auto;
}
.book-body {
  flex: 1 1 auto; display: flex; flex-direction: column;
  justify-content: center; justify-content: safe center; gap: 12px; min-height: 0;
  padding: 0; box-sizing: border-box;
}
.book-back { flex: none; align-self: center; padding-top: 0.6em; }
.book-text {
  margin: 0; line-height: 1.55; text-wrap: pretty; overflow-wrap: anywhere;
  font-size: calc(clamp(14px, 2.2vmin, 24px) * var(--wall-text-y));
  width: calc(100% / var(--wall-text-x));
  transform-origin: left top; transform: scaleX(var(--wall-text-x));
}
.book-meta { margin: 0; font-size: calc(11px * var(--nav-y)); color: #999; }

/* ── floor strip: hall / entrance / counter ── */
.floor-bar {
  /* the floor band: below the back wall, never over it */
  position: absolute; left: 0; right: 0;
  top: calc(var(--wall-top) + var(--wall-height)); bottom: 0; z-index: 4;
  display: flex; align-items: flex-end; justify-content: center;
  padding-bottom: clamp(4px, 1vh, 12px); pointer-events: none;
}
.floor-nav {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  pointer-events: auto;
}
.nav-slot {
  min-height: calc(1.3em * var(--nav-y)); display: flex;
  align-items: center; justify-content: center;
}
.nav-link {
  cursor: pointer; font-size: clamp(11px, 1.5vmin, 17px); color: var(--blue); padding: 2px 6px;
  display: inline-block; transform-origin: center bottom;
  transform: scale(var(--nav-x), var(--nav-y));
}
.nav-link:hover { color: var(--red); }
.counter {
  position: absolute; right: 4%; bottom: clamp(6px, 1.4vh, 14px);
  font-size: clamp(10px, 1.3vmin, 15px); color: #999;
  display: inline-block; transform-origin: center bottom;
  transform: scale(var(--nav-x), var(--nav-y));
}

/* ── the 2Ds split: text on one half, the piece enlarged on the other ── */
.wall-text.split { display: flex; gap: 3%; align-items: stretch; }
/* the piece keeps the side of the wall it was hung on */
.wall-text.split.art-first .wall-text-art { order: 0; }
.wall-text.split.art-first .wall-text-body { order: 1; }
.wall-text.split.art-last .wall-text-art { order: 1; }
.wall-text.split.art-last .wall-text-body { order: 0; }
.wall-text.split.split-row { flex-direction: row; }
.wall-text.split.split-col { flex-direction: column; }
.wall-text.split .wall-text-art {
  flex: 1 1 64%; min-width: 0; min-height: 0; align-self: stretch;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.wall-text.split .art-sheet {
  width: 100%; height: 100%;
  background-repeat: no-repeat; background-position: center; background-size: contain;
}
/* a tall sheet fills its half edge to edge and scrolls down it */
.wall-text.split .wall-text-art.tall {
  align-items: safe flex-start; overflow-x: hidden; overflow-y: auto;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  /* no scrollbar, so the sheet gets the full width of its half */
  scrollbar-width: none; -ms-overflow-style: none;
}
.wall-text.split .wall-text-art.tall::-webkit-scrollbar { width: 0; height: 0; display: none; }
.wall-text.split .wall-text-art.tall .art-sheet {
  flex: 0 0 auto; width: 100%; height: auto;
  background-size: 100% 100%;
}
.wall-text.split .wall-text-body {
  flex: 0 1 33%; min-width: 0; min-height: 0;
  display: flex; flex-direction: column; justify-content: center; justify-content: safe center; gap: 14px;
  overflow-x: hidden; overflow-y: auto;
}
.wall-text:not(.split) .wall-text-body {
  display: flex; flex-direction: column;
  justify-content: center; justify-content: safe center; gap: 14px;
}

/* ── a text-only work: the writing IS the piece, and it scrolls ── */
.work-body {
  position: absolute; inset: 0; cursor: pointer;
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: none; -ms-overflow-style: none;
  padding-right: 2%; box-sizing: border-box;
  /* the writing IS the work here, so it is set at least as large as
     the wall text that captions it */
  font-size: calc(clamp(16px, 2.7vmin, 26px) * var(--wall-text-y));
  line-height: 1.6; letter-spacing: var(--tracking);
  color: var(--ink); text-wrap: pretty; white-space: pre-wrap;
}
.work-body::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* ── a large web build: the wait is declared, then shown ── */
.emu-note {
  position: absolute; left: 0; right: 0; bottom: 4.2em;
  margin: 0 auto; max-width: 46ch; text-align: center; z-index: 5;
  font-size: calc(clamp(9px, 1.2vmin, 13px) * var(--nav-y));
  line-height: 1.45; color: #888; text-wrap: pretty;
}
.emu-loading {
  position: absolute; inset: 0; z-index: 4;
  display: flex; align-items: center; justify-content: center;
  background: var(--paper);
}
.emu-loading p {
  margin: 0; max-width: 28ch; text-align: center;
  font-size: calc(clamp(11px, 1.5vmin, 16px) * var(--nav-y));
  line-height: 1.5; color: #666; text-wrap: pretty;
}

/* the title line of a caption */
.wall-text-body .text-title {
  margin: 0 0 0.55em; font-weight: 700;
  font-size: calc(clamp(15px, 2.4vmin, 26px) * var(--wall-text-y));
  letter-spacing: var(--tracking); line-height: 1.3;
}

/* a caption open for editing: it keeps its finished look, so what is
   typed is what a visitor reads */
.wall-text-body .cap-live {
  cursor: text; outline: 1px dashed #c8c8c8; outline-offset: 5px;
  min-height: 1em; white-space: pre-wrap;
}
.wall-text-body .cap-live:focus { outline: 1px solid var(--blue); }
.wall-text-body .cap-live:empty::before {
  content: attr(data-placeholder); color: #bbb;
}

/* a caption that has been rewritten locally */
.wall-text-body .meta-edited { color: var(--red); }
