/* The visitors' page (round 4 part 3, H2): its header, the knock on each room's door, the note at
   the foot of the screen, and the talk with a crew member. The building itself is the desk's room
   (style.css and the drawings' sheets); nothing here is drawn inline. */
/* The top (round 6; Chris, 18 Oct, night: the welcome read like "an extremely obvious museum sign",
   and what was left once it folded was "too imposing"): the building fills the screen. A small
   see-through mark stays at the top with a round (i) for "About the studio"; during the glide
   (visit.js arrive), a small Skip. Only the buttons take a tap: the building stays in reach. */
.visit-head {
  position: fixed; top: 0; left: 0; right: 0; z-index: 12; display: flex; align-items: center; gap: 8px;
  padding: calc(env(safe-area-inset-top, 0px) + 10px) max(12px, env(safe-area-inset-right, 0px)) 0 max(12px, env(safe-area-inset-left, 0px));
  pointer-events: none;
}
.visit-head button { pointer-events: auto; }
.visit-mark {
  min-width: 0; margin: 0; padding: 6px 11px; border-radius: 999px; font: 600 12px/1.2 var(--mono); letter-spacing: 0.08em;
  text-transform: uppercase; color: rgba(243, 241, 237, 0.78); background: rgba(13, 12, 11, 0.34);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.visit-info, .visit-skip {
  flex: none; min-height: 34px; border: 1px solid rgba(243, 241, 237, 0.22); background: rgba(13, 12, 11, 0.34); color: rgba(243, 241, 237, 0.9);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); cursor: pointer;
}
/* The "i" is drawn and set in the middle of its circle (round 7, Chris, 18 Oct: "not centered in its
   bubble"): a letter's own box never sits in the optical middle. */
.visit-info { margin-left: auto; width: 34px; padding: 0; border-radius: 50%; display: inline-grid; place-items: center; }
.visit-info .info-i { display: block; width: 16px; height: 16px; fill: currentColor; }
.visit-skip { margin-left: auto; padding: 0 14px; border-radius: 999px; font: 600 13px var(--font); }
.visit-skip:not([hidden]) + .visit-info { margin-left: 0; }
/* Talk with people here (round 7, part L): beside the (i), its count of new messages on it. */
.visit-people {
  flex: none; position: relative; margin-left: auto; width: 34px; min-height: 34px; padding: 0; border-radius: 50%; display: inline-grid; place-items: center;
  border: 1px solid rgba(243, 241, 237, 0.22); background: rgba(13, 12, 11, 0.34); color: rgba(243, 241, 237, 0.9);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); cursor: pointer;
}
.visit-people .talk-i { display: block; width: 16px; height: 16px; fill: currentColor; }
.visit-people:hover, .visit-people:focus-visible { background: rgba(13, 12, 11, 0.62); color: var(--text); }
.visit-skip:not([hidden]) ~ .visit-people, .visit-skip:not([hidden]) ~ .visit-info, .visit-people:not([hidden]) ~ .visit-info { margin-left: 0; }
.people-badge {
  position: absolute; top: -5px; right: -5px; min-width: 17px; height: 17px; padding: 0 4px; border-radius: 999px;
  background: var(--gold); color: #1b1714; font: 700 10.5px/17px var(--font); text-align: center;
}
.visit-info:hover, .visit-info:focus-visible, .visit-skip:hover, .visit-skip:focus-visible { background: rgba(13, 12, 11, 0.62); color: var(--text); }
/* Arrived at "You are here", the mark leaves too (it sat over the lobby's plates): only the (i) stays. */
.visit-head.arrived .visit-mark { opacity: 0; visibility: hidden; }
@media (prefers-reduced-motion: no-preference) { .visit-mark { transition: opacity 0.6s ease, visibility 0.6s; } }
/* Once, on a first visit, for a few seconds after arriving, at the foot of the screen, off the figures. */
.visit-hint {
  position: fixed; left: 50%; bottom: calc(env(safe-area-inset-bottom, 0px) + 18px); transform: translateX(-50%); z-index: 12;
  max-width: calc(100vw - 32px); margin: 0; padding: 7px 14px; border-radius: 999px; background: rgba(13, 12, 11, 0.62);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); color: #f6f1e7; font: 600 14px/1.3 var(--font); text-align: center; pointer-events: none;
}
/* Aboard the new world its own buttons stand at the foot (a talk's, the tour's, Places and Crew): the hint above them
   (20 Oct: it lay over Constans's two on a phone). */
