/* ═══════════════════════════════════════════════════════════════════════
   Anshi Wang, the room
   Beat 4: the card recedes and dissolves, and the painted study settles in
   behind it. Everything here keys off body[data-phase='room'].

   The painting is fitted by room.js, which writes --room-w / --room-h /
   --room-x / --room-y on .room. Anything that must scale with the painting
   is sized from --room-u (1% of the painting's width), and anything that
   must sit on a painted object is placed in percentages inside
   .room__scene. Loaded after styles.css; panels.css styles the sheets that
   open over the room.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  /* unhurried, like the film: the room takes a long breath to settle */
  --room-in:   1900ms;
  --room-push: 4200ms;
  --room-ease: cubic-bezier(.22, .7, .28, 1);

  /* the room's in-world palette, shared with panels.css */
  --parch:      #ece2cc;
  --parch-ink:  #241c12;
  --parch-mute: #6f6552;
  --gilt:       #b8924a;
  --gilt-lit:   #f0d58a;
  --gilt-deep:  #7d5f28;

  /* the room's light: warm, from the upper left; and its shadow. RGB triples,
     so they can carry any alpha: rgba(var(--light), .3) */
  --light: 255, 190, 110;
  --shade: 14, 4, 0;
  /* fine grain, multiplied into the overlays so they carry the painting's texture */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='.55' intercept='-.05'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* ══ the room ════════════════════════════════════════════════════════ */

.room {
  /* fallbacks until room.js has measured; it overwrites all four */
  --room-w: 100vw;
  --room-h: 56.25vw;
  --room-x: 0px;
  --room-y: 0px;
  --room-u: calc(var(--room-w) / 100);

  position: fixed; inset: 0;
  z-index: 10;                     /* over the backdrop, under the card (20) */
  overflow: hidden;
  background: #0d0b0a;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.room:focus { outline: none; }

body[data-phase='room'] .room {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  /* the card is already dissolving; the room follows a beat behind it */
  transition: opacity var(--room-in) ease 450ms;
}

/* What the painting doesn't cover (portrait phones, awkward windows) is not
   black bars but the same painting, blurred and dimmed, so the room simply
   runs on past its own edges. */
.room__fill {
  position: absolute; inset: -8%;
  background: center / cover no-repeat;   /* src set by room.js */
  filter: blur(34px) brightness(.55) saturate(.9);
  opacity: 0;
  transition: opacity 1400ms ease;
}

/* The push-in. Wraps the scene so the fitted box keeps its own geometry. */
.room__zoom {
  position: absolute; inset: 0;
  transform: scale(.93);
  transform-origin: 56% 44%;       /* toward the window, the room's light */
  will-change: transform;
  transition: transform var(--room-push) var(--room-ease) 250ms;
}
body[data-phase='room'] .room__zoom { transform: none; }
.room.is-ready .room__zoom { will-change: auto; }

/* The painting's box, at the painting's exact aspect ratio. Zone layers are
   children of this and use percentages, so they follow it everywhere. */
.room__scene {
  position: absolute;
  left: var(--room-x);
  top:  var(--room-y);
  width:  var(--room-w);
  height: var(--room-h);
}

.room__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
  opacity: 0;
  transition: opacity 1400ms ease;
  -webkit-user-select: none; user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}

.room.is-loaded .room__fill,
.room.is-loaded .room__img { opacity: 1; }

/* a faint vignette, so anything laid over the room reads clearly */
.room__vignette {
  position: absolute; inset: 0;
  pointer-events: none;
  background:
    radial-gradient(125% 105% at 50% 46%,
      rgba(8,5,3,0) 58%, rgba(8,5,3,.34) 84%, rgba(8,5,3,.55) 100%);
}

/* ══ the card leaves ═════════════════════════════════════════════════
   It recedes as it fades, on the same expo curve the paper uses. The stage
   is hidden once it has gone, which also stops it swallowing pointer events
   meant for the room. */

