:root {
  --room-ivory: #f4eadb;
  --room-paper: #faf4e8;
  --room-ink: #2b1f14;
  --room-ink-soft: rgba(43, 31, 20, .65);
  --room-amber: #c46a2b;
  --room-amber-dark: #8f4618;
  --room-teal: #1e6a66;
  --room-night: #17120e;
  --room-line: rgba(43, 31, 20, .18);
  --room-serif: "Fraunces", Georgia, serif;
  --room-sans: "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --safe-top: max(18px, env(safe-area-inset-top));
  --safe-right: max(20px, env(safe-area-inset-right));
  --safe-bottom: max(18px, env(safe-area-inset-bottom));
  --safe-left: max(20px, env(safe-area-inset-left));
}

* {
  box-sizing: border-box;
}

html,
body {
  min-height: 100%;
  margin: 0;
  background: var(--room-night);
  color: var(--room-ink);
  font-family: var(--room-sans);
  overscroll-behavior: none;
}

body {
  overflow: hidden;
}

button,
a {
  color: inherit;
  font: inherit;
}

button {
  border: 0;
}

:where(a, button):focus-visible {
  outline: 2px solid var(--room-amber);
  outline-offset: 4px;
}

.skip-link {
  position: fixed;
  z-index: 200;
  top: 12px;
  left: 12px;
  padding: 10px 14px;
  background: var(--room-paper);
  color: var(--room-ink);
  transform: translateY(-160%);
  transition: transform .2s ease;
}

.skip-link:focus {
  transform: translateY(0);
}

.room-shell {
  position: relative;
  min-height: 100dvh;
  isolation: isolate;
  overflow: hidden;
  background:
    radial-gradient(circle at 64% 18%, rgba(255, 210, 155, .32), transparent 38%),
    linear-gradient(145deg, #dfc9ad 0%, #ae7e5c 55%, #69452f 100%);
  transition: filter .8s ease, background .8s ease;
}

.room-shell::after {
  position: absolute;
  z-index: 2;
  inset: 0;
  content: "";
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(18, 12, 7, .2), transparent 25%, transparent 75%, rgba(18, 12, 7, .18)),
    radial-gradient(circle at 56% 42%, transparent 30%, rgba(19, 12, 8, .3) 110%);
  mix-blend-mode: multiply;
}

html[data-room-theme="night"] .room-shell {
  background:
    radial-gradient(circle at 68% 22%, rgba(30, 106, 102, .28), transparent 36%),
    linear-gradient(145deg, #27251f 0%, #1b2322 55%, #111413 100%);
}

#room-canvas {
  position: absolute;
  z-index: 1;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: grab;
}

#room-canvas:active {
  cursor: grabbing;
}

.room-atmosphere {
  position: absolute;
  z-index: 3;
  inset: 0;
  pointer-events: none;
  opacity: .16;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.24'/%3E%3C/svg%3E");
  mix-blend-mode: soft-light;
}

.room-header {
  position: absolute;
  z-index: 12;
  top: 0;
  right: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--safe-top) var(--safe-right) 0 var(--safe-left);
  pointer-events: none;
}

.room-brand,
.room-header-actions,
.room-icon-button {
  pointer-events: auto;
}

.room-brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  color: var(--room-paper);
  text-decoration: none;
  text-shadow: 0 1px 16px rgba(26, 15, 8, .32);
}

.room-brand-mark {
  position: relative;
  display: block;
  width: 39px;
  height: 39px;
  border: 1px solid rgba(255, 255, 255, .55);
  background: rgba(43, 31, 20, .18);
  backdrop-filter: blur(14px);
}

.room-brand-mark::after {
  content: "";
  position: absolute;
  inset: 6px 7px;
  background: var(--room-paper);
  -webkit-mask: url('/assets/img/ry-monogram.svg') center / contain no-repeat;
  mask: url('/assets/img/ry-monogram.svg') center / contain no-repeat;
}

.room-brand strong,
.room-brand small {
  display: block;
}

.room-brand strong {
  font-family: var(--room-serif);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.05;
}

