/* ==========================================================================
   THE FOYER — Babycakes Design Studio lobby (SPEC "The lobby", criterion I)

   Art direction
   -------------
   The room is a photograph (the studio's own canonical render). Everything the
   client reads is live type set over it, and every interactive state is made of
   LIGHT rather than pasted-on widgets: hovering a door brightens that exact
   door inside the photograph, clipped along its real architectural edges so
   the seam has nowhere to show.

   Two layouts, one DOM
   --------------------
   >= 740px  cinematic. The stage is letterboxed to the plate's exact aspect
             ratio, which is what lets percentage coordinates land on real
             architecture and puts the hit areas on the actual doors.
   <  740px  stacked. A portrait crop carries the room whole (contain,
             nothing beheaded) and the two doors become full-width plates.

   Structure: everything above §7 is shared. ALL stage-coordinate geometry and
   every container-relative (cqw) size lives inside §7's media query, because a
   `.door--office .door__title` rule outranks a `.door__title` rule no matter
   which query it sits in -- leak one into portrait and the plates render with
   4px type. Keep new geometry inside the breakpoint that owns it.

   Survey of the landscape plate (percentages, measured off the render):
     frosted office door   glass quad   x 13.4-28.7%   y  9.9-86.0%
     brass lever                        x 16.9-23.9%   y 55.0-63.6%
     gallery doorway       opening      x 58.5-68.5%   y 29.7-74.1%
     chrome clover, back wall           x 38.0-53.0%   y 35.0-60.0%
   The office door sits on the receding left wall, so its horizontals converge
   on a vanishing point measured at (68.6%, 56.8%). At the lettering height the
   plane rakes 10.4deg; the threshold below it rakes -16.4deg. Type and light
   laid onto that plane are sheared to match, which is why the sign reads as
   painted on the glass rather than pasted over it.
   ========================================================================== */