body[data-phase='room'] .stage {
  opacity: 0;
  visibility: hidden;
  transition: opacity 1300ms ease, visibility 0s linear 1300ms;
}
body[data-phase='room'] .scaler {
  transform: scale(calc(var(--card-boost) * .9));
  transition: transform 1700ms var(--paper-ease);
}

/* Once the room has fully covered it, the blurred letters behind the card
   are dead weight for the GPU. */
body[data-phase='room'] .backdrop {
  visibility: hidden;
  transition: visibility 0s linear 2700ms;
}

/* ══ layers on the painting ══════════════════════════════════════════ */

.layer, .books, .trophies {
  position: absolute; inset: 0;
  pointer-events: none;
}
/* books are stacked against each other (each shades the next); keep that
   stacking inside the shelf, under anything that opens over the room */
.books { isolation: isolate; }

button.book, button.trophy, button.quad, .hit {
  -webkit-tap-highlight-color: transparent;
}

/* the whole shelf or desk as one target, for painting sizes too small to
   hit a single book or trophy */
.hit {
  position: absolute;
  margin: 0; padding: 0; border: 0;
  background: none;
  cursor: pointer;
  pointer-events: auto;
}
.hit[hidden] { display: none; }
.hit:focus-visible { outline: 2px solid var(--gilt-lit); outline-offset: 2px; }

/* the lamp. The painting has it lit, so switching it off lays a warm dark
   over its light: deepest on the bulb and shade, falling away across the
   wall, pillow and nightstand. Multiply keeps the painted texture showing
   through. --bx / --by (the bulb) are set by room.js. */
.lamp-off {
  position: absolute;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: multiply;
  background:
    radial-gradient(8% 5% at var(--bx) var(--by),
      rgba(22,13,7,.88) 0%, rgba(22,13,7,.7) 45%, rgba(22,13,7,0) 100%),
    radial-gradient(75% 45% at var(--bx) var(--by),
      rgba(40,24,12,.72) 0%, rgba(48,30,16,.45) 40%, rgba(60,38,20,0) 100%);
  transition: opacity 450ms ease;
}
.room.is-dark .lamp-off { opacity: 1; }
/* and the rest of the room loses a little of its warmth with it */
.room__vignette { transition: background-color 450ms ease; }
.room.is-dark .room__vignette { background-color: rgba(8,5,3,.12); }

/* ══ lighting · one light for every overlay ═════════════════════════════
   The room is lit warm from the upper left (the lamp and the windows), with
   deep shadow toward the lower right. The painting is also DARK where the
   overlays sit: its shelves, blanket and desk average close to black-brown.
   So nothing here is drawn in its own colours and dropped on top. Each
   overlay is dimmed to the painting's exposure, tinted toward its ambers,
   shaded light to dark along the same diagonal, softened to the painting's
   focus, and given shadows that fall where that light says: to the right and
   a little toward the viewer. */

/* ── books ───────────────────────────────────────────────────────────── */

/* room.js gives each book its size (--bw, --bh), leather (--tone), how dark
   that leather has aged (--dark), and a lean (--lean) about the corner it
   rests on (--pivot). Plain books are spans, not buttons: there is nothing
   behind them to open. A book lying on its side (.book--flat) swaps the two
   axes its shading runs along (--ax across the round of the spine, --ay
   along its length). */
.book {
  --ax: 90deg;
  --ay: 180deg;
  --ridge: calc(var(--room-u) * .07);
  position: absolute;
  width:  calc(var(--room-u) * var(--bw));
  height: calc(var(--room-u) * var(--bh));
  margin: 0; padding: 0; border: 0;
  background: none;
  transform-origin: var(--pivot, 50% 100%);
  transform: translate(-50%, -100%) rotate(var(--lean, 0deg));
  cursor: pointer;
  pointer-events: auto;
  transition: transform 260ms var(--room-ease), filter 260ms ease;
}
.book--plain { cursor: default; pointer-events: none; }
.book--flat { --ax: 180deg; --ay: 90deg; }