html.v3d-world .visit-hint { bottom: calc(env(safe-area-inset-bottom, 0px) + 124px); }
@media (prefers-reduced-motion: no-preference) { .visit-hint:not([hidden]) { animation: hint-in 0.5s ease-out both; } }
@keyframes hint-in { from { opacity: 0; transform: translate(-50%, -6px); } to { opacity: 1; transform: translate(-50%, 0); } }
.visit-main { display: grid; gap: 0; }
/* C, round 6: the visitor's own figure, "You" over his hat; "Talk" over someone he stopped beside;
   "Back to me" when he is out of sight. */
.walker.me::after {
  content: attr(data-label); position: absolute; left: 50%; top: -6px; transform: translate(-50%, -100%); padding: 1px 7px; border-radius: 999px;
  background: rgba(13, 12, 11, 0.66); color: var(--gold); font: 700 11px/1.4 var(--font); white-space: nowrap; pointer-events: none;
}
/* Over the one he stands beside: every desk is the box its "Talk" stands in (round 7: it had stood
   in the room's corner for everyone but Arion, whose desk alone was positioned). */
#zones .desk-unit { position: relative; }
/* Round 7, part V4: she lies in the sea out to the page's edges, the quay and the gangway at her stern
   where a visitor comes aboard (ship.js, ship.css). */
@media (min-width: 1000px) {
  .visit-main .ship .hull::before { left: -48px; right: -48px; }
  .visit-main .ship .hull::after { left: -48px; right: -48px; }
  .visit-main .hull-quay { display: block; position: absolute; right: 100%; bottom: calc(var(--keel) - 10px); width: 48px; height: 30px; pointer-events: none; }
  .visit-main .hull-quay-art { display: block; width: 100%; height: 100%; }
}
.near-talk {
  position: absolute; left: 4%; top: 6%; z-index: 3; min-height: 28px; padding: 3px 12px; border-radius: 999px; border: 1px solid var(--gold);
  background: rgba(13, 12, 11, 0.82); color: var(--gold); font: 700 13px var(--font); cursor: pointer;
}
.back-to-me {
  position: fixed; left: 50%; bottom: calc(env(safe-area-inset-bottom, 0px) + 64px); transform: translateX(-50%); z-index: 13;
  min-height: 36px; padding: 6px 16px; border-radius: 999px; border: 1px solid var(--gold); background: rgba(13, 12, 11, 0.78);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); color: var(--gold); font: 700 14px var(--font); cursor: pointer;
}
html.sheet-open .back-to-me { display: none; }

/* H, round 6: the arrival's camera (visit.js arrive) scales the building from the middle of its top;
   the opening shot shows it at night, each floor's rooms dark until its moment (--lights) comes. */
.visit-main { transform-origin: 50% 0; }
.visit-main.dusk .storey { opacity: 0.14; }
.visit-main.dusk.lights .storey { opacity: 1; transition: opacity 0.6s ease-out var(--lights, 0ms); }
/* The building's own small moves (breathing, blinking, screens, waves) wait for the camera: in the
   opening shot every one of them is on the screen, and each would repaint the moving building. */
.visit-main.dusk * { animation-play-state: paused !important; }
/* The page's foot stands below the lobby: in the shot it would float beside the building. */
.visit-main.dusk ~ .visit-foot { visibility: hidden; }
.visit-staff, .visit-foot { margin: 12px 4px 0; font-size: 13px; color: var(--faint); }
/* The room's sheet orders the building (style.css); this note comes after it. */
.visit-staff { order: 3; }
.visit-foot { margin-top: 22px; text-align: center; }

/* A room's door: knock to go in. A room whose door is open says so; the lobby is always open. */
.knock {
  margin-left: auto; padding: 5px 12px; min-height: 32px; border-radius: 999px; border: 1px solid var(--gold);
  background: var(--gold-soft); color: var(--gold); font: 600 13px var(--font); cursor: pointer;
}
.knock:disabled { border-color: var(--line); background: transparent; color: var(--ok); cursor: default; }
.wing:not(.open) .desk-unit .plate { opacity: 0.88; }
@media (prefers-reduced-motion: no-preference) {
  .knock.nudge { animation: knock-nudge 0.5s ease-in-out 2; }
}
@keyframes knock-nudge { 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }

