/* Spud & Root: town/study.html (the club's library). Loaded after site.css.
   study.js sets data-state on .study (outside -> talking -> opening ->
   inside, with focus while you've stepped up to something) and adds is-*
   classes as things happen. The room itself is drawn by study-room.js. */

/* ---------- The club's kit ----------
   Everything laid over the room is one family, as if the club had it made:
   brass plates, oxblood leather, green baize and cream card stock, kept in
   the house style (ink outlines, the offset shadow), with the club's own
   words engraved in small capitals. Other Study files use these too:

     --club-ink         engraving black: text and outlines on the kit
     --club-card        cream card stock; --club-gilt, the gilt rule on it
     --club-brass       brass; --club-brass-light its highlight (and gilt
                        lettering on leather or baize), --club-brass-dark
                        its shadow
     --club-leather     oxblood leather; --club-baize, green baize
     --club-wax         red sealing wax
     --club-serif       Cinzel, for the club's words: titles, labels,
                        buttons. Its small letters are small capitals, so
                        type ordinary case ("Leave the club") and it comes
                        out engraved. Not for running text
     --club-text        Georgia, for running text on card stock

     and to make a brass or card piece of your own: --club-brass-face (the
     brass, a gradient) with --club-brushed over it (its grain),
     --club-screws (two screw heads, as background images) and --club-rule
     (the double gilt rule, as inset box-shadows)

     .club-card        card stock with a double gilt rule: a panel, a
                        notice, an end card. Pad it 16 px or more inside
     .brass-btn         a brass plate button, engraved, never under 44 px;
                        .brass-btn--leather is the quiet one (Done, Back);
                        aria-pressed="true" shows it pressed in
     .plate             an engraved brass plate with two screws, for a label
                        (a name, a score); not a button
     .seal              a red wax seal holding a mark or a number (set
                        --seal for its size, --tilt to turn it);
                        .seal--blind is its impression in the card, not inked

   Speech stays in the site's bubbles: the members talk like the rest of
   the gang. */