/* where it stands: a long soft shadow thrown along the board away from the
   light, and the tight dark line where the leather meets the wood */
.book::before,
.book::after {
  content: '';
  position: absolute;
  z-index: -1;
  pointer-events: none;
}
.book::before {
  left: 10%; width: 200%;
  bottom: calc(var(--room-u) * -.12);
  height: calc(var(--room-u) * .42);
  background: radial-gradient(closest-side at 26% 50%,
    rgba(var(--shade), .9), rgba(var(--shade), 0));
  filter: blur(calc(var(--room-u) * .06));
}
.book::after {
  left: -4%; right: -10%;
  bottom: calc(var(--room-u) * -.04);
  height: calc(var(--room-u) * .1);
  border-radius: 50%;
  background: rgba(var(--shade), .95);
  filter: blur(calc(var(--room-u) * .02));
}

/* The leather. Its edges are softened to the painting's focus; the title
   that sits on it is a separate layer, so it stays sharp enough to read.
   Layers, top first:
     the room's light, warm at the upper left and gone by the lower right
     the round of the spine: dark at both edges, a lit strip left of centre
     the head and tail, darker where the leather turns over the boards
     two raised bands a binder works across the spine, lit above, shaded below
     long faint streaks where the leather has worn
     grain, multiplied in
     the leather itself                                                      */
.book__body {
  position: absolute; inset: 0;
  border-radius: calc(var(--room-u) * .06) / calc(var(--room-u) * .04);
  background:
    linear-gradient(150deg,
      rgba(var(--light), .3) 0%, rgba(var(--light), .06) 35%,
      rgba(var(--shade), 0) 55%, rgba(var(--shade), .5) 100%),
    linear-gradient(var(--ax),
      rgba(var(--shade), .85) 0%, rgba(var(--shade), .3) 9%,
      rgba(var(--light), .22) 20%, rgba(var(--light), .46) 29%,
      rgba(var(--light), .14) 40%, rgba(var(--shade), .05) 56%,
      rgba(var(--shade), .45) 80%, rgba(var(--shade), .92) 100%),
    linear-gradient(var(--ay),
      rgba(var(--shade), .75) 0, rgba(var(--shade), 0) 6%,
      rgba(var(--shade), 0) 93%, rgba(var(--shade), .8) 100%),
    linear-gradient(var(--ay),
      transparent 0 9%,
      rgba(var(--light), .34) 9%, rgba(var(--light), .34) 10.2%,
      rgba(var(--shade), .6) 10.2%, rgba(var(--shade), .6) 11.6%,
      transparent 11.6% 87%,
      rgba(var(--light), .3) 87%, rgba(var(--light), .3) 88.2%,
      rgba(var(--shade), .6) 88.2%, rgba(var(--shade), .6) 89.6%,
      transparent 89.6%),
    repeating-linear-gradient(var(--ax),
      rgba(var(--shade), .14) 0 1px, transparent 1px 4px,
      rgba(var(--light), .05) 4px 5px, transparent 5px 9px),
    var(--grain) 0 0 / 120px 120px,
    var(--tone);
  background-blend-mode: normal, normal, normal, normal, normal, multiply, normal;
  box-shadow:
    /* the edge of the page block, caught by the light along the head */
    inset 0 calc(var(--room-u) * .045) 0 rgba(214, 176, 112, .26),
    /* the shadow it lays across its neighbour, to the right */
    calc(var(--room-u) * .16) calc(var(--room-u) * .02) calc(var(--room-u) * .2) rgba(var(--shade), .82),
    0 calc(var(--room-u) * .03) calc(var(--room-u) * .08) rgba(var(--shade), .9);
  filter: brightness(var(--dark, .6)) saturate(1.15) blur(calc(var(--room-u) * .012));
}
/* a book on its side shows the page block's edge along its top, not its head */
.book--flat .book__body {
  box-shadow:
    inset calc(var(--room-u) * .045) 0 0 rgba(214, 176, 112, .2),
    calc(var(--room-u) * .14) calc(var(--room-u) * .08) calc(var(--room-u) * .2) rgba(var(--shade), .82);
}