/* What the studio says back: a line at the foot of the screen for a few seconds. */
.visit-note {
  position: fixed; left: 50%; bottom: calc(env(safe-area-inset-bottom, 0px) + 18px); transform: translateX(-50%);
  z-index: 20; max-width: min(92vw, 520px); margin: 0; padding: 10px 16px; border-radius: 12px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text); box-shadow: 0 6px 22px rgba(0, 0, 0, 0.4);
  font-size: 15px; text-align: center;
}

/* The talk and the About sheet (round 6; Chris, 18 Oct, night: the popups "don't swipe down away,
   and they allow scrolling the page behind them ... and it's small window"). On a phone, a sheet
   over almost the whole screen with a grab bar, swiped down by its head to close; on a wide screen,
   a tall window in the middle, the building around it. The page behind never moves while one is
   open (visit.js lockPage). */
.talk-sheet, .about-sheet {
  width: min(100vw, 640px); max-width: 100vw; margin: auto auto 0; padding: 0 16px calc(env(safe-area-inset-bottom, 0px) + 12px);
  /* Above the keyboard when it is up (keyboard.js keeps --kb and --vvh; without it, as before). */
  bottom: var(--kb, 0px);
  border: 1px solid var(--line); border-radius: 18px 18px 0 0; background: var(--panel); color: var(--text);
  display: none; flex-direction: column; gap: 10px; overscroll-behavior: contain;
}
/* Glass (round 7, Chris, 18 Oct): the studio shows through, blurred, behind a sheet; solid where a
   browser cannot blur. */
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .talk-sheet, .about-sheet {
    background: rgba(23, 21, 18, 0.72); border-color: rgba(243, 241, 237, 0.14);
    -webkit-backdrop-filter: blur(18px) saturate(140%); backdrop-filter: blur(18px) saturate(140%);
  }
  @media (prefers-color-scheme: light) {
    .talk-sheet, .about-sheet { background: rgba(255, 255, 255, 0.74); border-color: rgba(29, 39, 49, 0.12); }
  }
}
/* Without a graphics chip the sheets are solid (visit.js softDrawing): their blur made the whole
   moving room draw again under them every frame, and it seemed to stop. */
html.soft-draw .talk-sheet, html.soft-draw .about-sheet { background: var(--panel); -webkit-backdrop-filter: none; backdrop-filter: none; }
.talk-sheet { height: min(92dvh, calc(var(--vvh, 100dvh) - 8px)); max-height: min(92dvh, calc(var(--vvh, 100dvh) - 8px)); }
.about-sheet { max-height: min(86dvh, calc(var(--vvh, 100dvh) - 16px)); overflow-y: auto; }
.talk-sheet[open], .about-sheet[open] { display: flex; }
.talk-sheet::backdrop, .about-sheet::backdrop { background: rgba(0, 0, 0, 0.34); }
@media (min-width: 700px) {
  .talk-sheet, .about-sheet { margin: auto; border-radius: 18px; }
  .talk-sheet { height: min(80vh, 760px, calc(var(--vvh, 100dvh) - 32px)); }
}
html.sheet-open, html.sheet-open body { overflow: hidden; }
/* The page keeps its scrollbar's room whether or not it can scroll, so opening a sheet (which stops
   the page scrolling) never moves it sideways (round 7, Chris, 18 Oct). */