.room-brand small {
  margin-top: 3px;
  font-size: 11px;
  letter-spacing: .11em;
  opacity: .72;
  text-transform: uppercase;
}

.room-header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.room-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 13px;
  border: 1px solid rgba(255, 255, 255, .28);
  background: rgba(34, 25, 18, .18);
  color: var(--room-paper);
  font-size: 11px;
  letter-spacing: .06em;
  backdrop-filter: blur(14px);
}

.room-status i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #c9db9e;
  box-shadow: 0 0 0 4px rgba(201, 219, 158, .13);
}

/* ---------- First-visit onboarding ----------
 * Two things the room never said out loud: that the pulsing dots are controls,
 * and that a second presentation exists behind a switch that reads as a label.
 * Both appear once, name themselves plainly, and leave on the first interaction.
 */

.room-mode-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.room-mode-hint {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 14;
  width: max-content;
  max-width: min(30ch, 60vw);
  margin: 0;
  padding: 9px 12px;
  border: 1px solid rgba(196, 106, 43, .5);
  border-radius: 10px;
  background: rgba(250, 244, 232, .96);
  color: var(--room-ink);
  font-size: 11.5px;
  line-height: 1.45;
  letter-spacing: 0;
  text-align: left;
  text-transform: none;
  box-shadow: 0 14px 34px -18px rgba(23, 18, 14, .8);
  pointer-events: none;
}

/* A little arrow so it reads as pointing at the switch above it. */
.room-mode-hint::before {
  position: absolute;
  top: -5px;
  right: 34px;
  width: 8px;
  height: 8px;
  border-top: 1px solid rgba(196, 106, 43, .5);
  border-left: 1px solid rgba(196, 106, 43, .5);
  background: inherit;
  content: "";
  transform: rotate(45deg);
}

/* While the hint is up the switch itself carries a ring, so the eye connects
   the sentence to the control it describes. */
.room-mode[data-onboarding="true"] {
  border-color: rgba(196, 106, 43, .85);
  box-shadow: 0 0 0 3px rgba(196, 106, 43, .22);
}

.room-onboard {
  position: absolute;
  z-index: 13;
  width: min(30ch, calc(100% - 40px));
  padding: 13px 15px 12px;
  border: 1px solid rgba(196, 106, 43, .45);
  border-radius: 12px;
  background: rgba(250, 244, 232, .97);
  color: var(--room-ink);
  box-shadow: 0 20px 44px -22px rgba(23, 18, 14, .85);
  /* Placed against the computer marker each frame by updateHotspots(). */
  transform: translate(-50%, -50%);
}

.room-onboard-copy {
  margin: 0 0 10px;
  font-size: 12.5px;
  line-height: 1.5;
}

.room-onboard-copy strong {
  display: block;
  margin-bottom: 3px;
  font-family: var(--room-serif);
  font-size: 15px;
  font-weight: 600;
}

.room-onboard-copy span {
  color: var(--room-ink-soft);
}

.room-onboard-dismiss {
  padding: 7px 13px;
  border: 1px solid rgba(43, 31, 20, .28);
  border-radius: 999px;
  background: var(--room-ink);
  color: var(--room-paper);
  font: 600 11px/1 var(--room-sans);
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
}

.room-onboard-dismiss:hover,
.room-onboard-dismiss:focus-visible {
  background: var(--room-amber-dark);
}

/* The marker the hint is about beats harder than the rest while it is up. */
.room-hotspot[data-onboarding="true"] .hotspot-dot {
  background: var(--room-paper);
  box-shadow: 0 0 0 5px rgba(196, 106, 43, .3);
  transform: translate(-50%, -50%) scale(1.35);
}

.room-hotspot[data-onboarding="true"] .hotspot-copy {
  opacity: 1;
  transform: translate(0, -50%);
}

@media (prefers-reduced-motion: reduce) {
  .room-hotspot[data-onboarding="true"] .hotspot-dot {
    transform: translate(-50%, -50%) scale(1.2);
  }
}

/* A phone is narrower than the callout, so riding the marker pushed it off the
   left edge. Dock it above the shortcut bar instead and let the lit marker alone
   carry the aim — updateHotspots() stops repositioning it below this width. */