.book__title {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  overflow: hidden;               /* the type is fitted to the spine; this only guards it */
}
.book__text {
  display: block;
  writing-mode: vertical-rl;      /* reads top to bottom, as on a real spine */
  text-align: center;
  white-space: nowrap;
  font-family: var(--body);
  font-weight: 500;
  font-size: calc(var(--room-u) * var(--fs));
  line-height: 1.1;
  letter-spacing: .02em;
  color: #c79650;                  /* gilt, dimmed to the room's exposure */
  /* pressed into the leather: dark on the side away from the light, a
     thread of light on the side toward it */
  text-shadow:
    calc(var(--room-u) * .03) calc(var(--room-u) * .03) 0 rgba(var(--shade), .85),
    calc(var(--room-u) * -.02) calc(var(--room-u) * -.02) 0 rgba(var(--light), .18);
}
.book__line { display: block; }

/* the lift is for a pointer that can hover; on touch a tap opens the book, and
   a lift that stuck after the panel closed would look like a fault */
@media (hover: hover) {
  button.book:hover {
    z-index: 50 !important;
    transform: translate(-50%, calc(-100% - var(--room-u) * .4)) rotate(var(--lean, 0deg));
    filter: brightness(1.45) saturate(1.1);
  }
}
button.book:focus-visible {
  z-index: 50 !important;
  transform: translate(-50%, calc(-100% - var(--room-u) * .4)) rotate(var(--lean, 0deg));
  filter: brightness(1.45) saturate(1.1);
  outline: 1.5px solid var(--gilt-lit); outline-offset: 2px;
}

/* ── trophies ────────────────────────────────────────────────────────── */

.trophy {
  position: absolute;
  width:  calc(var(--room-u) * var(--tw));
  height: calc(var(--room-u) * var(--th));
  margin: 0; padding: 0; border: 0;
  background: none;
  transform: translate(-50%, -100%);
  cursor: pointer;
  pointer-events: auto;
  transition: transform 260ms var(--room-ease), filter 260ms ease;
}
.trophy svg {
  display: block;
  width: 100%; height: 100%;
  overflow: visible;
  /* dimmed and warmed to the painting, a shadow onto the wall behind it, and
     the slightest softening. (The metal itself is shaded light to dark along
     the light's diagonal, in the gradients defined in index.html.) */
  filter:
    brightness(.86) saturate(1.2)
    drop-shadow(calc(var(--room-u) * .2) calc(var(--room-u) * .08) calc(var(--room-u) * .2) rgba(var(--shade), .7))
    blur(calc(var(--room-u) * .016));
}
/* On a phone the painting has shrunk to a fraction of its size and the
   trophies with it (about 12 x 18 px), so the softening blur has nothing left
   to soften. Compact mode keeps the tone and the shadow and drops the blur, so
   the edges never depend on how an engine rounds a sub-pixel blur. */
.room.is-compact .trophy svg {
  filter:
    brightness(.86) saturate(1.2)
    drop-shadow(calc(var(--room-u) * .2) calc(var(--room-u) * .08) calc(var(--room-u) * .2) rgba(var(--shade), .7));
}
/* where it meets the desk: a dark pool right under the base, and a long soft
   shadow that the light throws to the right */