@font-face {
  font-family: "Cinzel";
  src: url("../fonts/cinzel.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}

:root {
  --club-ink: #24170d;
  --club-card: #f4ead2;
  --club-gilt: #b48c38;
  --club-brass: #d2aa52;
  --club-brass-light: #f3dc93;
  --club-brass-dark: #7a5719;
  --club-leather: #5c1a16;
  --club-baize: #1f4a33;
  --club-wax: #a8261b;
  --club-serif: "Cinzel", Georgia, "Times New Roman", serif;
  --club-text: Georgia, "Times New Roman", serif;

  /* polished brass, lit from above, with a brushed grain */
  --club-brass-face: linear-gradient(175deg, #f5df9b 0%, #dcb862 34%, #c69b45 66%, #d8b561 100%);
  --club-brass-pressed: linear-gradient(175deg, #c39848 0%, #cfa653 45%, #bc9143 100%);
  --club-brushed: repeating-linear-gradient(90deg, rgba(255, 250, 230, 0.08) 0 1px, rgba(255, 250, 230, 0) 1px 3px);
  /* two screw heads, at the ends of a plate */
  --club-screws:
    radial-gradient(circle at 11px 50%, #4a320d 0 1.4px, #f7e6a8 1.9px 2.6px, #8a6322 3px 3.7px, rgba(138, 99, 34, 0) 4.2px),
    radial-gradient(circle at calc(100% - 11px) 50%, #4a320d 0 1.4px, #f7e6a8 1.9px 2.6px, #8a6322 3px 3.7px, rgba(138, 99, 34, 0) 4.2px);
  /* a double gilt rule just inside the edge of card stock (thick, then thin) */
  --club-rule: inset 0 0 0 5px var(--club-card), inset 0 0 0 7px var(--club-gilt), inset 0 0 0 9px var(--club-card), inset 0 0 0 10px var(--club-gilt);
}

.club-card,
.panel {
  color: var(--club-ink);
  background-color: var(--club-card);
  border: var(--stroke) solid var(--club-ink);
  border-radius: 6px;
  box-shadow: var(--club-rule), var(--shadow);
}

/* (.study .panel: the front door's section styles .panel__done and
   .panel .btn too, further down; this outranks it) */
.brass-btn,
.leave,
.study .panel .btn,
.up-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: 44px;
  min-height: 44px;
  padding: 6px 18px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.1;
  letter-spacing: 0.05em;
  text-align: center;
  text-decoration: none;
  color: #3a2508;
  text-shadow: 0 1px 0 rgba(255, 246, 214, 0.6);
  background-color: var(--club-brass);
  background-image: var(--club-brushed), var(--club-brass-face);
  border: var(--stroke) solid var(--club-ink);
  border-radius: 5px;
  box-shadow: inset 0 1px 0 rgba(255, 250, 225, 0.85), inset 0 -2px 0 rgba(95, 62, 12, 0.3), 3px 3px 0 var(--club-ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transform: none;
  transition: translate 0.12s ease, box-shadow 0.12s ease, filter 0.15s ease;
}
@media (hover: hover) {
  .brass-btn:hover,
  .leave:hover,
  .study .panel .btn:hover,
  .study .panel__done:hover,
  .up-btn:hover,
  .back-btn:hover,
  .card-btn:hover,
  .sound:hover {
    transform: none;
    filter: brightness(1.08);
  }
}
.brass-btn:active,
.leave:active,
.study .panel .btn:active,
.study .panel__done:active,
.up-btn:active,
.back-btn:active,
.card-btn:active,
.sound:active {
  transform: none;
  translate: 2px 2px;
  box-shadow: inset 0 1px 0 rgba(255, 250, 225, 0.6), 1px 1px 0 var(--club-ink);
}
.brass-btn[aria-pressed="true"],
.study .panel .btn[aria-pressed="true"] {
  background-image: var(--club-brushed), var(--club-brass-pressed);
  box-shadow: inset 0 2px 4px rgba(60, 35, 5, 0.5), 1px 1px 0 var(--club-ink);
  translate: 2px 2px;
}
.brass-btn:disabled,
.study .panel .btn:disabled {
  opacity: 0.45;
  cursor: default;
  translate: none;
  box-shadow: none;
  filter: saturate(0.5);
}
.brass-btn--leather,
.study .panel__done,
.back-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 6px 18px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.1;
  letter-spacing: 0.05em;
  color: #ecd08a;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
  background-color: var(--club-leather);
  background-image: linear-gradient(175deg, #74251e 0%, #5a1914 55%, #4a130f 100%);
  border: var(--stroke) solid var(--club-ink);
  border-radius: 5px;
  /* a gilt line tooled just inside the edge */
  box-shadow: inset 0 0 0 2px var(--club-leather), inset 0 0 0 3px rgba(226, 190, 110, 0.6), 3px 3px 0 var(--club-ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: translate 0.12s ease, box-shadow 0.12s ease, filter 0.15s ease;
}
.brass-btn--leather:active,
.study .panel__done:active,
.back-btn:active {
  box-shadow: inset 0 0 0 2px var(--club-leather), inset 0 0 0 3px rgba(226, 190, 110, 0.6), 1px 1px 0 var(--club-ink);
}

.plate {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 30px;
  padding: 4px 24px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 0.875rem;
  line-height: 1.1;
  letter-spacing: 0.1em;
  color: #3a2508;
  text-shadow: 0 1px 0 rgba(255, 246, 214, 0.6);
  background-color: var(--club-brass);
  background-image: var(--club-screws), var(--club-brushed), var(--club-brass-face);
  border: 2px solid var(--club-ink);
  border-radius: 3px;
  box-shadow: inset 0 0 0 1px rgba(255, 244, 205, 0.55), 2px 2px 0 var(--club-ink);
}

/* Wax: a red disc a little out of round, with the stamp's rim pressed in
   and the wax squeezed out beyond it */
.seal,
.card-btn::before,
.stamp-toast__seal,
.card__stamps .is-got .card__seal {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: var(--seal, 34px);
  height: var(--seal, 34px);
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: calc(var(--seal, 34px) * 0.46);
  line-height: 1;
  color: #fbe1cd;
  text-shadow: 0 -1px 0 rgba(70, 0, 0, 0.6), 0 1px 0 rgba(255, 180, 160, 0.3);
  background: radial-gradient(circle at 35% 30%, #da4b3d 0, var(--club-wax) 52%, #78120d 100%);
  border: 0;
  border-radius: 47% 53% 45% 55% / 54% 46% 54% 46%;
  box-shadow:
    inset 0 0 0 calc(var(--seal, 34px) * 0.1) rgba(255, 150, 130, 0.12),
    inset 0 0 0 calc(var(--seal, 34px) * 0.13) rgba(80, 0, 0, 0.4),
    0 0 0 calc(var(--seal, 34px) * 0.07) #9b2117,
    1px 2px 0 calc(var(--seal, 34px) * 0.07) rgba(30, 8, 4, 0.4);
  rotate: var(--tilt, -8deg);
}
.seal--blind,
.card__stamps li:not(.is-got) .card__seal {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: var(--seal, 34px);
  height: var(--seal, 34px);
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: calc(var(--seal, 34px) * 0.46);
  line-height: 1;
  color: #cdb88a;
  text-shadow: 1px 1px 0 rgba(255, 252, 240, 0.85), -1px -1px 0 rgba(110, 80, 30, 0.25);
  background: transparent;
  border: 0;
  border-radius: 50%;
  /* pressed into the card, not inked: lit from the top left */
  box-shadow:
    inset 2px 2px 3px rgba(110, 80, 30, 0.42),
    inset -1px -1px 1px rgba(255, 253, 244, 0.9),
    0 0 0 1px rgba(150, 118, 60, 0.18);
  rotate: none;
}

.study-page {
  overflow: hidden;
  background: #1a1009;
  overscroll-behavior: none;
}

.study {
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 360px;
  overflow: hidden;
  font-family: var(--font-body);
  -webkit-user-select: none;
  user-select: none;
  /* no "Open image in new tab" or "Save image" on a long press, anywhere
     on the page (study.js cancels the menu too) */
  -webkit-touch-callout: none;
}
.study img,
.study svg,
.study canvas {
  -webkit-user-drag: none;
}

/* ---------- Outside: the front door ---------- */
.front {
  position: absolute;
  inset: 0;
  background: #0b0a0d;
  overflow: hidden;
  transition: opacity 0.9s ease;
  container-type: size;
}
/* The art fits its viewBox (the part a phone held upright must show) into the
   screen, bottom and middle, and shows more street round it on a wider one: so
   one of its units is --u on the screen, and its point (x, y) is at
   left: 50% + (x - 500) * --u, top: 100% - (1180 - y) * --u. The door and
   the hall behind it are placed that way. */
.front__scene {
  position: absolute;
  inset: 0;
  --u: min(100vw / 700, 100vh / 1510);
  transform-origin: 50% calc(100% - 580 * var(--u));
  transition: transform 1.05s cubic-bezier(0.55, 0, 0.85, 0.4) 0.4s;
}
@supports (width: 1cqw) {
  .front__scene {
    --u: min(100cqw / 700, 100cqh / 1510);
  }
}
/* A phone on its side is short: the door bigger, and the street cut off above */
@media (orientation: landscape) and (max-height: 520px) {
  .front__scene {
    inset: auto 0 -12% 0;
    height: 175%;
    --u: min(100vw / 700, 175vh / 1510);
  }
  @supports (width: 1cqw) {
    .front__scene {
      --u: min(100cqw / 700, 175cqh / 1510);
    }
  }
}
.front__art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.front__hall,
.front__leaf {
  position: absolute;
  left: calc(50% - 160 * var(--u));
  top: calc(100% - 880 * var(--u));
  width: calc(320 * var(--u));
  height: calc(600 * var(--u));
  pointer-events: none;
}
/* The door opens into the hall, on its hinges at the left */
.front__leaf {
  transform-origin: 0 50%;
  transition: transform 0.85s cubic-bezier(0.4, 0, 0.25, 1), filter 0.85s ease;
}
/* The hall's light down the steps, once the door's open */
.front__spill {
  position: absolute;
  left: calc(50% - 400 * var(--u));
  top: calc(100% - 284 * var(--u));
  width: calc(800 * var(--u));
  height: calc(284 * var(--u));
  clip-path: polygon(30% 0, 70% 0, 88% 50.7%, 100% 100%, 0 100%, 12% 50.7%);
  background: linear-gradient(rgba(255, 224, 160, 0.8), rgba(255, 196, 110, 0.38) 50%, rgba(255, 180, 90, 0));
  mix-blend-mode: screen;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.6s ease 0.15s;
}
/* Rain over everything, and brighter where it falls through a lantern's light */
.front__rain,
.front__lit-rain::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -220px;
  bottom: 0;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='220'%3E%3Cg stroke='%23b4c2e0' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='M12 8l-5 26M58 40l-5 26M104 14l-5 26M132 70l-5 26M30 92l-5 26M80 120l-5 26M120 150l-5 26M18 168l-5 26M64 190l-5 26M100 96l-5 26' opacity='.5'/%3E%3Cpath d='M40 0l-4 20M88 60l-4 20M8 120l-4 20M126 118l-4 20M50 150l-4 20M110 196l-4 20' opacity='.3'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 140px 220px;
  pointer-events: none;
  animation: front-rain 0.42s linear infinite;
}
.front__lit-rain {
  position: absolute;
  top: calc(100% - 1046 * var(--u));
  width: calc(460 * var(--u));
  height: calc(460 * var(--u));
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: radial-gradient(closest-side, #000 25%, transparent);
  mask-image: radial-gradient(closest-side, #000 25%, transparent);
}
.front__lit-rain::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='220'%3E%3Cg stroke='%23ffe2a6' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M12 8l-5 26M58 40l-5 26M104 14l-5 26M132 70l-5 26M30 92l-5 26M80 120l-5 26M120 150l-5 26M18 168l-5 26M64 190l-5 26M100 96l-5 26M40 0l-4 20M88 60l-4 20M8 120l-4 20M126 118l-4 20M50 150l-4 20M110 196l-4 20'/%3E%3C/g%3E%3C/svg%3E");
}
.front__lit-rain--l {
  left: calc(50% - 494 * var(--u));
}
.front__lit-rain--r {
  left: calc(50% + 34 * var(--u));
}
@keyframes front-rain {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(0, 220px, 0); }
}
/* Raindrops landing in the puddle */
.front__ripple {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: front-ripple 2.2s ease-out infinite;
}
.front__ripple--late {
  animation-delay: -1.1s;
}
@keyframes front-ripple {
  from { transform: scale(0.2); opacity: 0.9; }
  to { transform: scale(1.6); opacity: 0; }
}
.front__plate {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  letter-spacing: 0.08em;
}
.front__mat-note {
  font-family: var(--font-script);
  font-size: 15px;
  letter-spacing: 0.04em;
}
.front__mat {
  transform-box: fill-box;
  transform-origin: 0 100%;
  transition: transform 0.5s var(--ease-spring);
}
.is-mat-up .front__mat {
  transform: rotate(-16deg) translateY(-4px);
}
.front__hatch {
  transition: transform 0.25s ease-in;
}
.is-hatch-open .front__hatch {
  transform: translateX(-96px);
  transition-timing-function: ease-out;
}
.front__salt {
  transform-box: fill-box;
}
.is-glaring .front__salt {
  animation: salt-glare 2.4s ease-in-out infinite;
}
@keyframes salt-glare {
  0%, 40%, 100% { transform: translateX(0); }
  50%, 70% { transform: translateX(-8px); }
  80%, 90% { transform: translateX(8px); }
}
.front__ring {
  transform-box: fill-box;
  transform-origin: 50% 0;
}
.is-knocking .front__ring {
  animation: knock 0.42s ease-in-out 3;
}
/* The ring swings out from its pivot in the lion's mouth and falls back:
   seen face on, that's the ring foreshortened from the top, then a bounce
   as it strikes. Flat, as 3D transforms on SVG come out skewed in Safari */
@keyframes knock {
  0%, 100% { transform: scaleY(1); }
  40% { transform: scaleY(0.45); }
  72% { transform: scaleY(1); }
  84% { transform: scaleY(0.88); }
}
/* Smoke curling up behind the blinds */
.front__puff {
  stroke-dasharray: 90 200;
  animation: front-puff 3.4s ease-in-out infinite;
}
@keyframes front-puff {
  from { stroke-dashoffset: 90; opacity: 0; }
  30% { opacity: 0.7; }
  to { stroke-dashoffset: -200; opacity: 0; }
}
.front__glass {
  animation: lamp 3.2s ease-in-out infinite;
}
.front__glass--gas {
  animation-duration: 4.3s;
  animation-delay: -1.7s;
}
@keyframes lamp {
  0%, 100% { fill: #ffd77a; }
  47% { fill: #ffd77a; }
  50% { fill: #f5c25c; }
  53% { fill: #ffd77a; }
}

/* The invisible buttons over the knocker and the mat (placed by study.js) */
.front__hit {
  position: absolute;
  left: 0;
  top: 0;
  width: 60px;
  height: 60px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: transparent;
  font-size: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.front__hit--mat {
  border-radius: 8px;
}
html:not(.js) .front__hit {
  display: none;
}

.front__talk {
  position: absolute;
  left: 50%;
  top: 30%;
  width: min(340px, calc(100% - 32px));
  translate: -50% 0;
  padding: 14px 16px 16px;
  background: var(--white);
  border: var(--stroke) solid var(--ink);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  text-align: center;
}
.front__talk::before {
  content: "";
  position: absolute;
  left: calc(50% - 11px);
  top: -14px;
  width: 22px;
  height: 22px;
  background: var(--white);
  border-left: var(--stroke) solid var(--ink);
  border-top: var(--stroke) solid var(--ink);
  rotate: 45deg;
}
.front__talk[hidden] {
  display: none;
}
.front__says {
  position: relative;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.25rem;
  line-height: 1.2;
  min-height: 1.2em;
}
.front__form {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}
.front__form[hidden] {
  display: none;
}
.front__form input {
  flex: 1;
  min-width: 0;
  padding: 0.45em 0.7em;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: var(--cream);
  border: var(--stroke) solid var(--ink);
  border-radius: var(--radius-sm);
  -webkit-user-select: text;
  user-select: text;
}
.front__form button,
.panel__done,
.panel .btn {
  padding: 0.4em 1em;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  color: var(--ink);
  background: var(--logo-yellow);
  border: var(--stroke) solid var(--ink);
  border-radius: var(--radius-pill);
  box-shadow: 3px 3px 0 var(--ink);
  cursor: pointer;
}
.front__form button:active,
.panel__done:active,
.panel .btn:active {
  translate: 2px 2px;
  box-shadow: 1px 1px 0 var(--ink);
}

.front__hint {
  position: absolute;
  left: 50%;
  bottom: max(18px, env(safe-area-inset-bottom));
  translate: -50% 0;
  padding: 0.35em 1em;
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--ink);
  background: var(--white);
  border: var(--stroke) solid var(--ink);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-sm);
  white-space: nowrap;
  pointer-events: none;
  transition: opacity 0.4s ease;
}
html:not(.js) .front__hint,
.study:not([data-state="outside"]) .front__hint {
  opacity: 0;
}

/* Through the door: it swings open, the hall's light spills down the steps,
   and in you go */
[data-state="opening"] .front__leaf,
[data-state="inside"] .front__leaf,
[data-state="focus"] .front__leaf {
  transform: perspective(calc(1100 * var(--u))) rotateY(-78deg);
  filter: brightness(0.4);
}
[data-state="opening"] .front__spill,
[data-state="inside"] .front__spill,
[data-state="focus"] .front__spill {
  opacity: 1;
}
[data-state="opening"] .front__scene,
[data-state="inside"] .front__scene,
[data-state="focus"] .front__scene {
  transform: scale(3.6);
}
[data-state="opening"] .front,
[data-state="inside"] .front,
[data-state="focus"] .front {
  opacity: 0;
  pointer-events: none;
}
[data-state="inside"] .front,
[data-state="focus"] .front {
  visibility: hidden;
}
/* When you've come in by the door (Salt has spoken: not with ?inside), the
   street stays over the room while the door opens, then the two cross-fade */
.study:has(.front__says:not(:empty))[data-state="opening"] .front {
  opacity: 1;
}
.study:has(.front__says:not(:empty))[data-state="opening"] .stage {
  opacity: 0;
}
.study:has(.front__says:not(:empty)) .stage {
  transition: opacity 0.55s ease 0.1s;
}
.study:has(.front__says:not(:empty))[data-state="inside"] .front {
  transition: opacity 0.55s ease-in 0.1s, visibility 0s linear 0.65s;
}
@media (prefers-reduced-motion: reduce) {
  .front__rain,
  .front__lit-rain::before,
  .front__glass,
  .front__ripple {
    animation: none;
  }
  .front__scene,
  .front__leaf,
  .front__spill,
  .study:has(.front__says:not(:empty)) .stage {
    transition: none;
  }
}

/* ---------- Inside ---------- */
.stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #1a1009;
  touch-action: none;
}
.stage[hidden] {
  display: none;
}
.room {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: block;
  cursor: grab;
  /* study.js slides it about with a transform (applyCamera()) */
  transform-origin: 0 0;
  will-change: transform;
}
.is-dragging .room {
  cursor: grabbing;
}
/* The flat picture of the room, under the SVG (study.js, "The flat
   picture"). While it's up, the still parts of the SVG are hidden but
   still catch taps */
.room-flat {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: 0 0;
  will-change: transform;
  pointer-events: none;
}
.room-flat[hidden] {
  display: none;
}
.room.is-flat [data-flat] {
  visibility: hidden;
  pointer-events: painted;
}
/* ?perf */
.perf {
  position: fixed;
  left: 6px;
  top: calc(env(safe-area-inset-top, 0px) + 6px);
  z-index: 99;
  padding: 4px 6px;
  font: 11px/1.35 ui-monospace, Menlo, monospace;
  white-space: pre;
  color: #fff;
  background: rgba(0, 0, 0, 0.7);
  border-radius: 4px;
  pointer-events: none;
}
/* The firelight over the hearth: a layer of its own, so its flicker never
   has the room drawn again. study.js keeps it over the fireplace (it's the
   glow's size in the room's units, scaled to the screen) */
.fire-light {
  position: absolute;
  left: 0;
  top: 0;
  width: 1400px;
  height: 840px;
  transform-origin: 0 0;
  pointer-events: none;
  background: radial-gradient(closest-side, rgba(255, 138, 42, 0.6), rgba(255, 138, 42, 0.21) 45%, rgba(255, 138, 42, 0));
  opacity: 0.78;
  mix-blend-mode: screen;
  will-change: transform, opacity;
  animation: fire-light 1.7s ease-in-out infinite;
}
.fire-light.is-up {
  background: radial-gradient(closest-side, rgba(255, 150, 60, 0.85), rgba(255, 138, 42, 0.32) 45%, rgba(255, 138, 42, 0));
}
.is-cellar .fire-light {
  display: none;
}
@keyframes fire-light {
  0%, 100% { opacity: 0.76; }
  14% { opacity: 0.86; }
  27% { opacity: 0.7; }
  41% { opacity: 0.83; }
  55% { opacity: 0.68; }
  68% { opacity: 0.88; }
  83% { opacity: 0.72; }
}
/* Things in the foreground, nearer than the room; never in the way */
.fg {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: block;
  transform-origin: 0 0;
  will-change: transform;
  pointer-events: none;
  filter: brightness(0.55) saturate(0.85);
  transition: opacity 0.5s ease;
}
[data-state="focus"] .fg {
  opacity: 0;
}
.room__shade {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 75% 85% at 50% 55%, transparent 55%, rgba(12, 6, 2, 0.55) 100%);
}

/* Anything you can tap glows a little under the pointer or keyboard */
.room .hot {
  cursor: pointer;
  outline: none;
}
.room .hot:focus-visible {
  filter: drop-shadow(0 0 3px #ffe08a) drop-shadow(0 0 8px rgba(255, 196, 80, 0.7));
}
/* Only where there's a pointer that hovers: a phone keeps the last thing
   tapped "hovered", and a filter on something that moves (the fire, a
   member breathing) is costly to draw again every frame */
@media (hover: hover) {
  .room .hot:hover {
    filter: drop-shadow(0 0 3px #ffe08a) drop-shadow(0 0 8px rgba(255, 196, 80, 0.7));
  }
  .room .hot--quiet:hover {
    filter: brightness(1.12);
  }
  .is-dragging .room .hot:hover {
    filter: none;
  }
}

/* Books: any of them can be taken down. The one you're reading sticks out */
.room .book {
  cursor: pointer;
  transition: translate 0.25s ease;
}
@media (hover: hover) {
  .room .book:hover {
    filter: brightness(1.25);
  }
}
.room .book:focus-visible {
  outline: none;
  filter: brightness(1.3) drop-shadow(0 0 4px #ffe08a);
}
.room .book.is-out {
  translate: 0 -10px;
  filter: drop-shadow(0 0 6px #ffe08a);
}

/* The members breathe, each at his own pace */
.room .member__bob {
  animation: bob var(--bob, 3.6s) ease-in-out infinite;
  animation-delay: var(--bob-delay, 0s);
  transform-box: fill-box;
  transform-origin: 50% 100%;
}
@keyframes bob {
  0%, 100% { transform: scale(1, 1); }
  50% { transform: scale(1.012, 0.985); }
}
.room .member.is-talking .member__bob {
  animation: talk 0.36s ease-in-out infinite;
}
@keyframes talk {
  0%, 100% { transform: scale(1, 1) rotate(0); }
  50% { transform: scale(1.02, 0.97) rotate(-1deg); }
}
.room .member.is-hopping .member__bob {
  animation: hop 0.5s ease-in-out infinite;
}
@keyframes hop {
  0%, 100% { transform: translateY(0) scale(1, 1); }
  15% { transform: translateY(0) scale(1.06, 0.92); }
  50% { transform: translateY(-14%) scale(0.96, 1.05); }
  85% { transform: translateY(0) scale(1.04, 0.95); }
}
.room .member.is-swaying .member__bob {
  animation: sway 1.4s ease-in-out infinite;
}
@keyframes sway {
  0%, 100% { transform: rotate(-4deg); }
  50% { transform: rotate(4deg); }
}
.room .member.is-shaking .member__bob {
  animation: shake 0.12s linear 6;
}
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-2%); }
  75% { transform: translateX(2%); }
}
.room .member.is-sobbing .member__bob {
  animation: sob 0.5s ease-in-out infinite;
}
@keyframes sob {
  0%, 100% { transform: scale(1, 1); }
  30% { transform: scale(1.02, 0.96) translateY(1%); }
}

/* Cigar embers glow as they're puffed */
.room .ember {
  animation: ember 3s ease-in-out infinite;
  animation-delay: var(--ember-delay, 0s);
}
@keyframes ember {
  0%, 100% { fill: #e2401b; }
  45% { fill: #ff7a2a; }
  55% { fill: #ffc04a; }
}

/* The fire */
.room .flame {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: flame var(--fl, 0.9s) ease-in-out infinite alternate;
  animation-delay: var(--fd, 0s);
}
@keyframes flame {
  0% { transform: scale(1, 1) skewX(0); }
  33% { transform: scale(0.94, 1.1) skewX(-4deg); }
  66% { transform: scale(1.05, 0.92) skewX(3deg); }
  100% { transform: scale(0.97, 1.06) skewX(-2deg); }
}
.room .fire.is-roaring .flames {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: roar 2.4s ease-out;
}
@keyframes roar {
  0% { transform: scale(1); }
  12% { transform: scale(1.35, 1.6); }
  100% { transform: scale(1); }
}

/* Lids that open: the humidor's from its back edge, the globe's from its
   right-hand end */
.room .humidor__open {
  display: none;
}
.room .humidor.is-open .humidor__open {
  display: inline;
}
.room .humidor.is-open .humidor__lid {
  display: none;
}
.room .globe__lid {
  transform-box: fill-box;
  transform-origin: 100% 100%;
}

/* The fire burns down: study.js sets the flames' size; a log goes on */
.room .flames-size {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  transition: transform 1.2s ease;
}
.room .new-log {
  opacity: 0;
  transform: translateY(-60px);
}
.room .new-log.is-on {
  opacity: 1;
  transform: none;
  transition: transform 0.45s cubic-bezier(0.5, 0, 0.8, 1.4), opacity 0.2s;
}

/* The pendulum and the chandeliers */
.room .pendulum {
  transform-box: fill-box;
  transform-origin: 50% 0;
  animation: pendulum 1s ease-in-out infinite alternate;
}
@keyframes pendulum {
  from { transform: rotate(-7deg); }
  to { transform: rotate(7deg); }
}

/* Rain on the window, and the lightning */
.room .rain {
  animation: room-rain 0.6s linear infinite;
}
@keyframes room-rain {
  from { transform: translate(0, -80px); }
  to { transform: translate(-14px, 0); }
}
.room .lightning {
  opacity: 0;
}
.is-lightning .room .lightning {
  animation: flash 0.9s ease-out;
}
@keyframes flash {
  0% { opacity: 0; }
  5% { opacity: 1; }
  15% { opacity: 0.2; }
  22% { opacity: 0.9; }
  100% { opacity: 0; }
}
.is-lightning .room__shade {
  animation: room-flash 0.9s ease-out;
}
@keyframes room-flash {
  0% { background-color: transparent; }
  6% { background-color: rgba(200, 220, 255, 0.28); }
  20% { background-color: transparent; }
  24% { background-color: rgba(200, 220, 255, 0.18); }
  100% { background-color: transparent; }
}

/* The gramophone's record goes round while it plays */
.room .gramo__disc {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  transform: scaleY(0.28);
}
.is-playing .room .gramo__disc {
  animation: disc 1.8s linear infinite;
}
@keyframes disc {
  from { transform: scaleY(0.28) rotate(0); }
  to { transform: scaleY(0.28) rotate(360deg); }
}

/* Music notes and tears float up and away */
.room .note {
  animation: note 2.6s ease-out forwards;
}
@keyframes note {
  from { opacity: 0; transform: translate(0, 0); }
  15% { opacity: 1; }
  to { opacity: 0; transform: translate(var(--nx, 20px), -90px); }
}
.room .tear {
  animation: tear 1.1s ease-in forwards;
}
@keyframes tear {
  from { opacity: 1; transform: translate(0, 0); }
  to { opacity: 0; transform: translate(var(--tx, 0), 40px); }
}

/* ---------- Speech bubbles ---------- */
.bubbles {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.bubble {
  position: absolute;
  left: 0;
  top: 0;
  width: max-content;
  max-width: min(240px, 60vw);
  padding: 0.45em 0.8em;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(0.9rem, 2.2vh, 1.1rem);
  line-height: 1.2;
  color: var(--ink);
  background: var(--white);
  border: var(--stroke) solid var(--ink);
  border-radius: 16px;
  box-shadow: 3px 3px 0 var(--ink);
  translate: -50% -100%;
  animation: bubble-in 0.25s var(--ease-spring);
  text-align: center;
}
.bubble::after {
  content: "";
  position: absolute;
  left: calc(50% - 8px);
  bottom: -11px;
  width: 14px;
  height: 14px;
  background: var(--white);
  border-right: var(--stroke) solid var(--ink);
  border-bottom: var(--stroke) solid var(--ink);
  rotate: 45deg;
}
.bubble--shout {
  font-size: clamp(1.1rem, 3vh, 1.5rem);
  background: var(--club-brass-light);
}
.bubble--shout::after {
  background: var(--club-brass-light);
}
.bubble.is-gone {
  opacity: 0;
  transition: opacity 0.3s ease;
}
@keyframes bubble-in {
  from { scale: 0.6; opacity: 0; }
  to { scale: 1; opacity: 1; }
}

/* ---------- Walking about: the strip of places along the bottom ----------
   A leather strap with the places tooled on it in gilt, like the spines on
   the shelves; where you are is set in a brass plate. Where it's too long
   for the screen it fades out at both ends, with the next places showing,
   and slides under a finger (study.js keeps the place you're at in the
   middle) */
.study-nav {
  position: absolute;
  left: 50%;
  bottom: max(12px, env(safe-area-inset-bottom));
  translate: -50% 0;
  display: flex;
  gap: 4px;
  max-width: calc(100% - 24px);
  padding: 4px;
  overflow-x: auto;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
  background-color: var(--club-leather);
  background-image: linear-gradient(180deg, #6e231c 0%, #561712 60%, #47120e 100%);
  border: var(--stroke) solid var(--club-ink);
  border-radius: 8px;
  box-shadow: inset 0 0 0 2px #5c1a16, inset 0 0 0 3px rgba(226, 190, 110, 0.5), var(--shadow-sm);
  transition: opacity 0.4s ease, translate 0.4s ease;
}
.study-nav::-webkit-scrollbar {
  display: none;
}
.study-nav[hidden] {
  display: none;
}
.study-nav button {
  flex: none;
  min-width: 44px;
  min-height: 44px;
  padding: 4px 11px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 0.8125rem;
  line-height: 1;
  letter-spacing: 0.05em;
  color: #e9cc80;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.55);
  background: transparent;
  /* each place in its own tooled panel */
  border: 1px solid rgba(226, 190, 110, 0.28);
  border-radius: 4px;
  cursor: pointer;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) {
  .study-nav button:hover {
    color: #fbe6ad;
    border-color: rgba(240, 210, 140, 0.7);
  }
}
.study-nav button[aria-current="true"] {
  color: #3a2508;
  text-shadow: 0 1px 0 rgba(255, 246, 214, 0.6);
  background-color: var(--club-brass);
  background-image: var(--club-screws), var(--club-brushed), var(--club-brass-face);
  border: 2px solid var(--club-ink);
  padding-inline: 21px;
  box-shadow: inset 0 0 0 1px rgba(255, 244, 205, 0.5);
}
/* Too long for the screen: the strap runs the width of it and the places
   fade into the leather at both ends, as they slide under a finger. (Two
   patches of leather that stay put at the ends, so the strap keeps its
   shadow; each takes up a little room, so the first and last places can be
   slid clear of it) */
@media (max-width: 1080px) {
  .study-nav {
    width: calc(100% - 24px);
  }
  .study-nav::before,
  .study-nav::after {
    content: "";
    position: sticky;
    z-index: 1;
    flex: none;
    width: 30px;
    pointer-events: none;
    background-image: linear-gradient(180deg, #6a211a 0%, #541712 60%, #4a130f 100%);
  }
  .study-nav::before {
    left: 0;
    margin-right: -10px;
    -webkit-mask-image: linear-gradient(90deg, #000 25%, transparent);
    mask-image: linear-gradient(90deg, #000 25%, transparent);
  }
  .study-nav::after {
    right: 0;
    margin-left: -10px;
    -webkit-mask-image: linear-gradient(270deg, #000 25%, transparent);
    mask-image: linear-gradient(270deg, #000 25%, transparent);
  }
}
[data-state="focus"] .study-nav {
  opacity: 0;
  translate: -50% 120%;
  pointer-events: none;
}

/* ---------- The panel for whatever you've stepped up to ---------- */
.panel {
  position: absolute;
  right: max(12px, env(safe-area-inset-right));
  bottom: max(12px, env(safe-area-inset-bottom));
  width: min(380px, calc(100% - 24px));
  max-height: calc(100% - 90px);
  display: flex;
  flex-direction: column;
  /* card stock: .club-card, at the top */
  animation: panel-in 0.35s var(--ease-out);
}
.panel[hidden] {
  display: none;
}
@keyframes panel-in {
  from { opacity: 0; translate: 0 30px; }
  to { opacity: 1; translate: 0 0; }
}
.panel__inner {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  /* clear of the gilt rule */
  padding: 16px 18px 18px;
}
/* The title engraved in small capitals, over a gilt rule with a dot in it */
.panel__title {
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1.15;
  letter-spacing: 0.04em;
  color: var(--club-leather);
  text-align: center;
}
.panel__title::after {
  content: "";
  display: block;
  width: min(70%, 220px);
  height: 7px;
  margin: 7px auto 0;
  background:
    radial-gradient(circle, var(--club-gilt) 0 2.5px, rgba(180, 140, 56, 0) 3px) center / 7px 7px no-repeat,
    linear-gradient(var(--club-gilt), var(--club-gilt)) center / 100% 1px no-repeat;
}
.panel__body {
  min-height: 0;
  overflow-y: auto;
  font-family: var(--club-text);
  font-size: 1.0625rem;
  line-height: 1.45;
}
.panel__body p + p {
  margin-top: 0.5em;
}
.panel__done {
  align-self: flex-end;
}
.panel .btns {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 6px;
}
.panel .small {
  font-size: 1rem;
  font-style: italic;
  color: #5d4a33;
}
.panel .book-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.15rem;
  font-style: italic;
}
@media (max-width: 600px) {
  .panel {
    left: 12px;
    right: 12px;
    width: auto;
    max-height: 46%;
  }
  .panel--tall {
    max-height: 66%;
  }
  .panel__body {
    font-size: 1rem;
  }
}

/* ---------- Way out, sound and your card: one row along the top ----------
   The row is 44 px tall from 10 px down, so with its shadow it ends at 57 px
   and study.js keeps speech bubbles below 60 px: none slides under it.
   Leave is a brass door plate (on a phone just "Leave"; on the street,
   before you're in, "Back to town"); Sound a brass roundel with a horn;
   your card a little green card with the club's seal on it */
.leave,
.sound,
.card-btn {
  position: absolute;
  top: max(10px, env(safe-area-inset-top));
  white-space: nowrap;
}
.leave {
  left: max(12px, env(safe-area-inset-left));
  padding: 6px 26px;
  font-size: 0.9375rem;
  background-image: var(--club-screws), var(--club-brushed), var(--club-brass-face);
}
.leave__street,
[data-state="outside"] .leave__club,
[data-state="talking"] .leave__club {
  display: none;
}
[data-state="outside"] .leave__street,
[data-state="talking"] .leave__street {
  display: inline;
}
@media (max-width: 600px) {
  .leave {
    padding-inline: 22px;
  }
  /* "Leave" to the eye, "Leave the club" to a screen reader */
  .leave__more {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}
.sound {
  right: max(12px, env(safe-area-inset-right));
  display: block;
  width: 44px;
  height: 44px;
  padding: 0;
  /* the words stay, for a screen reader; the horn says it to the eye */
  text-indent: 200%;
  overflow: hidden;
  border: var(--stroke) solid var(--club-ink);
  border-radius: 50%;
  background-color: var(--club-brass);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%233a2508' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 10.3h2.4c3.4 0 6.2-1.9 8.6-5.1v13.6c-2.4-3.2-5.2-5.1-8.6-5.1H3.5z' fill='%233a2508' fill-opacity='.22'/%3E%3Cpath d='M17.6 9.4a3.9 3.9 0 0 1 0 5.2M19.9 7.2a7.1 7.1 0 0 1 0 9.6'/%3E%3C/svg%3E"),
    var(--club-brushed),
    radial-gradient(circle at 38% 30%, #f6e2a0 0%, #d8b25c 45%, #b98d3a 78%, #d3ae5c 100%);
  background-repeat: no-repeat, repeat, no-repeat;
  background-position: 54% 50%, 0 0, 0 0;
  background-size: 26px 26px, auto, auto;
  box-shadow: inset 0 1px 0 rgba(255, 250, 225, 0.8), inset 0 -2px 0 rgba(95, 62, 12, 0.3), 3px 3px 0 var(--club-ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: translate 0.12s ease, box-shadow 0.12s ease, filter 0.15s ease;
}
.sound[hidden] {
  display: none;
}
/* Off: the horn with a cross where the sound was, the brass gone dull */
.sound[aria-pressed="false"] {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%233a2508' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 10.3h2.4c3.4 0 6.2-1.9 8.6-5.1v13.6c-2.4-3.2-5.2-5.1-8.6-5.1H3.5z' fill='%233a2508' fill-opacity='.22'/%3E%3Cpath d='M17.5 9.6l4.5 4.8M22 9.6l-4.5 4.8'/%3E%3C/svg%3E"),
    var(--club-brushed),
    radial-gradient(circle at 38% 30%, #d9c58e 0%, #b3955a 50%, #8f7543 100%);
}

.study__noscript {
  position: absolute;
  left: 50%;
  top: max(64px, 8%);
  translate: -50% 0;
  width: max-content;
  max-width: calc(100% - 32px);
  padding: 0.5em 1em;
  color: var(--ink);
  background: var(--white);
  border: var(--stroke) solid var(--ink);
  border-radius: var(--radius-md);
  text-align: center;
}
html.js .study__noscript {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .front__rain,
  .front__puff,
  .front__lamp path,
  .room .rain,
  .room .member__bob,
  .room .flame,
  .room .pendulum,
  .room .gramo__disc,
  .room .candle-glow,
  .room .ember,
  .fire-light {
    animation: none !important;
  }
  .front__art {
    transition: none;
  }
}

/* ---------- Your own cigar, once you've lit one ---------- */
.your-cigar {
  position: absolute;
  right: max(14px, env(safe-area-inset-right));
  bottom: max(88px, calc(env(safe-area-inset-bottom) + 82px));
  width: 150px;
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
  rotate: -18deg;
  filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, 0.35));
  transition: opacity 0.3s ease;
}
.your-cigar[hidden],
[data-state="focus"] .your-cigar {
  display: none;
}
.your-cigar svg {
  display: block;
  width: 100%;
  height: auto;
}
.your-cigar__ember {
  animation: ember 3s ease-in-out infinite;
}
.your-cigar.is-puffing {
  animation: puff-cigar 0.7s ease;
}
.your-cigar.is-puffing .your-cigar__ember {
  animation: none;
  fill: #ffc04a;
}
@keyframes puff-cigar {
  40% { translate: -24px -14px; scale: 1.08; }
}

/* ---------- The members' book ---------- */
.signed {
  margin: 0 0 12px;
  padding-left: 1.4em;
  font-family: Georgia, "Times New Roman", serif;
}
.signed li + li {
  margin-top: 2px;
}
.sign label {
  display: block;
  margin-bottom: 6px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.04em;
  color: var(--club-leather);
}
.sign__row {
  display: flex;
  gap: 10px;
}
/* 16 px at the least: any smaller and an iPhone zooms in on it */
.sign input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 0.35em 0.7em;
  font-family: var(--club-text);
  font-size: max(16px, 1.0625rem);
  font-style: italic;
  color: var(--club-ink);
  background: #fffbf0;
  border: 2px solid var(--club-ink);
  border-radius: 3px;
  box-shadow: inset 2px 2px 0 rgba(110, 80, 30, 0.15);
  -webkit-user-select: text;
  user-select: text;
}
.sign input::placeholder {
  color: #76624a;
}
.panel ol {
  margin: 0;
  padding-left: 1.4em;
}
.study .panel a.btn {
  line-height: 1.2;
}

/* ---------- The window, open ---------- */
.room .window__gap {
  display: none;
}
.is-window-open .room .window__gap {
  display: inline;
}
.room .curtain {
  transform-box: fill-box;
  transform-origin: 50% 0;
}
.is-window-open .room .curtain--left {
  animation: billow 2.6s ease-in-out infinite;
}
.is-window-open .room .curtain--right {
  animation: billow 2.9s ease-in-out infinite reverse;
}
@keyframes billow {
  0%, 100% { transform: skewX(0) scaleX(1); }
  50% { transform: skewX(-3deg) scaleX(1.06); }
}

/* ---------- The secret door ---------- */
.room .secret-door {
  transform-box: fill-box;
  transform-origin: 0 50%;
  transition: transform 1.6s cubic-bezier(0.5, 0, 0.3, 1);
}
.is-secret-open .room .secret-door {
  transform: scaleX(0.16) skewY(-12deg);
  pointer-events: none;
}
.room .lever {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  transition: transform 0.3s ease;
}
.room .lever.is-pulled {
  transform: rotate(-16deg);
}
.room .vault {
  visibility: hidden;
  transition: visibility 0s 1.6s;
}
.is-secret-open .room .vault {
  visibility: visible;
  transition: none;
}
.room .safe__door {
  transform-box: fill-box;
  transform-origin: 0 50%;
  transition: transform 1s cubic-bezier(0.5, 0, 0.3, 1);
}
.room .safe.is-open .safe__door {
  transform: scaleX(0.12) skewY(10deg);
}
.room .safe__dial {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  transition: transform 0.08s linear;
}

/* Glows and light never catch a tap meant for what's under them */
.room .candle-glow,
.room .lamp-glow,
.room .fire-floor,
.room .fire-back,
.room .lightning {
  pointer-events: none;
}

/* ---------- The dumbwaiter ---------- */
.room .dumbwaiter__car {
  transform: translateY(110px);
  transition: transform 1.8s cubic-bezier(0.5, 0, 0.3, 1);
}
.room .dumbwaiter__door {
  transition: transform 0.6s ease;
}
.room .dumbwaiter.is-up .dumbwaiter__car {
  transform: none;
}
.room .dumbwaiter.is-up .dumbwaiter__door {
  transform: translateY(-104px);
  transition-delay: 1.6s;
}
.room .supper {
  visibility: hidden;
}
.room .dumbwaiter.is-uncovered .supper {
  visibility: visible;
}
.room .dumbwaiter.is-uncovered .cloche {
  visibility: hidden;
}

/* ---------- The membership card ---------- */
.card-btn {
  right: calc(max(12px, env(safe-area-inset-right)) + 54px);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 4px 14px 4px 40px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 0.8125rem;
  line-height: 1.1;
  letter-spacing: 0.06em;
  color: #efd68e;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
  background-color: var(--club-baize);
  background-image: linear-gradient(175deg, #2b5e42 0%, #1d452f 60%, #173a27 100%);
  border: var(--stroke) solid var(--club-ink);
  border-radius: 5px;
  /* a gilt rule round the card */
  box-shadow: inset 0 0 0 3px var(--club-baize), inset 0 0 0 4px rgba(226, 194, 122, 0.8), 3px 3px 0 var(--club-ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: translate 0.12s ease, box-shadow 0.12s ease, filter 0.15s ease;
}
/* the club's seal, pressed on the card's end (study.js may put the count
   in a seal of its own: <span class="seal">3</span>; then this one goes) */
.card-btn::before {
  --seal: 25px;
  content: "\2605";
  position: absolute;
  left: 7px;
  top: 50%;
  margin-top: -12.5px;
  --tilt: -10deg;
}
.card-btn:has(.seal)::before {
  content: none;
}
.card-btn .seal {
  --seal: 26px;
  margin: 0 -2px 0 8px;
}
.card-btn:has(.seal) {
  padding-left: 14px;
}
/* The smallest phones: the seal comes off so the row still fits */
@media (max-width: 359px) {
  .leave {
    padding-inline: 18px;
  }
  .card-btn {
    padding: 4px 9px;
    font-size: 0.75rem;
    letter-spacing: 0.02em;
  }
  .card-btn::before {
    content: none;
  }
}

/* The card itself: cream card stock under a band of green leather with the
   club's crest tooled on it in gilt. A stamp not yet earned is the seal's
   impression in the card, a question mark pressed into it; earned, it's
   inked in red wax */
.card {
  position: relative;
  padding: 0 14px 18px;
  overflow: hidden;
  color: var(--club-ink);
  background: var(--club-card);
  border: var(--stroke) solid var(--club-ink);
  border-radius: 8px;
  box-shadow: 3px 3px 0 rgba(36, 23, 13, 0.35);
  font-family: var(--club-text);
  text-align: center;
}
/* the double gilt rule, over the band and the card alike */
.card::after {
  content: "";
  position: absolute;
  inset: 5px;
  border: 3px double var(--club-gilt);
  border-radius: 4px;
  pointer-events: none;
}
.card .card__club,
.card .card__kind {
  margin: 0 -14px;
  padding: 0 14px;
  background-color: var(--club-baize);
}
.card .card__club {
  padding-top: 70px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1.1;
  letter-spacing: 0.18em;
  color: #efd68e;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
  /* the crest: a shield with a chevron between three potatoes */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 44 52' fill='none' stroke='%23e2c27a' stroke-width='1.6' stroke-linejoin='round'%3E%3Cpath d='M6 5h32v16c0 13-8 21-16 26C14 42 6 34 6 21z'/%3E%3Cpath d='M9 8h26v13c0 11-6.6 17.6-13 22-6.4-4.4-13-11-13-22z' stroke-width='.8' opacity='.7'/%3E%3Cpath d='M9.5 31.5 22 19.5l12.5 12M9.5 25.5 22 13.5l12.5 12' stroke-width='1.3'/%3E%3Cg fill='%23e2c27a' stroke='none'%3E%3Cellipse cx='14.5' cy='13' rx='3.4' ry='2.5' transform='rotate(-20 14.5 13)'/%3E%3Cellipse cx='29.5' cy='13' rx='3.4' ry='2.5' transform='rotate(20 29.5 13)'/%3E%3Cellipse cx='22' cy='35.5' rx='3.6' ry='2.6'/%3E%3C/g%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 50% 18px;
  background-size: 40px 47px;
}
.card .card__kind {
  padding-bottom: 16px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.16em;
  color: #cdb877;
  /* the band ends in a gilt line */
  box-shadow: 0 2px 0 var(--club-gilt);
}
.card--life .card__club,
.card--life .card__kind {
  background-color: var(--club-leather);
}
/* signed on the line */
.card .card__name {
  display: inline-block;
  min-width: min(80%, 260px);
  margin-top: 20px;
  padding: 0 10px 3px;
  font-style: italic;
  font-size: 1.25rem;
  line-height: 1.25;
  border-bottom: 1px solid rgba(36, 23, 13, 0.55);
}
/* the member's number, under the signature (for study.js to add:
   <p class="card__no">Member No. 11</p> after .card__name) */
.card .card__no {
  margin-top: 8px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.12em;
  color: var(--club-leather);
}
.card__stamps {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 14px 6px;
  margin: 20px 0 0;
  padding: 0;
  list-style: none;
}
.card__stamps li {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  font-size: 1rem;
  line-height: 1.15;
  color: var(--club-ink);
  --seal: 40px;
}
/* the "?" of a stamp not yet earned, pressed into its impression */
.card__stamps li:not(.is-got) > span:last-child {
  position: absolute;
  top: 0;
  left: 50%;
  width: 40px;
  height: 40px;
  margin-left: -20px;
  display: grid;
  place-items: center;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1.125rem;
  color: #c9b385;
  text-shadow: 1px 1px 0 rgba(255, 252, 240, 0.85), -1px -1px 0 rgba(110, 80, 30, 0.22);
}
.card ~ .small {
  margin-top: 12px;
}

/* A stamp earned: a slip of card with the seal pressed on it, dropped in
   below the row of buttons */
.stamp-toast {
  position: absolute;
  z-index: 3;
  left: 50%;
  top: calc(max(10px, env(safe-area-inset-top)) + 58px);
  display: flex;
  align-items: center;
  gap: 14px;
  width: max-content;
  max-width: calc(100% - 24px);
  padding: 12px 20px 12px 16px;
  color: var(--club-ink);
  background-color: var(--club-card);
  border: var(--stroke) solid var(--club-ink);
  border-radius: 6px;
  box-shadow: inset 0 0 0 4px var(--club-card), inset 0 0 0 5px var(--club-gilt), var(--shadow-sm);
  font-family: var(--club-text);
  font-size: 1rem;
  line-height: 1.25;
  translate: -50% -30px;
  opacity: 0;
  pointer-events: none;
  transition: translate 0.4s var(--ease-spring), opacity 0.3s ease;
}
.stamp-toast.is-in {
  translate: -50% 0;
  opacity: 1;
}
/* Wider than a phone, a panel stands down the right-hand side: the slip
   drops in over the room to its left, clear of the panel's title */
@media (min-width: 601px) {
  [data-state="focus"] .stamp-toast {
    left: calc((100% - 392px) / 2);
    max-width: calc(100% - 416px);
  }
}
.stamp-toast strong {
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.04em;
  color: var(--club-leather);
}
.stamp-toast__seal {
  --seal: 38px;
}
.stamp-toast.is-in .stamp-toast__seal {
  animation: seal-press 0.5s cubic-bezier(0.3, 0, 0.4, 1) 0.15s backwards;
}
@keyframes seal-press {
  from { scale: 1.7; opacity: 0; }
  60% { scale: 0.92; opacity: 1; }
  to { scale: 1; }
}
.stamp-toast .small {
  font-size: 0.875rem;
  font-style: italic;
  color: #5d4a33;
}

/* ---------- Twenty-one ---------- */
.hands {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  background: #1f5c3a;
  border: var(--stroke) solid var(--ink);
  border-radius: var(--radius-md);
  color: #f6e3b4;
}
.hand__who {
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: 0.06em;
  color: var(--club-brass-light);
}
.hand__cards {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 62px;
}
.pcard {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 42px;
  height: 60px;
  padding: 3px 4px;
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: 1rem;
  line-height: 1;
  color: var(--ink);
  background: #fbf8ef;
  border: 2px solid var(--ink);
  border-radius: 6px;
  animation: deal 0.3s var(--ease-out);
}
.pcard--red {
  color: #b0281c;
}
.pcard span:last-child {
  align-self: flex-end;
  font-size: 1.3rem;
}
.pcard--back {
  background: repeating-linear-gradient(45deg, #7a1f1a 0 5px, #9a2f22 5px 10px);
}
.pcard--back span {
  visibility: hidden;
}
@keyframes deal {
  from { translate: 40px -20px; opacity: 0; rotate: 10deg; }
}
.twentyone-say {
  min-height: 1.4em;
  font-family: var(--font-display);
  font-weight: 600;
  text-align: center;
}
/* Kept short enough to fit the panel on a phone without scrolling: the two
   hands side by side, the cards fanned, and only the buttons that can be
   pressed now (Deal again, or Hit me and Stand), in one row */
.twentyone {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.twentyone .hands {
  flex-direction: row;
  gap: 10px;
  padding: 8px 10px;
}
.twentyone .hands > div {
  flex: 1 1 0;
  min-width: 0;
}
.twentyone .hand__cards {
  flex-wrap: nowrap;
  gap: 0;
  min-height: 60px;
}
.twentyone .pcard {
  flex: none;
}
.twentyone .pcard + .pcard {
  margin-left: -16px;
  box-shadow: -2px 0 3px rgba(0, 0, 0, 0.25);
}
.twentyone .btns {
  flex-wrap: nowrap;
  margin-top: 0;
}
.twentyone .btn {
  flex: 1 1 0;
  justify-content: center;
}
.twentyone .btn:disabled {
  display: none;
}
.study .panel .twentyone p + p {
  margin-top: 0;
}
.twentyone > .small:first-child {
  font-size: 0.9375rem;
  line-height: 1.35;
}
.twentyone .hand__who {
  font-size: 0.9375rem;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
/* a short phone screen: the tall panels (twenty-one) go up to the row of
   buttons along the top */
@media (max-width: 600px) and (max-height: 620px) {
  .panel--tall {
    max-height: calc(100% - 66px);
  }
}

/* ---------- The club photograph ---------- */
.room .club-photo {
  visibility: hidden;
}
.has-photo .room .club-photo {
  visibility: visible;
}
.flash {
  position: absolute;
  inset: 0;
  z-index: 6;
  background: #fffbea;
  pointer-events: none;
  animation: flashbulb 1.4s ease-out forwards;
}
@keyframes flashbulb {
  0% { opacity: 0; }
  4% { opacity: 1; }
  100% { opacity: 0; }
}
.photo-print {
  padding: 12px 12px 8px;
  background: #efe3c6;
  border: 2px solid var(--ink);
  border-radius: 4px;
  box-shadow: 4px 4px 0 rgba(35, 31, 32, 0.4);
  rotate: -1.5deg;
}
.photo-print__img {
  position: relative;
  aspect-ratio: 600 / 320;
  overflow: hidden;
  background: radial-gradient(ellipse at 50% 40%, #a88a5c, #5e4426);
  border: 2px solid #3b2a10;
}
.photo-print__img svg {
  display: block;
  width: 100%;
  height: 100%;
  filter: sepia(1) contrast(1.05) brightness(0.95);
}
.photo-print__img .is-blurred {
  filter: blur(2.5px);
}
.photo-print__img::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 50%, transparent 50%, rgba(40, 24, 8, 0.55));
}
.photo-print__cap {
  margin-top: 6px;
  font-family: var(--font-script);
  font-size: 1.25rem;
  text-align: center;
  color: #3b2a10;
}

/* A panel's hidden buttons stay hidden, whatever .btn says */
.panel [hidden] {
  display: none !important;
}

/* ---------- The telephone ---------- */
.room .phone {
  transform-box: fill-box;
  transform-origin: 50% 0;
}
.room .phone.is-ringing {
  animation: phone-ring 0.09s linear infinite;
}
@keyframes phone-ring {
  0%, 100% { transform: rotate(0); }
  25% { transform: rotate(-2.5deg); }
  75% { transform: rotate(2.5deg); }
}
.room .phone.is-off .phone__ear {
  visibility: hidden;
}

/* The first time in, how to get about: a calling card, up in the ceiling
   under the row of buttons, clear of the members (a stamp's slip, if one
   comes at the same moment, lies over it) */
.study-hint {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: calc(max(10px, env(safe-area-inset-top)) + 60px);
  bottom: auto;
  width: max-content;
  max-width: min(calc(100% - 48px), 420px);
  padding: 12px 22px 13px;
  font-family: var(--club-text);
  font-style: italic;
  font-size: 1.0625rem;
  line-height: 1.35;
  color: var(--club-ink);
  background: #fbf6e9;
  border: 2px solid var(--club-ink);
  border-radius: 3px;
  /* a fine engraved rule inside the edge */
  box-shadow: inset 0 0 0 4px #fbf6e9, inset 0 0 0 5px rgba(36, 23, 13, 0.45), 3px 3px 0 var(--club-ink);
  text-align: center;
  text-wrap: balance;
  translate: -50% -12px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease, translate 0.4s var(--ease-spring);
}
.study-hint.is-in {
  translate: -50% 0;
  opacity: 1;
}
/* who sent the card, engraved above the note (for study.js to add:
   <span class="study-hint__from">...</span> before the text) */
.study-hint__from {
  display: block;
  margin-bottom: 4px;
  font-family: var(--club-serif);
  font-style: normal;
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  color: var(--club-leather);
}

/* The minutes, in the members' book */
.minutes__title {
  margin-top: 16px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: 0.04em;
  color: var(--club-leather);
}
.minutes {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  font-family: var(--club-text);
  font-size: 1rem;
}
.minutes li + li {
  margin-top: 4px;
}
.minutes__time {
  display: inline-block;
  min-width: 4.4em;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}

/* Thunder makes the lights flicker */
.is-lightning .room .candle-glow {
  animation: lights-flicker 0.9s steps(1) 1;
}
@keyframes lights-flicker {
  0% { opacity: 1; }
  10% { opacity: 0.2; }
  20% { opacity: 0.9; }
  30% { opacity: 0.3; }
  45% { opacity: 1; }
}

/* ---------- Quiz night ---------- */
.quiz__q {
  margin: 4px 0 2px;
  font-family: var(--club-text);
  font-weight: 700;
  font-size: 1.15rem;
  line-height: 1.3;
}
.quiz__note {
  min-height: 2.6em;
  margin-top: 8px;
}
/* The right answer on baize, a wrong one on oxblood, both in gilt */
.study .panel .btn.is-right,
.study .panel .btn.is-wrong {
  opacity: 1;
  filter: none;
  color: #f3dc93;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
  box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0), inset 0 0 0 3px rgba(226, 194, 122, 0.6), 1px 1px 0 var(--club-ink);
}
.study .panel .btn.is-right {
  background-image: linear-gradient(175deg, #2b5e42 0%, #1d452f 60%, #173a27 100%);
}
.study .panel .btn.is-wrong {
  background-image: linear-gradient(175deg, #74251e 0%, #5a1914 55%, #4a130f 100%);
}
/* A quieter choice: plain card, engraved */
.study .panel .btn--white {
  color: var(--club-ink);
  text-shadow: none;
  background-image: none;
  background-color: #fbf5e4;
  box-shadow: 3px 3px 0 var(--club-ink);
}

/* Picture tiles: the drinks in the globe bar, the cigars in the humidor */
.picks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
  gap: 8px;
  margin-top: 8px;
}
.picks--drinks {
  grid-template-columns: repeat(3, 1fr);
}
/* the cigars one to a row, so their lengths show */
.picks--cigars {
  grid-template-columns: 1fr;
  gap: 6px;
}
.picks--cigars .pick {
  flex-direction: row;
  justify-content: flex-start;
  gap: 8px;
  padding: 4px 12px 4px 4px;
  text-align: left;
}
.pick {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-height: 44px;
  padding: 6px 4px 8px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.15;
  letter-spacing: 0.03em;
  text-align: center;
  color: var(--club-ink);
  background: #fbf5e4;
  border: 2px solid var(--club-ink);
  border-radius: 4px;
  box-shadow: inset 0 0 0 3px #fbf5e4, inset 0 0 0 4px rgba(180, 140, 56, 0.55), 3px 3px 0 var(--club-ink);
  cursor: pointer;
}
.pick:active {
  translate: 2px 2px;
  box-shadow: inset 0 0 0 3px #fbf5e4, inset 0 0 0 4px rgba(180, 140, 56, 0.55), 1px 1px 0 var(--club-ink);
}
.pick:focus-visible {
  outline: 3px solid var(--club-ink);
  outline-offset: 2px;
}
.pick svg {
  width: 100%;
  height: 84px;
  overflow: visible;
}
.picks--cigars .pick svg {
  flex: none;
  width: 62%;
  height: 46px;
}
.pick.is-chosen {
  background: #f3dc93;
  box-shadow: inset 0 0 0 3px #f3dc93, inset 0 0 0 4px rgba(122, 87, 25, 0.6), 3px 3px 0 var(--club-ink);
}
@media (hover: hover) {
  .pick:not(.is-chosen):hover {
    background: #fff8e6;
  }
}
/* a drink is poured: the glass fills from the bottom */
.pick__pour {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  transform: scaleY(0);
  transition: transform 0.9s ease-out 0.15s;
}
.pick.is-chosen .pick__pour {
  transform: scaleY(1);
}
/* a cigar is chosen: snipped, then lit, and it smokes */
.pick__cap {
  transition: translate 0.3s ease, opacity 0.3s ease;
}
.pick.is-chosen .pick__cap {
  translate: -8px 4px;
  opacity: 0;
}
.pick__ember,
.pick__smoke {
  opacity: 0;
  transition: opacity 0.4s ease 0.6s;
}
.pick.is-chosen .pick__ember {
  opacity: 1;
}
.pick.is-chosen .pick__smoke {
  opacity: 0.8;
}

@media (max-width: 600px) {
  /* on a phone the room's a narrow slice: the foreground would hide it */
  .fg {
    display: none;
  }
  .study-hint {
    border-radius: var(--radius-md);
    width: max-content;
  }
}

/* ---------- The cellar ---------- */
.blackout {
  position: absolute;
  inset: 0;
  z-index: 4;
  background: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.6s ease;
}
.blackout.is-on {
  opacity: 1;
}
.is-cellar .study-nav,
.is-cellar .fg {
  display: none;
}
/* "Back upstairs": a brass button (the kit) */
.up-btn {
  position: absolute;
  left: 50%;
  bottom: max(14px, env(safe-area-inset-bottom));
  translate: -50% 0;
  padding-inline: 22px;
}
.up-btn:active {
  translate: calc(-50% + 2px) 2px;
}
.up-btn[hidden],
[data-state="focus"] .up-btn {
  display: none;
}
.room .barrel__pour {
  visibility: hidden;
}
.room .barrel.is-pouring .barrel__pour {
  visibility: visible;
}
.room .mouse {
  transform-box: fill-box;
}
.room .mouse.is-running {
  animation: mouse-run 1.6s ease-in-out;
}
@keyframes mouse-run {
  0% { transform: translateX(0); }
  30% { transform: translateX(-260px); }
  45% { transform: translateX(-260px) scaleX(-1); }
  80% { transform: translateX(0) scaleX(-1); }
  100% { transform: translateX(0); }
}
.is-cellar-dark .room .cellar-candle-glow,
.is-cellar-dark .room .cellar-flame {
  visibility: hidden;
}
.is-cellar-dark .room .cellar-shade {
  opacity: 1;
}
.room .cellar-shade {
  transition: opacity 0.4s ease;
}

/* Pepper slips away and turns up somewhere else */
.room .pepper-pos {
  transition: opacity 0.6s ease;
}

/* While Truffle tells the story, the lights go down a little */
.room__shade {
  transition: background-color 1.5s ease;
}
.is-story .room__shade {
  background-color: rgba(10, 5, 2, 0.35);
}

/* A phone on its side: everything a little smaller */
@media (max-height: 520px) and (min-aspect-ratio: 1/1) {
  .study-nav {
    bottom: max(6px, env(safe-area-inset-bottom));
    padding: 3px;
  }
  .study-nav button {
    padding: 0.2em 0.65em;
    font-size: 0.82rem;
  }
  .leave,
  .sound,
  .card-btn {
    top: max(8px, env(safe-area-inset-top));
    padding: 0.2em 0.7em;
    font-size: 0.82rem;
  }
  .card-btn {
    right: calc(max(12px, env(safe-area-inset-right)) + 96px);
  }
  .study-hint {
    bottom: 52px;
    font-size: 0.85rem;
  }
  .panel {
    max-height: calc(100% - 56px);
    bottom: 8px;
  }
  .bubble {
    font-size: 0.85rem;
  }
}
[data-state="focus"] .study-hint {
  opacity: 0;
}

/* ---------- What you're wearing, in the corner ---------- */
.your-dress {
  position: absolute;
  left: max(12px, env(safe-area-inset-left));
  bottom: calc(max(12px, env(safe-area-inset-bottom)) + 70px);
  width: 76px;
  pointer-events: none;
  filter: drop-shadow(3px 3px 0 rgba(0, 0, 0, 0.35));
  text-align: center;
}
.your-dress[hidden],
[data-state="focus"] .your-dress {
  display: none;
}
.your-dress svg {
  display: block;
  width: 100%;
  height: auto;
  background: #f6ecd2;
  border: var(--stroke) solid var(--ink);
  border-radius: 50%;
}
/* "You", on a little brass plate under the portrait */
.your-dress span {
  position: relative;
  display: inline-block;
  margin-top: -10px;
  padding: 2px 9px;
  font-family: var(--club-serif);
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  color: #3a2508;
  text-shadow: 0 1px 0 rgba(255, 246, 214, 0.6);
  background-color: var(--club-brass);
  background-image: var(--club-brushed), var(--club-brass-face);
  border: 2px solid var(--club-ink);
  border-radius: 3px;
}
@media (max-width: 600px), (max-height: 520px) {
  .your-dress {
    width: 54px;
  }
}

/* The cab outside, crossing the window */
.room .cab__body {
  visibility: hidden;
}
.room .cab__body.is-passing {
  visibility: visible;
  animation: cab 6.5s linear forwards;
}
@keyframes cab {
  from { transform: translateX(0); }
  to { transform: translateX(860px); }
}

/* The debating society */
.motion {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.15rem;
  font-style: italic;
  line-height: 1.3;
}

/* Only the area you're in is there at all */
.room .area--cellar,
.is-cellar .room .area--room {
  visibility: hidden;
}
.is-cellar .room .area--cellar {
  visibility: visible;
}

.debate {
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  font-size: 1rem;
}
.debate li {
  margin-top: 4px;
  animation: deal 0.3s var(--ease-out);
}

/* Stepped up to something with nothing to show but itself (the rules):
   "Step back", in leather like Done */
.back-btn {
  position: absolute;
  left: 50%;
  bottom: max(14px, env(safe-area-inset-bottom));
  translate: -50% 0;
  display: none;
  padding-inline: 22px;
}
.back-btn:active {
  translate: calc(-50% + 2px) 2px;
}
.is-zoomed[data-state="focus"] .back-btn {
  display: inline-flex;
}

/* ---------- The kit: on dark wood, on a phone on its side, on a big screen ---------- */

/* A ring you can see on the dark room, round whatever has the keyboard
   (the site's ink ring vanishes against it); in card stock the ink one
   shows, as everywhere else on the site */
.leave:focus-visible,
.sound:focus-visible,
.card-btn:focus-visible,
.up-btn:focus-visible,
.back-btn:focus-visible,
.your-cigar:focus-visible {
  outline: 3px solid var(--club-brass-light);
  outline-offset: 3px;
}
.study-nav button:focus-visible {
  outline: 3px solid var(--club-brass-light);
  outline-offset: -5px;
  box-shadow: none;
}
.study-nav button[aria-current="true"]:focus-visible {
  outline-color: var(--club-ink);
}

/* On a phone the calling card keeps its square corners (an older rule
   above rounds the hint) */
@media (max-width: 600px) {
  .study-hint {
    border-radius: 3px;
  }
}

/* A phone on its side: the older rules above shrink the buttons; the kit
   keeps them 44 px tall, and the row along the top clear of the panel */
@media (max-height: 520px) and (min-aspect-ratio: 1/1) {
  .leave,
  .sound,
  .card-btn {
    top: max(8px, env(safe-area-inset-top));
  }
  .leave {
    padding: 6px 22px;
    font-size: 0.875rem;
  }
  .sound {
    padding: 0;
  }
  .card-btn {
    right: calc(max(12px, env(safe-area-inset-right)) + 54px);
    padding: 4px 12px 4px 38px;
    font-size: 0.8125rem;
  }
  .card-btn:has(.seal) {
    padding-left: 12px;
  }
  .study-nav {
    padding: 3px;
  }
  .study-nav button {
    padding: 4px 12px;
    font-size: 0.8125rem;
  }
  .study-nav button[aria-current="true"] {
    padding-inline: 22px;
  }
  .study-hint,
  .stamp-toast {
    top: calc(max(8px, env(safe-area-inset-top)) + 56px);
    bottom: auto;
  }
  .study-hint {
    font-size: 1rem;
  }
  .panel {
    max-height: calc(100% - 72px);
  }
}

/* A big screen (the owner's is 2560 wide): the kit a size up */
@media (min-width: 1800px) and (min-height: 1000px) {
  .panel {
    width: 460px;
  }
  .panel__title {
    font-size: 1.5rem;
  }
  .panel__body {
    font-size: 1.1875rem;
  }
  .study .panel .btn,
  .study .panel__done {
    min-height: 50px;
    font-size: 1.0625rem;
  }
  .leave,
  .card-btn {
    min-height: 52px;
    font-size: 1rem;
  }
  .sound {
    width: 52px;
    height: 52px;
    background-size: 30px 30px, auto, auto;
  }
  .card-btn {
    right: calc(max(12px, env(safe-area-inset-right)) + 62px);
  }
  .study-nav button {
    min-height: 50px;
    font-size: 1rem;
  }
  .study-hint,
  .stamp-toast {
    top: calc(max(10px, env(safe-area-inset-top)) + 68px);
    font-size: 1.125rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .stamp-toast.is-in .stamp-toast__seal {
    animation: none;
  }
  .stamp-toast,
  .study-hint {
    transition: opacity 0.3s ease;
  }
  .brass-btn,
  .leave,
  .study .panel .btn,
  .up-btn,
  .brass-btn--leather,
  .study .panel__done,
  .back-btn,
  .card-btn,
  .sound {
    transition: none;
  }
}

/* ---------- Captions: a member's line from off the screen ----------
   study.js (S.say) puts it along the bottom, with his name, when the member
   speaking isn't on screen: a bubble with no tail, as there's nobody under
   it to point at. */
.bubble--caption {
  max-width: min(320px, calc(100vw - 32px));
}
.bubble--caption::after {
  display: none;
}
.bubble__who {
  font-weight: 700;
}
/* Nothing in the room is for long-pressing: no copy menu, no preview */
.stage {
  -webkit-touch-callout: none;
}