@media (max-width: 640px) {
  .room-onboard {
    top: auto;
    right: 16px;
    bottom: calc(104px + var(--safe-bottom));
    left: 16px;
    width: auto;
    transform: none;
  }

  .room-mode-hint {
    right: auto;
    left: 50%;
    max-width: min(30ch, calc(100vw - 32px));
    transform: translateX(-50%);
  }

  .room-mode-hint::before {
    right: auto;
    left: 50%;
    margin-left: -4px;
  }
}

.room-mode {
  display: inline-flex;
  padding: 3px;
  border: 1px solid rgba(255, 255, 255, .28);
  background: rgba(34, 25, 18, .18);
  backdrop-filter: blur(14px);
}

.room-mode button {
  /* 21px tall as authored, under the 24px WCAG 2.2 target minimum, and this is
     the control that switches the entire site between its two presentations. */
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 7px 12px;
  border: 0;
  background: transparent;
  color: rgba(250, 244, 232, .66);
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .11em;
  text-transform: uppercase;
  transition: background .22s ease, color .22s ease;
}

.room-mode button:hover {
  color: var(--room-paper);
}

.room-mode button.is-active {
  background: rgba(250, 244, 232, .92);
  color: var(--room-ink);
}

.room-icon-button {
  display: grid;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, .28);
  background: rgba(34, 25, 18, .18);
  cursor: pointer;
  place-items: center;
  backdrop-filter: blur(14px);
  transition: background .25s ease, transform .25s ease;
}

.room-icon-button:hover {
  background: rgba(34, 25, 18, .4);
  transform: translateY(-2px);
}

.room-icon-button:active {
  transform: translateY(0) scale(.97);
}

.theme-icon {
  position: relative;
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--room-paper);
  border-radius: 50%;
}

.theme-icon::after {
  position: absolute;
  top: -4px;
  left: 7px;
  width: 1px;
  height: 22px;
  content: "";
  background: var(--room-paper);
  box-shadow: 0 0 0 3px rgba(34, 25, 18, .18);
  transform: rotate(45deg);
  transform-origin: center;
}