.trophy::before,
.trophy::after {
  content: '';
  position: absolute;
  z-index: -1;
  pointer-events: none;
}
.trophy::before {
  left: 4%; right: -12%;
  bottom: -5%; height: 11%;
  border-radius: 50%;
  background: radial-gradient(closest-side at 46% 45%,
    rgba(var(--shade), .98) 0%, rgba(var(--shade), .8) 45%, rgba(var(--shade), 0) 100%);
  filter: blur(calc(var(--room-u) * .035));
}
.trophy::after {
  left: 30%; width: 170%;
  bottom: -5%; height: 17%;
  background: radial-gradient(closest-side at 26% 50%, rgba(var(--shade), .5), rgba(var(--shade), 0));
  filter: blur(calc(var(--room-u) * .1));
}
@media (hover: hover) {
  .trophy:hover {
    transform: translate(-50%, calc(-100% - var(--room-u) * .4));
    filter: brightness(1.4) saturate(1.05);
  }
}
.trophy:focus-visible {
  transform: translate(-50%, calc(-100% - var(--room-u) * .4));
  filter: brightness(1.4) saturate(1.05);
  outline: 1.5px solid var(--gilt-lit); outline-offset: 3px;
}

/* ── sheets laid in perspective: the frame's grid, the newspaper ─────── */

/* room.js sets width, height and transform (a matrix3d from the calibrated
   corners), so these are drawn in their own flat pixels and bent afterwards */
.quad {
  position: absolute; left: 0; top: 0;
  margin: 0; padding: 0; border: 0;
  transform-origin: 0 0;
  cursor: pointer;
  pointer-events: auto;
  transition: filter 300ms ease;
}
.quad:focus-visible { outline: 3px solid var(--gilt-lit); outline-offset: 2px; }