@font-face {
  font-family: "Cinzel Foyer";
  src: url("/assets/cinzel-foyer.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --ar: 1.791713;                 /* 1600 / 893, the canonical landscape plate */
  --ar-portrait: 0.822669;        /*  900 / 1094, the canonical portrait crop */
  --rake: 10.4deg;                /* office door plane at lettering height */
  --rake-sill: -16.4deg;          /* its threshold */

  --void: #06070a;
  --ink: #edf0f7;

  --gold-hi: #fff3d2;
  --gold-mid: #e3c489;

  /* gilding: bright for dark grounds, deeper for the lit frosted glass */
  --gild: linear-gradient(177deg,
      #fff8e4 0%, #f2d9a4 24%, #d8b169 46%,
      #a9822f 68%, #e7d3a0 88%, #fff2cf 100%);
  --gild-glass: linear-gradient(177deg,
      #fff9e6 0%, #eec888 22%, #c2934a 50%,
      #8d6826 72%, #dcbc76 90%, #fff2d2 100%);
  /* polished nickel, kept off the dark end so small sizes stay legible */
  --chrome: linear-gradient(168deg,
      #ffffff 0%, #eef3fa 24%, #c3ccdb 52%,
      #9aa5b6 66%, #dde5ef 84%, #ffffff 100%);

  --display: "Cinzel Foyer", "Cinzel", Didot, "Bodoni 72", Baskerville,
             "Times New Roman", serif;
  --text: ui-sans-serif, -apple-system, "Segoe UI", Inter, Roboto,
          "Helvetica Neue", Arial, sans-serif;

  --ease: cubic-bezier(.2, .7, .2, 1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body { height: 100%; }

body {
  background:
    radial-gradient(120% 90% at 50% 46%, #0d0f16 0%, var(--void) 58%, #030407 100%);
  color: var(--ink);
  font-family: var(--text);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

::selection { background: rgba(217, 178, 106, .3); color: #fff; }

a { color: inherit; }

/* ==========================================================================
   1. LOADER GATE  (warroom lesson: never reveal cold media)
   The gate is the `data-loading` attribute on <html>. foyer.js drops it only
   after the hero has decoded, so a half-painted room is never shown and the
   room can never appear frozen on a cold cache.
   ========================================================================== */

.foyer__loader {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  background: radial-gradient(80% 60% at 50% 45%, #0c0e14, var(--void) 70%);
  transition: opacity .7s var(--ease), visibility .7s var(--ease);
}
.loader__clover { display: block; width: 58px; height: 58px; }
.loader__clover svg { width: 100%; height: 100%; display: block; }
.loader__label {
  font-family: var(--display);
  font-size: .64rem;
  letter-spacing: .34em;
  text-indent: .34em;
  text-transform: uppercase;
  color: #7d8798;
}
html[data-loading] .loader__clover { animation: clover-breathe 1.9s ease-in-out infinite; }
@keyframes clover-breathe {
  0%, 100% { opacity: .45; transform: scale(.9) rotate(-3deg); }
  50%      { opacity: 1;   transform: scale(1)  rotate(3deg); }
}
html:not([data-loading]) .foyer__loader {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.foyer { opacity: 0; transition: opacity 1s var(--ease); }
html:not([data-loading]) .foyer { opacity: 1; }

/* ==========================================================================
   2. THE STAGE
   ========================================================================== */

.foyer {
  position: relative;
  container-type: inline-size;
}

.room {
  position: relative;
  isolation: isolate;      /* light layers blend over the photograph only */
  overflow: hidden;
}

.room picture { display: block; height: 100%; }

.room__plate {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;     /* the whole composition, always. Nothing beheaded. */
  object-position: center;
  transition: filter 1.1s var(--ease), transform 1.4s var(--ease);
}
html[data-loading] .room__plate {
  filter: blur(18px) brightness(.5);
  transform: scale(1.03);
}

/* ==========================================================================
   3. AMBIENCE — light shafts and dust. CSS only.
   ========================================================================== */

.amb { position: absolute; inset: 0; pointer-events: none; }

.shaft { position: absolute; mix-blend-mode: screen; }

.shaft--gallery {
  left: 26%; top: 21%; width: 46%; height: 76%;
  background: radial-gradient(58% 54% at 79% 5%,
      rgba(255, 201, 124, .30), rgba(255, 188, 106, .10) 44%, transparent 72%);
  filter: blur(26px);
  animation: shaft-breathe 13s ease-in-out infinite;
}
.shaft--pendant {
  left: 40%; top: 21%; width: 22%; height: 46%;
  background: radial-gradient(46% 60% at 50% 3%,
      rgba(255, 216, 152, .26), transparent 68%);
  filter: blur(18px);
  animation: shaft-breathe 9.5s ease-in-out infinite reverse;
}
@keyframes shaft-breathe {
  0%, 100% { opacity: .78; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.035); }
}

/* Dust turns over inside the warm half of the room. `.motes` is the box the
   individual --x/--y coordinates are measured in, so re-insetting that box for
   portrait moves the whole swarm into the light without touching the motes. */
.motes { position: absolute; inset: 14% 16% 2% 24%; }
.motes i {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--s);
  height: var(--s);
  border-radius: 50%;
  background: rgb(255, 232, 194);
  box-shadow: 0 0 7px 2px rgba(255, 206, 146, .6);
  opacity: var(--o);
  mix-blend-mode: screen;
  animation: mote-rise var(--t) linear var(--d) infinite;
  transform: scale(1.35);          /* motes read at 1-3px: keep them just visible */
}
@keyframes mote-rise {
  0%   { transform: translate3d(0, 0, 0)            scale(1.05); opacity: 0; }
  14%  {                                                         opacity: var(--o); }
  50%  { transform: translate3d(2.2cqw, -20cqw, 0)  scale(1.5); }
  86%  {                                                         opacity: var(--o); }
  100% { transform: translate3d(-1.4cqw, -40cqw, 0) scale(1);    opacity: 0; }
}

/* ==========================================================================
   4. SIGNAGE — type only. Placement belongs to whichever layout owns it.
   Kept well clear of the render's chrome clover so the locked brand lockup is
   never restaged as a broken one.
   ========================================================================== */

.signage {
  position: absolute;
  z-index: 3;
  display: flex;
  flex-direction: column;
  font-weight: 400;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .92));
}
.signage__name {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: .30em;
  text-indent: .30em;               /* optical: cancels the trailing track */
  text-transform: uppercase;
  background: var(--chrome);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.signage__rule {
  width: 100%;
  height: 1px;
  background: linear-gradient(90deg, transparent,
      rgba(217, 178, 106, .75) 76%, rgba(255, 243, 210, .95));
}
.signage__sub {
  font-family: var(--display);
  letter-spacing: .46em;
  text-indent: .46em;
  text-transform: uppercase;
  color: rgba(219, 226, 238, .85);
}

/* ==========================================================================
   5. THE DOORS — shared shell, type and state hooks.
   ========================================================================== */

.doors { position: absolute; inset: 0; z-index: 4; pointer-events: none; }

.door {
  position: absolute;
  display: block;
  text-decoration: none;
  color: inherit;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
}
.door:focus-visible {
  outline: 2px solid var(--gold-hi);
  outline-offset: 4px;
  border-radius: 2px;
}

/* --- bloom that spills past the doorway --------------------------------- */
.door__bloom {
  position: absolute;
  inset: -18% -34%;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: screen;
  transition: opacity .55s var(--ease);
}
.door--office .door__bloom {
  background: radial-gradient(44% 40% at 54% 56%,
      rgba(255, 226, 176, .34), rgba(255, 205, 130, .10) 46%, transparent 74%);
  filter: blur(16px);
}
.door--gallery .door__bloom {
  background: radial-gradient(46% 42% at 50% 52%,
      rgba(255, 206, 130, .44), rgba(255, 176, 88, .14) 44%, transparent 76%);
  filter: blur(18px);
}
.door:hover .door__bloom,
.door:focus-visible .door__bloom,
.door:active .door__bloom { opacity: 1; }

/* --- warm seam at the office threshold ---------------------------------- */
.door__seam {
  position: absolute;
  border-radius: 99px;
  background: linear-gradient(90deg, transparent,
      rgba(255, 214, 140, .9) 24%, rgba(255, 234, 186, 1) 52%,
      rgba(255, 214, 140, .9) 76%, transparent);
  opacity: .5;
  transition: opacity .5s var(--ease), box-shadow .5s var(--ease);
}

/* --- brass gleam travelling across the lever --------------------------- */
.door__handle { position: absolute; pointer-events: none; }
.door__gleam {
  position: absolute;
  inset: 0;
  mix-blend-mode: screen;
  background: linear-gradient(104deg,
      transparent 38%, rgba(255, 244, 214, .95) 50%, transparent 62%);
  background-size: 320% 100%;
  background-repeat: no-repeat;
  background-position: -60% 0;
  opacity: 0;
}
.door--office:hover .door__gleam,
.door--office:focus-visible .door__gleam,
.door--office:active .door__gleam { animation: brass-gleam 1.15s var(--ease) forwards; }
@keyframes brass-gleam {
  0%   { opacity: 0; background-position: -60% 0; }
  22%  { opacity: 1; }
  100% { opacity: 0; background-position: 160% 0; }
}

/* --- door lettering: real type, gilded --------------------------------- */
.door__plate {
  display: flex;
  flex-direction: column;
  transition: transform .45s var(--ease), filter .45s var(--ease);
}
.door__title,
.door__sub {
  font-family: var(--display);
  text-transform: uppercase;
  background: var(--gild);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  white-space: nowrap;
}
.door__title { font-weight: 600; }
.door__sub {
  display: flex;
  flex-direction: column;
  line-height: 1.5;
}
.door__hair {
  height: 1px;
  background: linear-gradient(90deg, transparent,
      rgba(217, 178, 106, .85) 28%, rgba(255, 243, 210, .95) 50%,
      rgba(217, 178, 106, .85) 72%, transparent);
}
.door__cue { display: none; }

/* ==========================================================================
   6. KEYLINE — type only.
   ========================================================================== */

.keyline {
  z-index: 5;
  letter-spacing: .015em;
  color: rgba(178, 187, 201, .8);
  text-shadow: 0 1px 10px rgba(0, 0, 0, .95), 0 0 26px rgba(0, 0, 0, .8);
}
.keyline a {
  color: var(--gold-mid);
  text-decoration: none;
  border-bottom: 1px solid rgba(217, 178, 106, .35);
  padding-bottom: 1px;
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
.keyline a:hover,
.keyline a:focus-visible { color: var(--gold-hi); border-color: rgba(255, 243, 210, .8); }

/* ==========================================================================
   7. CINEMATIC LAYOUT  (>= 740px)
   Owns every stage coordinate and every cqw size.
   ========================================================================== */

@media (min-width: 740px) {
  body { overflow: hidden; }

  .foyer {
    position: fixed;
    inset: 0;
    margin: auto;
    width: min(100vw, calc(100svh * var(--ar)));
    height: min(100svh, calc(100vw / var(--ar)));
  }
  .room { position: absolute; inset: 0; }

  /* a faint matte so the letterbox bands read as intentional framing */
  .room::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    box-shadow:
      inset 0 0 0 1px rgba(255, 240, 210, .07),
      inset 0 0 90px 30px rgba(0, 0, 0, .5);
  }

  /* --- hit areas, mapped onto the architecture -------------------------- */
  .door--office  { left: 12.2%; top: 9%;  width: 17.2%; height: 79%; }
  .door--gallery { left: 56.8%; top: 18%; width: 14%;   height: 57%; }

  /* --- the lit state: the real door in the photograph comes on.
         Full-stage layers (so the plate is never rescaled or offset) clipped
         to each doorway's own outline in stage coordinates. --------------- */
  .lift {
    position: absolute;
    inset: 0;
    display: block;
    background-image: url("/assets/lobby.jpg");
    background-size: 100% 100%;   /* stage aspect == plate aspect: no distortion */
    opacity: 0;
    transition: opacity .5s var(--ease);
    will-change: opacity;
  }
  .lift--office {
    clip-path: polygon(13.4% 9.9%, 28.7% 22.9%, 28.7% 77.9%, 13.4% 86%);
    filter: brightness(1.3) saturate(1.05) contrast(1.02);
  }
  .lift--gallery {
    clip-path: polygon(58.6% 30.2%, 68.3% 29.7%, 68.5% 74.1%, 58.5% 73.3%);
    filter: brightness(1.28) saturate(1.12);
  }
  .foyer:has(.door--office:hover)          .lift--office,
  .foyer:has(.door--office:focus-visible)  .lift--office,
  .foyer:has(.door--office:active)         .lift--office,
  .foyer:has(.door--gallery:hover)         .lift--gallery,
  .foyer:has(.door--gallery:focus-visible) .lift--gallery,
  .foyer:has(.door--gallery:active)        .lift--gallery { opacity: 1; }

  /* --- threshold seam, raked to the sill ------------------------------- */
  .door__seam {
    left: 7%; right: 4.1%;
    top: 92.4%;
    height: .6%;
    box-shadow: 0 0 1.1cqw .2cqw rgba(255, 190, 104, .45);
    transform: skewY(var(--rake-sill));
  }
  .door--office:hover .door__seam,
  .door--office:focus-visible .door__seam,
  .door--office:active .door__seam {
    opacity: 1;
    box-shadow: 0 0 2.1cqw .45cqw rgba(255, 190, 104, .65);
  }

  /* --- gleam sits over the lever the render already carries ------------- */
  .door__handle {
    left: 27.3%; top: 58.2%;
    width: 40.7%; height: 10.9%;
    overflow: hidden;
    border-radius: 99px;
  }

  /* --- lettering laid onto the door planes ----------------------------- */
  .door__plate {
    position: absolute;
    align-items: center;
    text-align: center;
    gap: .42cqw;
  }
  .door__hair { width: 58%; }

  /* office: sheared onto the raking plane (verticals stay vertical) and
     dimmed toward the far edge so the sign's far end sits back in space. The
     gild runs deeper here because it is read against LIT frosted glass. */
  .door--office .door__plate {
    left: 8.1%; width: 69%; top: 30.4%;
    transform: skewY(var(--rake));
    -webkit-mask-image: linear-gradient(96deg, #000 0%, #000 56%, rgba(0, 0, 0, .86) 100%);
    mask-image: linear-gradient(96deg, #000 0%, #000 56%, rgba(0, 0, 0, .86) 100%);
    filter: drop-shadow(0 .09cqw .07cqw rgba(28, 20, 8, .9))
            drop-shadow(0 0 .5cqw rgba(60, 42, 16, .5));
  }
  .door--office .door__title,
  .door--office .door__sub {
    background: var(--gild-glass);
    -webkit-background-clip: text;
    background-clip: text;
  }
  .door--office .door__title { font-size: 1.06cqw; letter-spacing: .32em; text-indent: .32em; }
  .door--office .door__sub   { font-size: .68cqw;  letter-spacing: .16em; text-indent: .16em; }

  /* gallery: gilded on the dark lintel above the opening */
  .door--gallery .door__plate {
    left: 0; width: 100%; top: 2%;
    filter: drop-shadow(0 .1cqw .09cqw rgba(0, 0, 0, .7))
            drop-shadow(0 0 .8cqw rgba(255, 196, 120, .18));
  }
  .door--gallery .door__title { font-size: 1cqw;   letter-spacing: .32em; text-indent: .32em; }
  .door--gallery .door__sub   { font-size: .56cqw; letter-spacing: .22em; text-indent: .22em; opacity: .92; }
  .door--gallery .door__frames { display: none; }

  /* the office lamp coming on behind the glass drives the gilt DARKER, which
     is what happens to gold leaf when the panel behind it lights up */
  .door--office:hover .door__plate,
  .door--office:focus-visible .door__plate {
    transform: skewY(var(--rake)) scale(1.03);
    filter: drop-shadow(0 .09cqw .07cqw rgba(20, 13, 4, .98))
            drop-shadow(0 0 .7cqw rgba(44, 29, 8, .65));
  }
  .door--office:active .door__plate { transform: skewY(var(--rake)) scale(.996); }

  .door--gallery:hover .door__plate,
  .door--gallery:focus-visible .door__plate {
    transform: translateY(-.3cqw) scale(1.035);
    filter: drop-shadow(0 .1cqw .09cqw rgba(0, 0, 0, .7))
            drop-shadow(0 0 1.4cqw rgba(255, 208, 136, .55));
  }
  .door--gallery:active .door__plate { transform: translateY(0) scale(.99); }

  /* --- signage + keyline ---------------------------------------------- */
  .signage {
    right: 3.4%;
    top: 2.1%;
    align-items: flex-end;
    text-align: right;
    gap: .3cqw;
  }
  .signage__name { font-size: 1.5cqw; }
  .signage__sub  { font-size: .7cqw; }

  .keyline {
    position: absolute;
    left: 3.6%;
    bottom: 2.4%;
    max-width: 40%;
    font-size: .78cqw;
  }
}

/* ==========================================================================
   8. STACKED LAYOUT  (< 740px, portrait phones)
   The portrait crop shows the composition whole; the doors become plates a
   thumb can actually hit. Same DOM, same anchors, same testids.
   ========================================================================== */

@media (max-width: 739px) {
  .foyer {
    display: flex;
    flex-direction: column;
    min-height: 100svh;
    padding-bottom: max(20px, env(safe-area-inset-bottom));
  }

  /* --- the room, whole --- */
  .room {
    position: relative;
    width: 100%;
    aspect-ratio: var(--ar-portrait);
    flex: 0 0 auto;
  }
  .room::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(180deg,
        rgba(6, 7, 10, .62) 0%, rgba(6, 7, 10, .12) 20%,
        transparent 58%, rgba(6, 7, 10, .96) 100%);
  }
  .motes { inset: 10% 0 8% 48%; }
  .shaft--gallery { display: none; }
  .shaft--pendant { left: 66%; top: 16%; width: 34%; height: 34%; }

  /* --- signage over the dark head of the crop --- */
  .signage {
    top: 6%;
    left: 50%;
    transform: translateX(-50%);
    align-items: center;
    text-align: center;
    gap: 5px;
  }
  .signage__name { font-size: clamp(1rem, 5.2vw, 1.45rem); letter-spacing: .32em; text-indent: .32em; }
  .signage__rule { width: 72%; margin: 0 auto;
    background: linear-gradient(90deg, transparent, rgba(217, 178, 106, .85) 50%, transparent); }
  .signage__sub  { font-size: clamp(.5rem, 2.3vw, .66rem); letter-spacing: .42em; text-indent: .42em; }

  /* --- doors as plates --- */
  .doors {
    position: static;
    display: flex;
    flex-direction: column;
    gap: 11px;
    padding: 0 14px;
    margin-top: -26px;              /* the plates tuck into the room's shadow */
    pointer-events: auto;
    z-index: 6;
  }

  .door {
    position: relative;
    left: auto; top: auto; width: 100%;
    min-height: 118px;
    display: block;
    padding: 16px 18px 18px 20px;
    border-radius: 5px 5px 2px 2px;
    overflow: hidden;
    isolation: isolate;
    transition: transform .3s var(--ease), box-shadow .3s var(--ease);
  }

  /* ---- office plate: a closed frosted door with the lamp on behind it ---- */
  .door--office {
    background:
      radial-gradient(42% 74% at 72% 56%,
        rgba(255, 229, 180, .34), rgba(255, 216, 154, .08) 46%, transparent 74%),
      linear-gradient(100deg,
        rgba(198, 197, 191, .20) 0%, rgba(226, 224, 216, .32) 26%,
        rgba(206, 205, 199, .24) 44%, rgba(230, 227, 218, .30) 64%,
        rgba(174, 176, 174, .17) 100%),
      linear-gradient(165deg, #1a1c22, #08090d 76%);
    border: 1px solid rgba(255, 255, 255, .13);
    box-shadow:
      0 18px 40px rgba(0, 0, 0, .62),
      inset 0 1px 0 rgba(255, 255, 255, .16),
      inset 0 -16px 26px rgba(0, 0, 0, .45);
  }
  /* joinery: left stile, centre mullion, bottom rail */
  .door--office::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
      linear-gradient(90deg, rgba(8, 9, 13, .92) 0 7px, transparent 7px),
      linear-gradient(90deg, transparent 0 calc(58% - 3px),
        rgba(8, 9, 13, .88) calc(58% - 3px) calc(58% + 3px), transparent calc(58% + 3px)),
      linear-gradient(0deg, rgba(8, 9, 13, .82) 0 6px, transparent 6px);
  }
  .door--office .door__lume {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(26% 58% at 68% 60%,
        rgba(255, 234, 190, .32), transparent 72%);
    filter: blur(9px);
    mix-blend-mode: screen;
  }
  .door--office .door__seam {
    left: 8px; right: 6%;
    bottom: 2px;
    height: 2px;
    box-shadow: 0 0 14px 3px rgba(255, 190, 104, .5);
    opacity: .62;
  }
  /* a real brass lever, drawn onto the mullion where the render carries it */
  .door--office .door__handle {
    left: calc(58% + 5px);
    top: 50%;
    width: 11px; height: 44px;
    transform: translateY(-50%);
    border-radius: 3px;
    background: linear-gradient(100deg, #6b551f 0%, #d9b26a 24%, #fff4cf 47%, #c99f52 63%, #75591f 100%);
    box-shadow: 0 0 12px rgba(217, 178, 106, .45), inset 0 0 3px rgba(255, 255, 255, .55);
  }
  .door--office .door__handle::after {
    content: "";
    position: absolute;
    left: -16px; top: 44%;
    width: 27px; height: 6px;
    border-radius: 3px;
    background: linear-gradient(180deg, #fff2c9 0%, #cfa55c 46%, #7a5f22 100%);
    box-shadow: 0 2px 6px rgba(0, 0, 0, .55);
  }
  .door--office .door__gleam { inset: -3px; border-radius: 5px; }

  /* ---- gallery plate: dark walnut standing ajar on warm light ---- */
  .door--gallery {
    background:
      radial-gradient(30% 106% at 90% 50%, rgba(255, 196, 118, .17), transparent 62%),
      linear-gradient(100deg, #0e0a06 0%, #191106 44%, #241906 76%, #100b06 100%);
    border: 1px solid rgba(255, 205, 140, .16);
    box-shadow: 0 18px 40px rgba(0, 0, 0, .62), inset 0 1px 0 rgba(255, 224, 170, .12);
  }
  .door--gallery .door__lume {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
      linear-gradient(90deg, transparent 0 84.4%,
        rgba(255, 243, 214, .92) 85.4%, rgba(255, 208, 140, .18) 86.8%, transparent 92%),
      radial-gradient(18% 100% at 87% 50%, rgba(255, 206, 138, .22), transparent 74%);
    filter: blur(1px);
    mix-blend-mode: screen;
  }
  /* framed prints down the corridor, each catching its picture light */
  .door--gallery .door__frames {
    display: block;
    position: absolute;
    left: 52%; right: 22%;
    top: 26%; bottom: 25%;
    pointer-events: none;
  }
  .door--gallery .door__frames i {
    position: absolute;
    top: 0; bottom: 0;
    width: 18%;
    border-radius: 1px;
    background:
      linear-gradient(180deg, rgba(255, 240, 212, .62) 0 2px, transparent 2px),
      linear-gradient(180deg, rgba(255, 233, 198, .20), rgba(0, 0, 0, .42) 62%);
    box-shadow: 0 -6px 13px -5px rgba(255, 222, 168, .85),
                inset 0 0 0 1px rgba(255, 232, 190, .22);
  }
  .door--gallery .door__frames i:nth-child(1) { left: 2%;  opacity: .6; }
  .door--gallery .door__frames i:nth-child(2) { left: 36%; opacity: .8; }
  .door--gallery .door__frames i:nth-child(3) { left: 70%; opacity: 1; }

  /* ---- plate lettering: unsheared, ranged left, clear of the joinery ---- */
  .door__plate {
    position: relative;
    align-items: flex-start;
    text-align: left;
    gap: 6px;
    max-width: 48%;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .85));
  }
  .door__title { font-size: clamp(.86rem, 4.6vw, 1.1rem);  letter-spacing: .2em;  text-indent: .2em; }
  .door__sub   { font-size: clamp(.52rem, 2.6vw, .68rem);  letter-spacing: .13em; text-indent: .13em;
                 align-items: flex-start; line-height: 1.6; }
  .door__hair  { width: 40px; }

  .door__cue {
    display: block;
    position: absolute;
    right: 16px; bottom: 10px;
    font-family: var(--text);
    font-size: .56rem;
    letter-spacing: .17em;
    text-transform: uppercase;
    color: rgba(28, 24, 16, .62);
    text-shadow: 0 1px 0 rgba(255, 250, 236, .28);
  }
  .door--gallery .door__cue { color: rgba(255, 236, 206, .62); text-shadow: 0 1px 5px rgba(0, 0, 0, .85); }

  .door__bloom { inset: -30% -20%; }

  .door:active { transform: scale(.985); box-shadow: 0 8px 20px rgba(0, 0, 0, .6); }

  .keyline {
    max-width: 34ch;
    margin: 22px auto 0;
    font-size: .68rem;
    text-align: center;
    color: rgba(170, 179, 194, .78);
  }
}

/* ==========================================================================
   9. SHORT LANDSCAPE — the whole room still fits, the type stays readable.
   ========================================================================== */

@media (min-width: 740px) and (max-height: 430px) {
  .keyline { font-size: 1.05cqw; }
  .signage__name { font-size: 1.9cqw; }
  .signage__sub  { font-size: .9cqw; }
  .door--office .door__title  { font-size: 1.25cqw; }
  .door--office .door__sub    { font-size: .72cqw; }
  .door--gallery .door__title { font-size: 1.2cqw; }
  .door--gallery .door__sub   { font-size: .68cqw; }
}

/* ==========================================================================
   10. REDUCED MOTION — the room holds still, the light stays.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .motes { display: none; }
  .shaft { animation: none; }
  html[data-loading] .room__plate { filter: none; transform: none; }
}

/* Touch devices get the tap state, not a hover state that sticks. */
@media (hover: none) {
  .door:hover .door__bloom { opacity: 0; }
  .door:active .door__bloom { opacity: 1; }
}