.room-title-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.room-gesture {
  position: absolute;
  z-index: 10;
  right: var(--safe-right);
  bottom: calc(90px + var(--safe-bottom));
  display: flex;
  align-items: center;
  gap: 10px;
  color: rgba(250, 244, 232, .7);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.gesture-mouse {
  position: relative;
  width: 17px;
  height: 25px;
  border: 1px solid currentColor;
  border-radius: 9px;
}

.gesture-mouse::before {
  position: absolute;
  top: 4px;
  left: 7px;
  width: 1px;
  height: 5px;
  content: "";
  background: currentColor;
}

.room-dock {
  position: absolute;
  z-index: 14;
  right: var(--safe-right);
  bottom: var(--safe-bottom);
  left: var(--safe-left);
  display: grid;
  max-width: 760px;
  margin: 0 auto;
  border: 1px solid rgba(255, 255, 255, .27);
  grid-template-columns: repeat(6, 1fr);
  background: rgba(30, 22, 16, .38);
  box-shadow: 0 18px 52px rgba(24, 15, 9, .24);
  backdrop-filter: blur(18px) saturate(120%);
}

.room-dock button {
  min-width: 0;
  padding: 11px 10px 12px;
  border-right: 1px solid rgba(255, 255, 255, .14);
  background: transparent;
  color: var(--room-paper);
  cursor: pointer;
  text-align: left;
  transition: background .2s ease, transform .2s ease;
}

.room-dock button:last-child {
  border-right: 0;
}

.room-dock button:hover {
  background: rgba(255, 255, 255, .12);
  transform: translateY(-2px);
}

.room-dock button:active {
  transform: translateY(0);
}

.room-dock span,
.room-dock b {
  display: block;
}

.room-dock span {
  margin-bottom: 4px;
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 11px;
  opacity: .56;
}

.room-dock b {
  overflow: hidden;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .02em;
  text-overflow: ellipsis;
}

.room-hotspots {
  position: absolute;
  z-index: 9;
  inset: 0;
  pointer-events: none;
}

.room-hotspot {
  position: absolute;
  display: block;
  width: 22px;
  height: 22px;
  padding: 0;
  background: transparent;
  color: var(--room-paper);
  cursor: pointer;
  opacity: 0;
  /* Until the first frame projects them, markers sit unplaced at the top-left
     corner: transparent, and never a phantom click target. */
  pointer-events: none;
  text-align: left;
  text-shadow: 0 2px 14px rgba(31, 17, 8, .72);
  transform: translate(-50%, -50%);
  transition: opacity .35s ease;
}

/* These five markers are the whole navigation of the room, and the room is what
   ships at `/`. At 22px they sat under the 24px floor for a touch target and
   well under the 44px a thumb actually wants — on the page whose own onboarding
   card tells you to tap one. The visible dot is a 9px child centred on this
   button, so widening the button widens only the hit area: the room looks
   identical and the targets stop being a game of precision. */
@media (hover: none) and (pointer: coarse) {
  .room-hotspot {
    width: 44px;
    height: 44px;
  }
}

.room-hotspot.is-visible {
  opacity: 1;
  pointer-events: auto;
}

.room-dock,
.room-gesture,
.room-hotspots {
  transition: opacity .32s ease, transform .32s ease;
}

html:not([data-room-focus="default"]) .room-dock,
html:not([data-room-focus="default"]) .room-gesture {
  opacity: 0;
  pointer-events: none;
  transform: translateY(10px);
}

html:not([data-room-focus="default"]) .room-hotspots {
  opacity: 0;
  pointer-events: none;
}

.hotspot-dot {
  position: absolute;
  top: 50%;
  left: 50%;
  display: block;
  width: 9px;
  height: 9px;
  border: 1.5px solid rgba(250, 244, 232, .92);
  border-radius: 50%;
  background: rgba(196, 106, 43, .9);
  box-shadow: 0 0 0 4px rgba(30, 18, 10, .22);
  transform: translate(-50%, -50%);
  transition: transform .22s ease, background .22s ease;
}

.hotspot-dot::after {
  position: absolute;
  inset: -6px;
  border: 1px solid rgba(250, 244, 232, .3);
  border-radius: inherit;
  content: "";
  animation: hotspot-pulse 2.8s ease-out infinite;
}

.room-hotspot:hover .hotspot-dot,
.room-hotspot:focus-visible .hotspot-dot {
  background: var(--room-paper);
  transform: translate(-50%, -50%) scale(1.25);
}

.hotspot-copy {
  position: absolute;
  top: 50%;
  left: 18px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .1em;
  opacity: 0;
  text-transform: uppercase;
  transform: translate(-4px, -50%);
  transition: opacity .22s ease, transform .22s ease;
  white-space: nowrap;
}

.room-hotspot:hover .hotspot-copy,
.room-hotspot:focus-visible .hotspot-copy {
  opacity: 1;
  transform: translate(0, -50%);
}

@keyframes hotspot-pulse {
  0% { opacity: .7; transform: scale(.6); }
  75%, 100% { opacity: 0; transform: scale(1.4); }
}

.room-fallback {
  position: absolute;
  z-index: 11;
  right: var(--safe-right);
  bottom: calc(88px + var(--safe-bottom));
  width: min(34ch, calc(100% - 40px));
  margin: 0;
  padding: 12px 14px;
  background: rgba(250, 244, 232, .88);
  color: var(--room-ink);
  font-size: 12px;
  line-height: 1.45;
}

.computer-interface {
  --interface-origin-x: 50%;
  --interface-origin-y: 50%;
  position: fixed;
  z-index: 80;
  inset: 0;
  display: grid;
  padding: clamp(10px, 2vw, 28px);
  background: #130f0c;
  opacity: 0;
  pointer-events: none;
  place-items: center;
  transform: scale(.96);
  transform-origin: var(--interface-origin-x) var(--interface-origin-y);
  transition: opacity .48s cubic-bezier(.2, .8, .2, 1), transform .48s cubic-bezier(.2, .8, .2, 1);
}

.computer-interface.is-open {
  opacity: 1;
  pointer-events: auto;
  transform: scale(1);
}

/* Professional is its own site, not a window inside the studio: it takes the
   whole screen, and every trace of the room steps aside. The switch stays in
   the bar, which is the only way back. */
html[data-site-mode="professional"] #room-canvas,
html[data-site-mode="professional"] .room-atmosphere,
html[data-site-mode="professional"] .room-header,
html[data-site-mode="professional"] .room-dock,
html[data-site-mode="professional"] .room-hotspots,
html[data-site-mode="professional"] .room-gesture,
html[data-site-mode="professional"] .room-loader,
html[data-site-mode="professional"] .skip-link,
html[data-site-mode="professional"] .computer-back,
html[data-site-mode="professional"] .computer-address,
html[data-site-mode="professional"] .computer-tabs {
  display: none;
}

html[data-site-mode="professional"] .computer-interface {
  padding: 0;
  background: var(--room-paper);
  transform: none;
}

html[data-site-mode="professional"] .computer-frame {
  width: 100%;
  height: 100%;
  border: 0;
  box-shadow: none;
  /* Two rows, not three: with the tabs hidden the viewport would otherwise
     land in the `auto` row and collapse to the iframe's default height. */
  grid-template-rows: auto minmax(0, 1fr);
}

html[data-site-mode="professional"] .computer-bar {
  grid-template-columns: 1fr auto;
}

html[data-site-mode="professional"] .computer-bar-end {
  grid-column: 2;
}

.computer-frame {
  display: grid;
  width: min(1680px, 100%);
  height: min(1050px, 100%);
  min-height: 0;
  overflow: hidden;
  border: 1px solid rgba(250, 244, 232, .19);
  background: #1f1914;
  box-shadow: 0 40px 110px rgba(0, 0, 0, .62);
  grid-template-rows: auto auto minmax(0, 1fr);
}

.computer-bar {
  display: grid;
  min-height: 48px;
  align-items: center;
  padding: 8px 12px;
  border-bottom: 1px solid rgba(250, 244, 232, .12);
  color: var(--room-paper);
  /* The address gives way rather than running under its neighbours: the two
     ends are sized by their content, and it takes whatever is left. The gap
     is on the grid so the separation survives however the address shrinks. */
  column-gap: 16px;
  grid-template-columns: auto minmax(0, 1fr) auto;
}

.computer-back,
.computer-external {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font-size: 11px;
  text-decoration: none;
  transition: background .2s ease;
}

.computer-back {
  justify-self: start;
}

/* The room header is covered while the computer is open, so the presentation
   switch is repeated here — same data attributes, so one handler drives both. */
.computer-bar-end {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  justify-self: end;
}

.computer-mode {
  border-color: rgba(250, 244, 232, .18);
  background: rgba(250, 244, 232, .06);
}

.computer-mode button {
  padding: 6px 10px;
  font-size: 11px;
}

.computer-back:hover,
.computer-external:hover {
  background: rgba(250, 244, 232, .09);
}

.computer-back svg,
.computer-external svg {
  width: 15px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.5;
}

.computer-address {
  display: flex;
  min-width: 0;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: 11px;
  letter-spacing: .04em;
  opacity: .54;
}

.computer-address span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.computer-address i {
  flex: 0 0 auto;
}

.computer-address i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #9cb37c;
}