/* the painting: dark linen, and the year in gold on it */
.frame {
  overflow: hidden;
  --soft: saturate(1.1) blur(.4px);
  --c0: rgba(230,130,60,.2);
  --c1: #82501f; --c2: #b06d25; --c3: #d98d33; --c4: #f3b654;
  background:
    var(--grain) 0 0 / 160px 160px,
    repeating-linear-gradient(0deg,  rgba(255,190,120,.04) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgba(0,0,0,.08) 0 1px, transparent 1px 3px),
    linear-gradient(150deg, #3c2210, #1e0f05);
  background-blend-mode: multiply, normal, normal, normal;
  /* the frame's lip throws its shadow across the top and left of the canvas,
     the side the light comes from; the far edges stay open */
  box-shadow:
    inset 7px 9px 15px rgba(var(--shade), .85),
    inset -2px -3px 9px rgba(var(--shade), .5),
    inset 0 0 0 1px rgba(var(--shade), .55);
  filter: var(--soft);
}
.frame__grid {
  position: absolute;
  left: 9px; right: 9px; top: 10px; bottom: 10px;
  display: grid;
  gap: 1.6px;
}
.cell {
  display: block;
  border-radius: 1.6px;
  background: var(--c0);
  transition: background-color 700ms ease;
}
.cell.lv1 { background: var(--c1); }
.cell.lv2 { background: var(--c2); }
.cell.lv3 { background: var(--c3); }
.cell.lv4 { background: var(--c4); box-shadow: 0 0 5px rgba(240,150,55,.45); }
.cell--none { background: transparent; }
/* the same light as everywhere else: warm on the upper left, deep at the lower right */
.frame__sheen {
  position: absolute; inset: 0;
  pointer-events: none;
  background:
    linear-gradient(135deg,
      rgba(var(--light), .32) 0%, rgba(var(--light), .09) 30%,
      rgba(var(--shade), 0) 48%, rgba(var(--shade), .58) 100%);
}
.frame.is-offline .frame__grid { opacity: .55; }
@media (hover: hover) {
  .frame:hover { filter: var(--soft) brightness(1.22); }
}

/* the newspaper: drawn 280 x 190, then laid on the blanket. The button
   itself is only a frame of reference; the sheet, and the two shadows that
   fall from it onto the blanket, are its children. */
.paper { overflow: visible; }
/* Only the room's newspaper (.quad.paper) from here on: the intro card and
   the resume share the .paper class name, and none of this is theirs. */
.quad.paper {
  background: none;              /* shows through the folded corner */
  /* the far corner is folded back on itself: this cuts it from the sheet
     (and from the shadow right under it), along the fold */
  --dogear: linear-gradient(40.6deg, #000 94.1%, transparent 94.7%);
}
.paper__cast,
.paper__contact,
.paper__sheet { position: absolute; inset: 0; }

/* the card's paper grain (styles.css shares the class name) is not this
   paper's: it would show through the folded corner */
.quad.paper::before,
.quad.paper::after { content: none; }

/* the long shadow the candle throws, toward the lower right; deepest along
   the front edge, where the sheet bends down and leaves the wool */
.paper__cast {
  background: linear-gradient(180deg, rgba(var(--shade), .8), rgb(var(--shade)) 70%);
  border-radius: 8px;
  transform: translate(14px, 18px) scale(1.04, 1.1);
  filter: blur(11px);
}
/* and the tight one where the paper actually rests on the wool */
.paper__contact {
  background: rgb(var(--shade));
  border-radius: 2px;
  transform: translate(2.5px, 4px);
  filter: blur(2.6px);
  -webkit-mask-image: var(--dogear);
          mask-image: var(--dogear);
}

/* the soft outer layer: everything on the sheet is softened together */
.paper__sheet {
  filter: saturate(1.08) brightness(.84) blur(.75px);
}

/* the paper itself */
.paper__face {
  position: absolute; inset: 0;
  overflow: hidden;
  /* paper over wool is never a true rectangle: unequal corners, and the blur
     on the sheet takes the last of the hardness off the edge. (A clip-path
     polygon was tried for a ragged edge, but it is cut without antialiasing
     once the sheet is bent into perspective, and leaves a row of teeth.) */
  border-radius: 3px 5px 2px 6px / 2px 3px 4px 2px;
  color: #3a220c;
  text-align: center;
  font-family: var(--display);
  /* aged newsprint in candlelight: a pool of warm light at the upper left,
     falling off into the brown of the shade, with foxing and grain, and a
     soft catch of light along the two edges that face the flame */
  background:
    linear-gradient(180deg, rgba(var(--light), .2) 0%, rgba(var(--light), 0) 9%),
    linear-gradient(90deg,  rgba(var(--light), .16) 0%, rgba(var(--light), 0) 7%),
    linear-gradient(135deg,
      rgba(var(--light), .3) 0%, rgba(var(--light), .1) 34%,
      rgba(var(--shade), 0) 52%, rgba(var(--shade), .7) 100%),
    radial-gradient(42% 36% at 12% 20%, rgba(255,190,110,.28), transparent 72%),
    radial-gradient(55% 45% at 84% 86%, rgba(70,26,4,.45), transparent 72%),
    var(--grain) 0 0 / 160px 160px,
    #82582e;
  background-blend-mode: normal, normal, normal, normal, normal, multiply, normal;
  box-shadow:
    inset 0 0 0 1px rgba(64,36,10,.4),
    inset 0 0 26px rgba(70,38,10,.6);
  -webkit-mask-image: var(--dogear);
          mask-image: var(--dogear);
}
.paper__face > span { position: absolute; }

/* The sheet is not flat: it sags into the blanket a little past the middle,
   catches the light again on the rise beyond, and bends down over the front
   edge and the right side, where it turns away from the flame. */
.paper__drape {
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg,
      rgba(0,0,0,0) 0%, rgba(var(--shade), .16) 40%, rgba(var(--shade), 0) 56%,
      rgba(var(--light), .16) 68%, rgba(var(--light), 0) 76%,
      rgba(var(--shade), .38) 92%, rgba(var(--shade), .68) 100%),
    linear-gradient(90deg,
      rgba(0,0,0,0) 0%, rgba(0,0,0,0) 78%,
      rgba(var(--shade), .2) 90%, rgba(var(--shade), .5) 100%),
    radial-gradient(38% 30% at 26% 64%, rgba(var(--light), .12), rgba(var(--light), 0));
}

/* The folded-back corner: the paper's back, lit where it turns up toward the
   light and in shade along the fold, laying a small shadow on the page.
   (The shadow is on this wrapper so the triangle's cut does not clip it.)
   Its corners are the cut corner reflected across the fold line, in the
   sheet's own 280 x 190 px. */
.paper__curl {
  position: absolute; inset: 0;
  pointer-events: none;
  filter: drop-shadow(-2px 3px 2.5px rgba(var(--shade), .6));
}
.paper__curl::before {
  content: '';
  position: absolute; inset: 0;
  clip-path: polygon(252.5px 0, 280px 24px, 256.2px 27.8px);
  background:
    linear-gradient(220deg,
      rgba(var(--shade), .5) 0%, rgba(var(--shade), .15) 30%,
      rgba(var(--light), .18) 70%, rgba(var(--light), .3) 100%) 252px 0 / 28px 28px no-repeat,
    var(--grain) 0 0 / 160px 160px,
    #8c6436;
  background-blend-mode: normal, multiply, normal;
}
.paper__mast {
  left: 0; right: 0; top: 8px;
  font-weight: 600; font-size: 33px; line-height: 1;
  letter-spacing: .03em; text-transform: uppercase;
}
.paper__meta {
  left: 14px; right: 14px; top: 49px;
  display: flex;
  justify-content: space-between;
  padding: 3px 0;
  border-top: 2px solid #3a220c;
  border-bottom: 1px solid #3a220c;
  font: italic 400 10px/1 var(--body);
}
.paper__head {
  left: 14px; right: 14px; top: 72px;
  font-weight: 600; font-size: 24px; line-height: 1.02;
  letter-spacing: .02em; text-transform: uppercase;
}
.paper__deck {
  left: 14px; right: 14px; top: 128px;
  font: italic 400 11.5px/1.1 var(--body);
}
.paper__cols {
  left: 14px; right: 14px; top: 147px; bottom: 10px;
  display: flex; gap: 9px;
}
.paper__col {
  flex: 1;
  background: repeating-linear-gradient(180deg, rgba(58,34,12,.75) 0 1.6px, transparent 1.6px 5px);
}
.paper__col--pic {
  background:
    linear-gradient(180deg, #56462f, #35281a) top / 100% 46% no-repeat,
    repeating-linear-gradient(180deg, rgba(58,34,12,.75) 0 1.6px, transparent 1.6px 5px);
}
/* where it was folded in half */
.paper__crease {
  left: 0; right: 0; top: 50%; height: 14px;
  transform: translateY(-50%);
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(0,0,0,0), rgba(46,26,6,.28) 46%, rgba(255,226,170,.26) 54%, rgba(0,0,0,0));
}
@media (hover: hover) {
  .paper:hover { filter: brightness(1.14) drop-shadow(0 0 5px rgba(255,190,110,.5)); }
}

/* ══ zones announce themselves once, softly ══════════════════════════
   When the room has settled, each zone breathes a little gilt light and
   then it is gone, so the eye knows what is there without a sign. */

.glow {
  position: absolute;
  pointer-events: none;
  opacity: 0;
  border-radius: 12%;
  background: radial-gradient(closest-side, rgba(255,214,140,.32), rgba(255,214,140,0));
}
.room.is-ready .glow { animation: breathe 2600ms ease-in-out 1 both; }
.room.is-ready .glow:nth-of-type(2) { animation-delay: 220ms; }
.room.is-ready .glow:nth-of-type(3) { animation-delay: 440ms; }
.room.is-ready .glow:nth-of-type(4) { animation-delay: 660ms; }
@keyframes breathe { 0% { opacity: 0; } 38% { opacity: 1; } 100% { opacity: 0; } }

/* ══ tooltips ════════════════════════════════════════════════════════ */

.tip {
  position: absolute; left: 0; top: 0;
  z-index: 6;
  width: max-content;              /* not squeezed by the room's right edge */
  max-width: min(340px, 86vw);
  padding: .42em .85em .5em;
  background: var(--parch);
  color: var(--parch-ink);
  border-radius: 4px;
  box-shadow: 0 8px 22px rgba(0,0,0,.5), 0 0 0 1px rgba(150,120,70,.45);
  font: 500 15px/1.25 var(--body);
  text-align: center;
  pointer-events: none;
  transform: translate(-50%, -100%);
  opacity: 0;
  transition: opacity 160ms ease;
}
.tip--below { transform: translate(-50%, 0); }
.tip.is-on { opacity: 1; }
.tip[hidden] { display: none; }
.room.has-panel .tip { display: none; }

/* ══ the small-screen way in · one word per zone ═════════════════════ */

.room__dock {
  position: absolute; left: 0; right: 0;
  bottom: calc(66px + env(safe-area-inset-bottom, 0px));
  z-index: 3;
  display: none;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0 1.5em;
  padding: 0 12px;
  pointer-events: none;
}
.room.is-compact .room__dock { display: flex; }
/* held sideways there is no spare band under the painting, so the row tucks
   into the bottom edge and takes a soft dark fade to read against the floor */
@media (min-aspect-ratio: 1/1) {
  .room__dock { bottom: calc(10px + env(safe-area-inset-bottom, 0px)); }
}
.room__dock::before {
  content: '';
  position: absolute; left: 0; right: 0; top: -36px; bottom: -70px;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(8,5,3,0), rgba(8,5,3,.6) 72%);
}
.room__dock button {
  position: relative;
  padding: .85em .1em;
  border: 0; background: none;
  font-family: var(--display);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .26em;
  text-indent: .26em;
  color: rgba(236,226,204,.62);
  text-shadow: 0 1px 3px rgba(0,0,0,.85);
  cursor: pointer;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
}
.room__dock button + button::before {
  content: '\00b7';
  position: absolute; left: -.95em; top: .82em;
  color: rgba(236,226,204,.4);
}
@media (hover: hover) { .room__dock button:hover { color: rgba(240,213,138,.95); } }
.room__dock button:focus-visible { outline: 1px solid var(--gilt-lit); outline-offset: 2px; }