html { scrollbar-gutter: stable; }
.sheet-grab { flex: none; align-self: center; width: 40px; height: 5px; margin: 8px 0 0; border-radius: 3px; background: var(--line); touch-action: none; }
@media (min-width: 700px) { .sheet-grab { display: none; } }
#talk-name:focus, #about-title:focus, #card-name:focus { outline: none; }
/* His head: his medallion, name and role on a wash of his company's colour. */
.talk-sheet { --co: var(--studio); }
.talk-sheet.c-symposio { --co: var(--symposio); } .talk-sheet.c-argo { --co: var(--argo); } .talk-sheet.c-sympan { --co: var(--sympan); }
.talk-sheet.c-engino { --co: var(--engino); } .talk-sheet.c-factories { --co: var(--factories); } .talk-sheet.c-band { --co: var(--band); }
.talk-head {
  flex: none; display: flex; align-items: center; gap: 12px; margin: 0 -16px; padding: 10px 16px 12px; border-bottom: 1px solid var(--line);
  background: linear-gradient(to bottom, color-mix(in srgb, var(--co) 18%, var(--panel)), var(--panel)); touch-action: none;
}
@media (min-width: 700px) { .talk-head { padding-top: 14px; border-radius: 18px 18px 0 0; } }
.talk-head .medallion { width: 64px; height: 64px; }
.talk-who { flex: 1 1 auto; min-width: 0; }
.talk-who h2 { margin: 0; font-size: 20px; letter-spacing: 0; text-transform: none; color: var(--text); }
.talk-sub { margin: 2px 0 0; color: var(--muted); font-size: 14px; }
.talk-ai { flex: none; padding: 3px 7px; border-radius: 6px; border: 1px solid var(--line); color: var(--faint); font: 600 11px/1 var(--mono); letter-spacing: 0.06em; }
/* What he does as he answers plays on his medallion too (visit.js perform). */
@media (prefers-reduced-motion: no-preference) {
  .talk-head .medallion.acting { animation: act-nod 0.9s ease-in-out; }
  .talk-head .medallion.acting-wave { animation: act-wave 1.1s ease-in-out; }
}
@keyframes act-nod { 30% { transform: translateY(-4px); } 60% { transform: translateY(1px); } }
@keyframes act-wave { 20% { transform: rotate(-8deg); } 40% { transform: rotate(7deg); } 60% { transform: rotate(-5deg); } 80% { transform: rotate(3deg); } }
/* The conversation: his lines by his medallion, yours on the right, the newest coming in. */
.talk-lines { flex: 1 1 auto; list-style: none; margin: 0; padding: 4px 0; display: flex; flex-direction: column; gap: 10px; overflow-y: auto; min-height: 80px; overscroll-behavior: contain; }
.talk-line { display: flex; align-items: flex-end; gap: 8px; }
.talk-face { flex: none; width: 28px; height: 28px; border-radius: 50%; overflow: hidden; }
.talk-face svg { display: block; width: 100%; height: 100%; }
.talk-said { max-width: 82%; padding: 9px 13px; border-radius: 16px 16px 16px 4px; background: var(--panel-2); border: 1px solid var(--line); overflow-wrap: anywhere; white-space: pre-wrap; font-size: 15px; line-height: 1.45; }
.talk-line.you { justify-content: flex-end; }
.talk-line.you .talk-said { border-radius: 16px 16px 4px 16px; background: var(--gold-soft); border-color: rgba(229, 175, 79, 0.45); }
.talk-line.note .talk-said { background: transparent; border-style: dashed; color: var(--muted); font-size: 14px; }
@media (prefers-reduced-motion: no-preference) { .talk-line.fresh { animation: line-in 0.28s ease-out both; } }
@keyframes line-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.talk-wait { flex: none; display: flex; align-items: center; gap: 8px; margin: 0; color: var(--faint); font-size: 14px; }
/* Two or three ways to start, until the visitor writes. */
.talk-starters { flex: none; display: flex; flex-wrap: wrap; gap: 6px; }
.talk-starters button { min-height: 36px; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--muted); font: 500 14px var(--font); cursor: pointer; }
.talk-starters button:hover, .talk-starters button:focus-visible { color: var(--text); border-color: var(--muted); }
.talk-form { flex: none; display: flex; gap: 8px; align-items: flex-end; }
.talk-form textarea {
  flex: 1 1 auto; min-width: 0; min-height: 44px; max-height: 140px; resize: none; padding: 10px 14px; border-radius: 22px; border: 1px solid var(--line);
  background: var(--bg); color: var(--text); font: 16px/1.4 var(--font); overflow-y: auto;
}
/* Chris's card (round 6, L): how to reach him. */
.chris-ways { display: flex; flex-wrap: wrap; gap: 8px; }
.chris-ways .go-out, .chris-join .go-out {
  display: inline-flex; align-items: center; min-height: 40px; padding: 8px 14px; border-radius: 12px; border: 1px solid var(--gold);
  background: var(--gold-soft); color: var(--text); font: 600 14px/1.3 var(--font); text-decoration: none;
}
/* Round 8, part Q: asking to join his meeting. */
.chris-join { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 12px; }
.chris-join label { flex: 1 1 100%; font-size: 14px; color: var(--muted); }
.chris-join input { flex: 1 1 180px; min-width: 0; min-height: 44px; padding: 10px 14px; border-radius: 12px; border: 1px solid var(--line); background: var(--bg); color: var(--text); font: 16px var(--font); }
.chris-join .go-out { cursor: pointer; }
.chris-join .about-small { flex: 1 1 100%; margin: 0; }
/* The talk between people (round 7, L): everyone here, two of them on their own, or one with Chris.
   The lines scroll; the form stays at the foot. */