.computer-tabs {
  display: flex;
  justify-content: center;
  overflow-x: auto;
  border-bottom: 1px solid rgba(250, 244, 232, .1);
  background: #191410;
  scrollbar-width: none;
}

.computer-tabs::-webkit-scrollbar {
  display: none;
}

.computer-tabs button {
  flex: 0 0 auto;
  padding: 10px 16px 9px;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: rgba(250, 244, 232, .56);
  cursor: pointer;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  transition: color .2s ease, border-color .2s ease, background .2s ease;
}

.computer-tabs button:hover,
.computer-tabs button[aria-current="page"] {
  border-bottom-color: var(--room-amber);
  background: rgba(250, 244, 232, .04);
  color: var(--room-paper);
}

.computer-viewport {
  position: relative;
  min-height: 0;
  overflow: hidden;
  background: var(--room-paper);
}

#portfolio-frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: var(--room-paper);
  opacity: 0;
  transition: opacity .3s ease;
}

#portfolio-frame.is-ready {
  opacity: 1;
}

.computer-loader {
  position: absolute;
  z-index: 2;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 14px;
  background: var(--room-paper);
  color: var(--room-ink);
  transition: opacity .25s ease, visibility .25s ease;
}

.computer-loader.is-hidden {
  visibility: hidden;
  opacity: 0;
}