/* ══ debug · ?debug on the address draws the zones over the painting ══ */

.dbg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  z-index: 30;
  overflow: visible;
}
.dbg line, .dbg rect, .dbg polygon, .dbg polyline {
  fill: none;
  vector-effect: non-scaling-stroke;
}
.dbg__grid  { stroke: rgba(0,255,255,.26); stroke-width: 1; }
.dbg__txt   { fill: #ffef7a; font: 11px monospace; paint-order: stroke; stroke: #000; stroke-width: 3px; }
.dbg__safe  { stroke: #ffee66; stroke-width: 1.5; stroke-dasharray: 8 5; }
.dbg__zone  { stroke: #44ff66; stroke-width: 1.5; }
.dbg__row   { stroke: #ff55ff; stroke-width: 1.5; }
.dbg__tick  { stroke: #44ffff; stroke-width: 1.5; }
.dbg__quad  { stroke: #ff8800; stroke-width: 1.5; fill: rgba(255,136,0,.12) !important; }

/* ══ reduced motion · cut to the room, no push-in, no breathing ═══════ */

@media (prefers-reduced-motion: reduce) {
  .room__zoom,
  body[data-phase='room'] .room__zoom { transform: none; transition: none; }

  body[data-phase='room'] .room { transition: opacity 320ms ease; }
  body[data-phase='room'] .stage {
    transition: opacity 320ms ease, visibility 0s linear 320ms;
  }
  body[data-phase='room'] .scaler { transform: scale(var(--card-boost)); transition: none; }
  body[data-phase='room'] .backdrop { transition-delay: 400ms; }

  .room__fill,
  .room__img { transition: opacity 300ms ease; }

  .room.is-ready .glow { animation: none; }
  .book, .trophy, .quad, .cell { transition: none; }
  .lamp-off, .room__vignette { transition: none; }
}