.people-sheet { height: min(86dvh, calc(var(--vvh, 100dvh) - 16px)); overflow: hidden; }
.people-rooms { flex: none; display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.people-rooms::-webkit-scrollbar { display: none; }
.people-room {
  flex: none; min-height: 32px; padding: 4px 12px; border-radius: 999px; border: 1px solid var(--line); background: transparent;
  color: var(--muted); font: 500 13px var(--font); cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
}
.people-room[aria-pressed="true"] { border-color: var(--gold); color: var(--text); background: var(--gold-soft); }
.people-dot { min-width: 17px; height: 17px; padding: 0 4px; border-radius: 999px; background: var(--gold); color: #1b1714; font: 700 10.5px/17px var(--font); text-align: center; }
.people-lines { list-style: none; margin: 0; padding: 0; flex: 1 1 auto; min-height: 120px; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; overscroll-behavior: contain; }
.pl { max-width: 86%; align-self: flex-start; padding: 7px 11px; border-radius: 14px 14px 14px 4px; background: rgba(243, 241, 237, 0.08); }
.pl.mine { align-self: flex-end; border-radius: 14px 14px 4px 14px; background: var(--gold-soft); }
.pl.chris { background: rgba(229, 175, 79, 0.14); border: 1px solid rgba(229, 175, 79, 0.35); }
.pl-head { display: flex; align-items: baseline; gap: 8px; font-size: 12px; color: var(--faint); }
.pl-name { padding: 0; border: 0; background: none; color: var(--text); font: 700 12.5px var(--font); }
button.pl-name { cursor: pointer; text-decoration: underline dotted; text-underline-offset: 3px; }
.pl.chris .pl-name { color: var(--gold); }
.pl-at { font-variant-numeric: tabular-nums; }
.pl-act { margin-left: auto; padding: 0 2px; border: 0; background: none; color: var(--faint); font: 500 11.5px var(--font); cursor: pointer; }
.pl-act:hover, .pl-act:focus-visible { color: var(--text); }
.pl-text { margin: 2px 0 0; font-size: 14.5px; line-height: 1.4; white-space: pre-wrap; overflow-wrap: anywhere; }
.pl-empty { align-self: stretch; padding: 18px 4px; color: var(--muted); font-size: 14px; text-align: center; }
.people-note { margin: 0; color: var(--gold); font-size: 13px; }
.people-why { margin: 0; color: var(--muted); font-size: 13.5px; }
.people-name { display: grid; gap: 8px; }
.people-name p { margin: 0; color: var(--muted); font-size: 13.5px; }
.people-small { margin: 0; }
.link-btn { padding: 0; border: 0; background: none; color: var(--gold); font: inherit; text-decoration: underline; cursor: pointer; }
/* The others in the building: each one's name over his head, and what he says in the lobby. */
.walker.guest[data-label]::after {
  content: attr(data-label); position: absolute; left: 50%; top: -6px; transform: translate(-50%, -100%); padding: 1px 7px; border-radius: 999px;
  background: rgba(13, 12, 11, 0.58); color: rgba(243, 241, 237, 0.92); font: 600 11px/1.4 var(--font); white-space: nowrap; pointer-events: none;
}
.walker.guest[data-guest] { cursor: pointer; }
/* "You" (round 7, K): his own figure, drawn as he picks, and each choice from a fixed list. */
.walker.me { cursor: pointer; }
.you-body { display: grid; gap: 14px; grid-template-columns: 1fr; }
@media (min-width: 560px) { .you-body { grid-template-columns: 150px 1fr; align-items: start; } }
.you-figure { justify-self: center; width: 120px; height: 210px; border-radius: 14px; background: rgba(0, 0, 0, 0.22); display: grid; place-items: center; }
.you-figure svg { width: 100px; height: 190px; }
/* His pet beside him in "You" (part T), small, on the same ground. */
.you-figure { grid-auto-flow: column; align-items: end; width: auto; min-width: 120px; padding: 0 6px; }
.you-figure svg.pet-art { width: 54px; height: 41px; margin: 0 0 6px -18px; }
.you-choices { display: grid; gap: 10px; }
.you-name { font-size: 13px; color: var(--muted); }
#you-name { min-height: 40px; padding: 8px 12px; border-radius: 10px; border: 1px solid var(--line); background: var(--bg); color: var(--text); font: 15px var(--font); }
.you-row { display: grid; gap: 6px; }
.you-row h3 { margin: 0; font-size: 12px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--faint); }
.you-opts { display: flex; flex-wrap: wrap; gap: 6px; }
.you-opts button { min-height: 32px; padding: 4px 11px; border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--muted); font: 500 13px var(--font); cursor: pointer; }
.you-opts button[aria-pressed="true"] { border-color: var(--gold); color: var(--text); background: var(--gold-soft); }
.you-opts .swatch { width: 30px; min-height: 30px; padding: 0; border-radius: 50%; border: 2px solid rgba(255, 255, 255, 0.18); }
.you-opts .swatch[aria-pressed="true"] { border-color: var(--gold); box-shadow: 0 0 0 2px rgba(229, 175, 79, 0.35); }
.you-opts .swatch.own { background: repeating-linear-gradient(45deg, #6b6b6b 0 4px, #8a8a8a 4px 8px); }
.you-sheet #you-title:focus { outline: none; }
/* Someone's card (round 7, B): a tap on him, before walking up to talk. */
.card-sheet { --co: var(--studio); }
.card-sheet.c-symposio { --co: var(--symposio); } .card-sheet.c-argo { --co: var(--argo); } .card-sheet.c-sympan { --co: var(--sympan); }
.card-sheet.c-engino { --co: var(--engino); } .card-sheet.c-factories { --co: var(--factories); } .card-sheet.c-band { --co: var(--band); }
.card-head .medallion { width: 56px; height: 56px; box-shadow: 0 0 0 2px color-mix(in srgb, var(--co) 70%, transparent); }
.card-who { flex: 1 1 auto; min-width: 0; }
.card-who h2 { margin: 0; font-size: 20px; letter-spacing: 0; text-transform: none; color: var(--text); }
.card-ways { display: flex; flex-wrap: wrap; gap: 8px; }
.card-go {
  min-height: 40px; padding: 8px 16px; border-radius: 12px; border: 1px solid var(--gold); background: var(--gold-soft);
  color: var(--text); font: 600 14px/1.3 var(--font); cursor: pointer;
}
.card-go[hidden], #card-how[hidden] { display: none; }
@media (min-width: 700px) { .card-sheet { width: min(100vw, 460px); } }
/* About the studio. */
.about-head { display: flex; align-items: center; gap: 12px; margin-top: 10px; touch-action: none; }
.about-head h2 { flex: 1 1 auto; margin: 0; font-size: 20px; letter-spacing: 0; text-transform: none; color: var(--text); }
.about-sheet p { margin: 0; line-height: 1.5; }
.about-small { color: var(--muted); font-size: 14px; }
.about-count { font: 600 13px var(--mono); color: var(--faint); }

/* The lobby (Chris, 17 Oct, late evening): Arion's question over his head when a visitor comes in,
   his songs and Constans's two ways in under their words, and the player in the corner that plays
   on while the visitor walks round the building. */
.desk-unit[data-crew="band-agent"] { position: relative; }
/* One short line above his head (he sits low in his lounge chair, right of the middle of his
   drawing), its tail pointing down at him: never over his figure or his plate. */
.hype-bubble {
  position: absolute; left: 60%; top: 2%; transform: translateX(-50%); z-index: 2; white-space: nowrap;
  padding: 4px 10px; border-radius: 11px; background: var(--gold); color: var(--on-gold); font: 700 12px/1.3 var(--font);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35); pointer-events: none;
}
.hype-bubble::after {
  content: ''; position: absolute; left: 50%; bottom: -5px; margin-left: -5px;
  border: 5px solid transparent; border-bottom: 0; border-top-color: var(--gold);
}
@media (prefers-reduced-motion: no-preference) { .hype-bubble { animation: hype-in 0.4s ease-out both; } }
@keyframes hype-in { from { opacity: 0; transform: translate(-50%, 6px); } to { opacity: 1; transform: translate(-50%, 0); } }
.talk-extra { display: flex; flex-wrap: wrap; gap: 8px; }
.talk-extra-head { width: 100%; margin: 0; font-size: 13px; color: var(--faint); }
.talk-extra .song, .talk-extra .go-out {
  padding: 8px 12px; min-height: 40px; border-radius: 12px; border: 1px solid var(--gold); background: var(--gold-soft);
  color: var(--text); font: 600 14px/1.3 var(--font); text-align: left; text-decoration: none; cursor: pointer;
}
.talk-extra .go-out { display: inline-flex; align-items: center; }
.music {
  position: fixed; left: max(12px, env(safe-area-inset-left, 0px)); bottom: calc(env(safe-area-inset-bottom, 0px) + 12px); z-index: 15;
  width: min(340px, calc(100vw - 24px)); border-radius: 14px; overflow: hidden; background: var(--panel); border: 1px solid var(--line);
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.45);
}
.music-frame { aspect-ratio: 16 / 9; background: #000; }
.music-frame iframe { display: block; width: 100%; height: 100%; border: 0; }
.music-bar { display: flex; align-items: center; gap: 8px; padding: 6px 8px 6px 12px; }
.music-title { flex: 1 1 auto; min-width: 0; font-size: 13px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.music-out { flex: none; font-size: 12px; color: var(--gold); text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; }
/* While a song plays, the studio's short notes sit above the player. */
body.music-on .visit-note { bottom: calc(env(safe-area-inset-bottom, 0px) + 250px); }
/* On a phone (upright or sideways): the smallest player YouTube allows, 200 x 200 pixels (its terms:
   never smaller, never hidden while it plays), in the corner, its title and Stop on one slim row
   above it. About half the area of the wide one. */
@media (max-width: 600px), (max-height: 500px) {
  .music { display: flex; flex-direction: column; width: max-content; border-radius: 12px; }
  .music-frame { width: 200px; height: 200px; aspect-ratio: auto; }
  .music-bar { order: -1; width: 200px; gap: 6px; padding: 3px 4px 3px 10px; }
  .music-title { font-size: 12px; }
  .music-bar .ghost.small { min-height: 26px; padding: 2px 10px; font-size: 12px; }
  body.music-on .visit-note { bottom: calc(env(safe-area-inset-bottom, 0px) + 248px); }
}

/* A knock answered (stage 5, audit of 18 Oct): the door swings open on its hinge as he reaches it;
   the dark of the doorway shows behind it. With reduced motion it is simply open. */
.wing-door svg { transform-origin: 2px 50%; }
.wing-door.door-open { background: rgba(0, 0, 0, 0.55); border-radius: 2px 2px 0 0; }
.wing-door.door-open svg { transform: perspective(90px) rotateY(-64deg); }
@media (prefers-reduced-motion: no-preference) {
  .wing-door svg { transition: transform 0.7s cubic-bezier(0.3, 0.7, 0.3, 1); }
}

/* The studio in 3D over the page (round 7, part F2): the frame fills the screen under the page's bar, its
   notes and its sheets; the drawn building stays laid out under it, unseen, for the page's own walking. */
.visit3d-frame { position: fixed; inset: 0; z-index: 5; display: block; width: 100%; height: 100%; border: 0; background: #0b0f18; }
/* While the yacht loads (visit-mode.js): a line over the frame, which says so when the device is slow. */
.visit3d-note { position: fixed; left: 16px; right: 16px; bottom: calc(env(safe-area-inset-bottom, 0px) + 40px); z-index: 6; margin: 0; text-align: center; color: #dfe6f3; font-size: 15px; line-height: 1.4; pointer-events: none; }
html.v3d .visit-main, html.v3d .visit-foot { visibility: hidden; }
/* Round 8, part E: the About sheet's words for the drawn building, or for the yacht while the new world shows. */
html.v3d-world .only-drawn, html:not(.v3d-world) .only-world { display: none; }
/* Her side in 2D (yacht2d.js): its own words, no walking hint. */
html:not(.y2d-on) .only-flat { display: none; }
html.y2d-on .only-drawn, html.y2d-on .only-world, html.y2d-on .visit-hint { display: none; }
html.v3d #back-to-me { display: none !important; }
.about-install { margin: 10px 0; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); }
.about-install p { margin: 0 0 8px; }