.computer-loader span {
  width: 38px;
  height: 1px;
  overflow: hidden;
  background: rgba(43, 31, 20, .18);
}

.computer-loader span::after {
  display: block;
  width: 45%;
  height: 100%;
  content: "";
  background: var(--room-amber);
  animation: computer-load 1s ease-in-out infinite alternate;
}

.computer-loader p {
  margin: 0;
  font-family: var(--room-serif);
  font-size: 14px;
}

@keyframes computer-load {
  from { transform: translateX(-110%); }
  to { transform: translateX(220%); }
}

.room-loader {
  position: fixed;
  z-index: 150;
  inset: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  min-height: 100dvh;
  background:
    radial-gradient(circle at 28% 24%, rgba(200, 168, 99, .34), transparent 36%),
    #0d1117;
  color: #f6f2ea;
  isolation: isolate;
  transition: transform .54s cubic-bezier(.77, 0, .175, 1), visibility 0s linear .54s;
  will-change: transform;
}

/* Only the stylesheet's own timer, for the case where the module never runs.
   room-index.html claims ownership inline before the module parses, so with JS
   alive this never fires and the authored hold is the single source of truth. */
html:not([data-room-loader-owner]) .room-loader {
  animation: room-loader-ceiling .54s cubic-bezier(.77, 0, .175, 1) 1.24s forwards;
}

@keyframes room-loader-ceiling {
  to {
    visibility: hidden;
    transform: translate3d(0, -101%, 0);
  }
}

.room-loader.is-complete {
  visibility: hidden;
  transform: translate3d(0, -101%, 0);
}

/* The curtain is dismissed half a second after the room first paints, and
   `visibility` only stops hit-testing once the fade ends. From the moment the
   room is live the loader is decoration, so it must never eat a click. */
html[data-room-ready="true"] .room-loader {
  pointer-events: none;
}

.room-loader-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

/* This is the only loader that carries the R/Y identity. Keeping it as a real
   foreground layer guarantees the animated shader cannot paint over the mark. */
.room-loader-mark {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: 50%;
  display: block;
  width: clamp(8.5rem, 18vw, 13.5rem);
  aspect-ratio: 619.75 / 512;
  background: #f6f2ea;
  -webkit-mask: url('/assets/img/ry-monogram.svg') center / contain no-repeat;
  mask: url('/assets/img/ry-monogram.svg') center / contain no-repeat;
  transform: translate3d(-50%, -50%, 0);
  filter: drop-shadow(.4rem .55rem 1.4rem rgba(13, 17, 23, .38));
  transition: opacity .24s ease, transform .46s cubic-bezier(.22, 1, .36, 1);
  will-change: transform, opacity;
}

.room-loader-progress {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: calc(50% + clamp(165px, 16vw, 220px));
  display: flex;
  align-items: flex-start;
  gap: .18em;
  transform: translate3d(-50%, 0, 0);
  font-family: var(--room-sans);
  font-size: clamp(.72rem, 1vw, .9rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: .16em;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 18px rgba(13, 17, 23, .34);
  transition: opacity .22s ease, transform .4s cubic-bezier(.22, 1, .36, 1);
  will-change: transform, opacity;
}

.room-loader-progress small {
  margin-top: .08em;
  font: inherit;
  font-size: .7em;
  opacity: .62;
}

.room-loader.is-finishing .room-loader-progress {
  opacity: 0;
  transform: translate3d(-50%, -10px, 0);
}

.room-loader.is-finishing .room-loader-mark {
  opacity: 0;
  transform: translate3d(-50%, -54%, 0) scale(1.06);
}

/* The overlay is skippable anywhere, but a pointer-only escape strands keyboard
   and screen-reader visitors behind four seconds of curtain. It arrives after
   the mark has landed so the entrance still gets its opening beat. */
.room-loader-skip {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: clamp(26px, 5.5vh, 58px);
  padding: 11px 22px;
  border: 1px solid rgba(246, 242, 234, .26);
  border-radius: 999px;
  background: rgba(13, 17, 23, .28);
  color: rgba(246, 242, 234, .74);
  font: 600 clamp(.6rem, .78vw, .72rem)/1 var(--room-sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  cursor: pointer;
  opacity: 0;
  transform: translate3d(-50%, 8px, 0);
  animation: room-loader-skip-in .46s cubic-bezier(.22, 1, .36, 1) 1.15s forwards;
  transition: color .2s ease, border-color .2s ease, background-color .2s ease;
}

@keyframes room-loader-skip-in {
  to {
    opacity: 1;
    transform: translate3d(-50%, 0, 0);
  }
}

.room-loader-skip:hover,
.room-loader-skip:focus-visible {
  border-color: rgba(200, 168, 99, .72);
  background: rgba(200, 168, 99, .14);
  color: #f6f2ea;
}

.room-loader.is-finishing .room-loader-skip {
  opacity: 0;
  transition: opacity .18s ease;
}

@media (prefers-reduced-motion: reduce) {
  .room-loader-skip {
    animation-delay: 0s;
    animation-duration: .01s;
  }
}

@media (max-width: 600px) {
  .room-loader-progress {
    top: calc(50% + 165px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .room-loader {
    animation: none;
    transition-duration: .12s;
    transition-delay: 0s;
  }

  .room-loader-canvas {
    display: none;
  }

  .room-loader-mark {
    transition: none;
  }
}

.noscript-card {
  position: fixed;
  z-index: 300;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: start;
  padding: 10vw;
  background: var(--room-paper);
}

.noscript-card h1 {
  margin: 0;
  font: 600 clamp(3rem, 8vw, 7rem)/.9 var(--room-serif);
}

.noscript-card p {
  max-width: 44ch;
  line-height: 1.6;
}

.noscript-card a {
  padding: 12px 16px;
  background: var(--room-ink);
  color: var(--room-paper);
}

@media (max-width: 640px) {
  .room-header {
    align-items: flex-start;
  }

  .room-status {
    display: none;
  }

  .room-brand small {
    display: none;
  }

  .room-brand strong {
    font-size: 15px;
  }

  .room-mode button {
    /* 9px is below comfortable reading on the device this rule targets, and the
       narrower padding was what dropped the target under 24px. */
    padding: 7px 10px;
    font-size: 11px;
    letter-spacing: .06em;
  }

  .room-gesture {
    display: none;
  }

  .room-dock {
    right: 0;
    bottom: 0;
    left: 0;
    max-width: none;
    padding-bottom: env(safe-area-inset-bottom);
    border-right: 0;
    border-bottom: 0;
    border-left: 0;
    grid-template-columns: repeat(3, 1fr);
  }

  .room-dock button {
    border-bottom: 1px solid rgba(255, 255, 255, .12);
  }

  .room-dock button:nth-child(3n) {
    border-right: 0;
  }

  .room-dock span {
    display: none;
  }

  .computer-interface {
    padding: 0;
  }

  .computer-frame {
    width: 100%;
    height: 100%;
    border: 0;
  }

  .computer-bar {
    min-height: 52px;
    padding-top: max(8px, env(safe-area-inset-top));
    grid-template-columns: 1fr auto;
  }

  .computer-address {
    display: none;
  }

  .computer-external {
    font-size: 0;
  }

  .computer-external svg {
    width: 18px;
  }

  .computer-mode button {
    padding: 6px 7px;
    font-size: 11px;
    letter-spacing: .04em;
  }

  .computer-tabs {
    justify-content: flex-start;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
