/* The gallery: a three-dimensional white room, built from planes.
   gallery.js places the walls, floor and ceiling in real-world proportions
   (1 cm = 6 px of world space) and moves a camera through them. These styles
   are the materials: paint, vinyl lettering, frames, labels, concrete, light. */

@font-face {
  font-family: "Schibsted Grotesk";
  src: url("fonts/schibsted-grotesk.woff2") format("woff2");
  font-weight: 400 900; font-display: swap;
}
@font-face {
  font-family: "Grotesk Fallback";
  src: local("Arial"), local("Liberation Sans"), local("Arimo"), local("Helvetica");
  size-adjust: 102.46%; ascent-override: 95.65%; descent-override: 25.38%; line-gap-override: 0%;
}

:root {
  color-scheme: light;
  --ink: oklch(22% 0.01 70);
  --ink-2: oklch(40% 0.01 70);
  --sans: "Schibsted Grotesk", "Grotesk Fallback", system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --out: cubic-bezier(.2, .8, .2, 1);
}
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { background: oklch(95% .003 80); -webkit-text-size-adjust: 100%; }
body { font-family: var(--sans); color: var(--ink); font-size: 1rem; line-height: 1.5; }
img { display: block; max-width: 100%; }
a { color: inherit; text-underline-offset: .2em; text-decoration-thickness: 1px; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }

.g-head {
  position: fixed; inset: 0 0 auto 0; z-index: 20;
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 18px clamp(20px, 4vw, 48px); font-size: .9375rem; pointer-events: none;
}
.g-head a { pointer-events: auto; text-decoration: none; padding: 6px 0; }
.g-head a:hover { text-decoration: underline; }
.g-name { font-weight: 600; }
.g-nav { display: flex; gap: 22px; }
.g-prints { color: var(--ink-2); }
.g-prints:hover { color: var(--ink); text-decoration: underline; }
.g-back { color: var(--ink-2); }
.g-back:hover { color: var(--ink); text-decoration: underline; }

/* ---------- the room ---------- */
.hall { position: relative; }
.stage {
  position: sticky; top: 0; height: 100svh; overflow: hidden;
  background: oklch(93% .003 80);
}
.cam { position: absolute; left: 50%; top: 50%; width: 0; height: 0; transform-style: preserve-3d; }
.cam.moving { transition: transform 1.1s cubic-bezier(.45, .05, .2, 1); }
.plane { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.plane, .plane * { backface-visibility: visible; }
.plane { pointer-events: none; }
.plane .work, .plane .wall-text { pointer-events: auto; }
.close-ui, .closeup, .g-head { transform: translateZ(0); }

/* white paint, a touch warmer and brighter just under the lights */
.wall.side { background: linear-gradient(oklch(97.5% .003 85), oklch(95.8% .003 82) 70%, oklch(92.5% .004 80)); }
.wall {
  background:
    linear-gradient(oklch(99% .004 90), oklch(97.4% .003 85) 18%, oklch(96.6% .003 82) 70%, oklch(93.5% .004 80));
}
/* the pipe that runs along the top of the wall */
.pipe {
  position: absolute; left: 0; right: 0; top: 18px; height: 22px;
  background: linear-gradient(oklch(88% .003 80), oklch(99% .003 90) 30%, oklch(94% .003 85) 60%, oklch(80% .004 80));
  box-shadow: 0 10px 14px -8px oklch(40% .01 70 / .25);
}
.endwall { background: linear-gradient(90deg, oklch(92.5% .004 80), oklch(95% .003 85) 70%, oklch(96.5% .003 85)); }

/* the ceiling: white beams and long strip lights */
.ceiling {
  background:
    repeating-linear-gradient(0deg, oklch(86% .004 80) 0 3px, oklch(95% .003 85) 3px 40px, oklch(89% .004 80) 40px 44px, oklch(97% .003 85) 44px 300px),
    oklch(96% .003 85);
}
.tube { position: absolute; width: 24px; background: repeating-linear-gradient(oklch(100% 0 0) 0 280px, transparent 280px 360px); box-shadow: 0 0 30px 8px oklch(100% 0 0 / .6); border-radius: 6px; }

/* polished concrete: pale, a little see-through so the works reflect in it */
.floor {
  background: linear-gradient(oklch(84% .003 80 / .9), oklch(85.5% .003 82 / .92) 35%, oklch(87% .003 85 / .95));
}
.sheen { position: absolute; width: 80px; background: radial-gradient(closest-side, oklch(100% 0 0 / .55), transparent); }
/* reflections: the work, faint and foreshortened, against the foot of its wall */
.refl { position: absolute; background-size: cover; opacity: .14; pointer-events: none; }
.refl.back { background-position: bottom; -webkit-mask-image: linear-gradient(#000, transparent); mask-image: linear-gradient(#000, transparent); }
.refl.left { -webkit-mask-image: linear-gradient(90deg, #000, transparent); mask-image: linear-gradient(90deg, #000, transparent); }
.refl.right { -webkit-mask-image: linear-gradient(-90deg, #000, transparent); mask-image: linear-gradient(-90deg, #000, transparent); }

/* ---------- on the wall ---------- */
.wall > * { position: absolute; }
.hang { display: contents; }
.wall-text, .tag { transform-origin: 0 0; }

/* vinyl lettering, applied straight to the paint */
.wall-text { color: oklch(20% .01 70); cursor: zoom-in; }
.wall-text .artist { font-size: 22px; font-weight: 500; }
.wall-text h1, .wall-text h2 { font-size: 78px; font-weight: 500; letter-spacing: -.03em; line-height: 1; margin-top: 6px; }
.wall-text.small-text h2 { font-size: 58px; }
.wall-text .dates { margin-top: 10px; font-size: 22px; color: var(--ink-2); }
.statement { margin-top: 34px; display: grid; gap: 18px; font-size: 20px; line-height: 1.55; }
.statement .mail { font-size: 22px; }
.exit { display: inline-block; margin-top: 30px; font-size: 20px; }

/* framed works: thin black wood, a white mat */
.work { position: absolute; }
.frame {
  position: absolute; left: 0; top: 0; padding: var(--mat, 42px);
  background: oklch(98.8% .003 90); border: var(--mould, 8px) solid oklch(18% .006 60);
  box-shadow: 4px 8px 10px oklch(30% .01 70 / .14), 14px 34px 50px -16px oklch(30% .01 70 / .3);
  cursor: zoom-in; font: inherit; color: inherit;
}
.frame img { width: 100%; height: 100%; object-fit: cover; }
.frame:focus-visible, .wall-text:focus-visible { outline: 2px solid var(--ink); outline-offset: 6px; }
.wall .frame { box-shadow: 1px 3px 4px oklch(30% .01 70 / .16), 5px 12px 18px -6px oklch(30% .01 70 / .3); }

/* the label: a small white card beside the work */
.tag {
  position: absolute; width: 132px; padding: 10px 11px 11px;
  display: flex; flex-direction: column; gap: 1px;
  font-size: 13px; line-height: 1.38; color: var(--ink-2);
  background: oklch(99.4% .002 90); box-shadow: 0 1px 2px oklch(30% .01 70 / .16);
  cursor: zoom-in;
}
.tag .who { color: var(--ink); font-weight: 600; }
.tag .what { color: var(--ink); margin-bottom: 4px; }
.tag .note { margin-top: 5px; color: var(--ink); }
.tag a { margin-top: 7px; color: var(--ink); align-self: flex-start; }
/* links on the wall answer once you have stepped up to them */
.wall .tag a, .wall .wall-text a { pointer-events: none; }

/* ---------- close up ---------- */
.close-ui {
  position: absolute; z-index: 10; left: 0; right: 0; bottom: max(18px, env(safe-area-inset-bottom));
  display: flex; justify-content: center; gap: 10px; pointer-events: none;
  opacity: 0; transform: translateY(8px); transition: opacity .35s var(--out), transform .35s var(--out);
}
html.zoomed .close-ui { opacity: 1; transform: none; pointer-events: auto; }
.close-ui button {
  font: inherit; font-size: .875rem; color: var(--ink); cursor: pointer; min-height: 40px; padding: 8px 16px;
  background: oklch(99% .002 90 / .94); border: 1px solid oklch(70% .004 80); border-radius: 2px;
}
.close-ui button:hover { border-color: var(--ink); }
.close-ui button:disabled { opacity: .4; cursor: default; }
.walk-ui { display: flex; gap: 10px; }

.g-hint {
  position: absolute; z-index: 10; left: 0; right: 0; bottom: max(20px, env(safe-area-inset-bottom));
  text-align: center; font-size: .8125rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2);
  transition: opacity .4s var(--out); pointer-events: none;
}
html.zoomed .g-hint { opacity: 0; }

/* ---------- viewer ---------- */
.viewer { padding: 0; border: 0; max-width: none; max-height: none; width: 100%; height: 100%; background: oklch(14% .005 70); color: oklch(95% .005 80); font-family: var(--sans); }
.viewer::backdrop { background: oklch(14% .005 70); }
.viewer[open] { display: grid; grid-template-rows: 1fr auto; }
.stage-v { display: grid; place-items: center; padding: 32px clamp(20px, 4vw, 48px) 0; min-height: 0; }
.viewer img { max-width: 100%; max-height: calc(100svh - 120px); width: auto; height: auto; object-fit: contain; transition: opacity .3s var(--out); }
.viewer img.loading { opacity: .3; }
.viewer .bar { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 20px clamp(20px, 4vw, 48px) max(20px, env(safe-area-inset-bottom)); font-size: .9375rem; }
.viewer .bar b { font-weight: 600; }
.viewer .ctl { display: flex; gap: 8px; }
.viewer button.v { font: inherit; color: inherit; background: transparent; border: 1px solid oklch(40% .005 70); padding: 9px 16px; min-height: 44px; cursor: pointer; border-radius: 2px; }
.viewer button.v:hover { border-color: oklch(70% .005 70); }
@media (max-width: 820px) {
  .viewer .bar { flex-direction: column; align-items: stretch; }
  .viewer .ctl .v { flex: 1; }
}

/* without JavaScript the room cannot be built: show the wall as a plain page */
html:not(.js) .stage { position: static; height: auto; overflow: visible; }
html:not(.js) .cam { position: static; transform: none; width: auto; height: auto; }
html:not(.js) .plane:not(.wall) { display: none; }
html:not(.js) .wall { position: static; padding: 90px 24px; display: grid; gap: 60px; background: none; }
html:not(.js) .wall > * { position: static; }
html:not(.js) .frame { position: static; max-width: 640px; }

/* ---------- arriving: out of the bookcase's dark glass into gallery light ---------- */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation: none; }
.veil { position: fixed; inset: 0; z-index: 50; pointer-events: none; opacity: 0; }
.veil.dark { background: oklch(4% .01 45); }
.veil.light { background: oklch(99% .008 85); }
@media (prefers-reduced-motion: no-preference) {
  html.arriving .veil.dark { animation: lift .45s cubic-bezier(.3, 0, .2, 1) both; }
  html.arriving .veil.light { animation: lift 1.2s cubic-bezier(.25, .6, .2, 1) .12s both; }
  html.leaving .veil.dark { transition: opacity .45s ease-in; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .cam.moving { transition: none; } }
@keyframes lift { from { opacity: 1; } to { opacity: 0; } }
@media (forced-colors: active) { .frame { border-color: CanvasText; } .tag { border: 1px solid CanvasText; } }

/* ---------- the close-up: flat, sharp, at the screen's own resolution ---------- */
.closeup {
  position: absolute; inset: 0; z-index: 8; display: grid; place-items: center;
  padding: 72px clamp(20px, 5vw, 64px) 96px;
  background: linear-gradient(oklch(98% .003 88), oklch(95.5% .003 82));
  opacity: 0; pointer-events: none; transition: opacity .45s var(--out);
}
html.close-open .closeup { opacity: 1; pointer-events: auto; }
.cu-inner { display: grid; place-items: center; width: 100%; height: 100%; min-height: 0; }
.cu-work { display: flex; align-items: flex-end; gap: clamp(20px, 3vw, 44px); max-height: 100%; max-width: 100%; }
.cu-frame {
  display: block; padding: clamp(14px, 2.6vh, 34px); cursor: zoom-in; font: inherit;
  background: oklch(98.8% .003 90); border: clamp(4px, .7vh, 8px) solid oklch(18% .006 60);
  box-shadow: 2px 6px 10px oklch(30% .01 70 / .16), 12px 30px 46px -16px oklch(30% .01 70 / .32);
}
.cu-frame img { display: block; max-height: calc(100svh - 260px); max-width: min(62vw, 900px); width: auto; height: auto; }
.cu-tag {
  flex: none; width: 15rem; padding: 14px 16px 16px; margin-bottom: 18%;
  display: flex; flex-direction: column; gap: 2px; font-size: .9375rem; line-height: 1.45; color: var(--ink-2);
  background: oklch(99.4% .002 90); box-shadow: 0 1px 3px oklch(30% .01 70 / .16);
}
.cu-tag .who { color: var(--ink); font-weight: 600; }
.cu-tag .what { color: var(--ink); margin-bottom: 6px; }
.cu-tag .note { margin-top: 8px; color: var(--ink); }
.cu-tag a { margin-top: 10px; color: var(--ink); align-self: flex-start; }
.cu-text { width: min(40rem, 100%); max-height: 100%; overflow: auto; }
.cu-text .artist { font-size: 1rem; font-weight: 500; }
.cu-text h1, .cu-text h2 { font-size: clamp(2.5rem, 2rem + 2vw, 3.75rem); font-weight: 500; letter-spacing: -.03em; line-height: 1; margin-top: 6px; }
.cu-text .dates { margin-top: 8px; color: var(--ink-2); }
.cu-text .statement { margin-top: 24px; gap: 14px; font-size: 1.0625rem; line-height: 1.6; }
.cu-text .exit { display: inline-block; margin-top: 20px; }
@media (max-width: 820px) {
  .closeup { padding: 76px 20px 92px; }
  .cu-work { flex-direction: column; align-items: stretch; }
  .cu-frame img { max-width: 100%; max-height: 54svh; margin: 0 auto; }
  .cu-tag { width: auto; margin: 0; }
}

/* ---------- the set, and the phone close-up (2026-10-07) ---------- */
.note-text[hidden] { display: none; }
.cu-set { display: grid; grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); gap: clamp(28px, 4vw, 64px); align-items: center; width: min(76rem, 100%); max-height: 100%; }
.cu-set .cu-text { width: auto; }
.cu-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(10px, 1.4vw, 18px); align-items: center; }
.cu-thumb {
  display: block; padding: clamp(6px, 1vh, 12px); cursor: zoom-in; font: inherit;
  background: oklch(98.8% .003 90); border: 3px solid oklch(18% .006 60);
  box-shadow: 1px 4px 8px oklch(30% .01 70 / .16);
}
.cu-thumb img { display: block; width: 100%; height: auto; }
.swipe-hint { display: none; }
@media (max-width: 820px) {
  .stage { height: 100dvh; }
  .closeup { place-items: start center; overflow-y: auto; padding: 68px 18px calc(96px + env(safe-area-inset-bottom)); }
  .cu-inner { height: auto; }
  .cu-work { gap: 14px; }
  .cu-frame { padding: 12px; border-width: 4px; }
  .cu-frame img { max-height: calc(100dvh - 330px); }
  .cu-tag { padding: 10px 12px 12px; font-size: .875rem; }
  .cu-tag a { margin-top: 6px; }
  .cu-set { grid-template-columns: 1fr; gap: 20px; }
  .cu-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cu-text .statement { font-size: 1rem; }
  /* on a phone you swipe between works; only "Step back" remains */
  .close-ui { flex-direction: column; align-items: center; gap: 6px; bottom: max(14px, env(safe-area-inset-bottom)); }
  .walk-ui { display: none; }
  .swipe-hint { display: block; margin: 0; font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
  .close-ui button { box-shadow: 0 2px 10px oklch(30% .01 70 / .14); }
}
@media (prefers-reduced-motion: no-preference) {
  html.close-open .cu-inner > * { animation: cu-in .4s var(--out) both; }
}
@keyframes cu-in { from { opacity: 0; transform: translateY(6px); } }
/* the set: five frames at one height, wrapping evenly */
.cu-grid { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: clamp(10px, 1.4vw, 18px); }
.cu-thumb img { width: auto; height: clamp(110px, 24vh, 240px); }
@media (max-width: 820px) { .cu-thumb img { height: clamp(90px, 15dvh, 160px); } }
/* phone: the controls sit on their own band, never over the work or its label */
@media (max-width: 820px) {
  .closeup { padding-bottom: calc(132px + env(safe-area-inset-bottom)); }
  .cu-frame img { max-height: calc(100dvh - 420px); }
  .close-ui {
    left: 0; right: 0; bottom: 0; padding: 14px 0 max(14px, env(safe-area-inset-bottom));
    background: linear-gradient(oklch(96% .003 82 / 0), oklch(96% .003 82) 26%);
  }
}

/* the room handles its own gestures: drag to look, pinch to walk in */
.stage { touch-action: none; -webkit-user-select: none; user-select: none; }
html.close-open .stage { touch-action: none; }
@media (max-width: 820px) { .g-hint { font-size: .75rem; } }
.hint-phone { display: none; }
@media (max-width: 820px) { .hint-desk { display: none; } .hint-phone { display: inline; } }
.g-hint { line-height: 1.7; }

/* ---------- the close-up in the room (2026-10-07) ---------- */
.closeup.room { background: none; padding: 0; display: block; overflow: visible; }
.closeup.room .cu-inner { position: absolute; inset: 0; display: block; width: auto; height: auto; }
.ov { pointer-events: auto; }
.closeup.room .ov.wall-text { color: oklch(20% .01 70); cursor: default; }
.closeup.room .ov.frame { cursor: zoom-in; }
.closeup.room .ov.tag a, .closeup.room .ov a { pointer-events: auto; }
.work.lifted .tag { visibility: hidden; }
.closeup.flat { background: linear-gradient(oklch(98% .003 88), oklch(95.5% .003 82)); }
@media (prefers-reduced-motion: no-preference) {
  html.close-open .closeup.room .cu-inner > * { animation: ov-in .3s ease-out both; }
}
@keyframes ov-in { from { opacity: 0; } }
/* look around with the mouse */
@media (hover: hover) and (pointer: fine) { .stage { cursor: grab; } .stage.grabbing { cursor: grabbing; } .stage .frame, .stage .wall-text { cursor: zoom-in; } }
@media (max-width: 820px) { .closeup.room { overflow: visible; } }
html:not(.close-open) .closeup, html:not(.close-open) .closeup * { pointer-events: none !important; }

/* ---------- old wood underfoot, timber overhead (2026-10-07) ---------- */
/* reclaimed planks (Keith Misner, Unsplash), satin with age, darker toward the walls */
.floor {
  background:
    radial-gradient(70% 60% at 50% 55%, oklch(100% 0 0 / .07), transparent 70%),
    linear-gradient(oklch(14% .02 50 / .35), oklch(14% .02 50 / .12) 30%, oklch(14% .02 50 / .28)),
    url("photo/floor-old.jpg") 0 0 / 420px auto repeat,
    oklch(30% .03 50);
}
.floor .sheen { background: radial-gradient(closest-side, oklch(96% .02 80 / .22), transparent); mix-blend-mode: screen; }
.floor .refl { opacity: .2; mix-blend-mode: screen; }
.wall::after { height: 1.2%; background: linear-gradient(oklch(60% .01 70 / 0), oklch(30% .02 60 / .5)); }
/* the ceiling between the beams: white boards in shadow */
.ceiling { transform-style: preserve-3d; background: linear-gradient(90deg, oklch(90% .004 80), oklch(93% .004 82) 50%, oklch(90% .004 80)); }
/* timber (Andrey Haimin, Unsplash): the faces you see are lit from below */
.beam { position: absolute; background: url("photo/beam.jpg") 0 0 / 560px auto repeat; backface-visibility: visible; transform-origin: 0 0; }
.beam-bottom { box-shadow: inset 0 0 0 9999px oklch(100% 0 0 / .04); }
.beam-front, .beam-back { box-shadow: inset 0 0 0 9999px oklch(10% .02 50 / .28); }
.tube { z-index: 2; }
/* the hint sits on the dark floor now */
.g-hint { color: oklch(94% .01 80); text-shadow: 0 1px 2px oklch(10% .02 50 / .8), 0 0 12px oklch(10% .02 50 / .6); }
.floor { background-size: auto, auto, 640px auto, auto; }

/* ---------- light fixtures between the beams ---------- */
.fixture, .fx-cable { position: absolute; transform-origin: 0 0; backface-visibility: visible; }
.fx-glow { background: oklch(99.5% .01 95); box-shadow: 0 0 40px 14px oklch(100% .01 95 / .55), 0 0 6px 2px oklch(100% 0 0 / .9); border-radius: 2px; }
.fx-side { background: linear-gradient(oklch(72% .005 250), oklch(84% .004 250) 60%, oklch(66% .005 250)); }
.fx-cable { background: oklch(40% .005 250 / .7); }
.floor .sheen { width: auto; background: radial-gradient(50% 50% at 50% 50%, oklch(96% .02 80 / .2), transparent 75%); }

/* ---------- the vault: white-painted slopes and a gable over the back wall ---------- */
.ceiling { background: none !important; }
.vault { backface-visibility: visible; }
.vault-left  { background: linear-gradient(90deg, oklch(90% .004 80), oklch(95.5% .003 85) 85%, oklch(97% .003 88)); }
.vault-right { background: linear-gradient(90deg, oklch(93% .004 82), oklch(97.5% .003 88) 85%, oklch(98.5% .003 90)); }
.gable { background: linear-gradient(oklch(96.5% .003 85), oklch(94% .004 82)); clip-path: polygon(0 100%, 50% 0, 100% 100%); }
.vault-left  { background: linear-gradient(90deg, oklch(84% .005 80), oklch(90% .004 82) 70%, oklch(93% .004 85)) !important; }
.vault-right { background: linear-gradient(90deg, oklch(96% .003 85), oklch(98.5% .003 90) 80%, oklch(99% .003 92)) !important; }
.gable { background: linear-gradient(oklch(92% .004 82), oklch(95% .004 84)) !important; }
.beam.ridge, .beam.ridge-side { position: absolute; background: url("photo/beam.jpg") 0 0 / 560px auto repeat; }
.beam.ridge-side { box-shadow: inset 0 0 0 9999px oklch(10% .02 50 / .3); }

/* no pipe: the beams sit on timber wall plates */
.pipe { display: none; }
.wallplate { position: absolute; background: url("photo/beam.jpg") 0 40% / 560px auto repeat; box-shadow: inset 0 -3px 0 oklch(15% .02 50 / .35), 0 6px 10px -4px oklch(20% .02 50 / .35); }
.cu-tag .what, .tag .what { margin-bottom: 4px; }

/* ---------- quiet links, and images that do not offer themselves for saving ---------- */
.g-insta { color: var(--ink-2); }
.g-insta:hover { color: var(--ink); }
.tag .note a, .cu-tag .note a { color: inherit; }
img { -webkit-user-drag: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.frame img, .cu-frame img, .ov img, .cu-thumb img, .viewer img { pointer-events: none; }
.refl { pointer-events: none; }
@media (max-width: 420px) { .g-nav { gap: 16px; } }

/* labels are lettering on the wall: no card, no shadow */
.tag, .cu-tag, .ov.tag { background: none !important; box-shadow: none !important; padding: 0 !important; }
.ph-tag { position: absolute; display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center;
  font-size: 14px; line-height: 1.4; color: var(--ink-2); pointer-events: auto; }
.ph-tag .what { color: var(--ink); font-size: 15px; margin-bottom: 2px; }
.ph-tag .note { margin-top: 6px; color: var(--ink); max-width: 30ch; }
.ph-tag a { color: inherit; }

/* Sharp wall lettering replaces the projected copy, in the same position. */
.wall-text.lifted, .work.lifted .frame { visibility: hidden; }

/* Projected wall targets must not scroll the camera stage when they receive focus. */
.stage { overflow: clip; }

/* Zoom moves the gallery camera; the browser viewport remains fixed during a pinch. */
.closeup.room { touch-action: none; }
.zoom-ui { display: flex; gap: 8px; }
.zoom-ui button { min-width: 44px; min-height: 44px; }

/* The heavy 3D scene does not need compositing while its photograph fills the viewer. */
html.viewer-open .hall, html.viewer-open .hall * { visibility: hidden !important; }

/* The camera stays live everywhere in the room; there is no inspection screen. */
.room-zoom { position:absolute; z-index:12; right:20px; bottom:max(18px,env(safe-area-inset-bottom)); display:flex; gap:8px; }
.room-zoom button { font:inherit; color:var(--ink); min-width:44px; min-height:44px; border:1px solid oklch(70% .004 80); border-radius:2px; background:oklch(99% .002 90 / .94); cursor:pointer; }
@media (max-width:820px) { .g-hint { bottom:74px; } }
.print-info { margin:auto; padding:32px; border:0; width:min(40rem,calc(100% - 40px)); max-height:calc(100dvh - 80px); background:oklch(97% .003 85); color:var(--ink); font:inherit; }
.print-info::backdrop { background:oklch(97% .003 85 / .94); }
.print-info h2 { font-size:2.5rem; font-weight:500; }
.print-info .statement { font-size:1rem; margin-top:24px; }
.print-info button { font:inherit; padding:8px 16px; min-height:44px; margin-top:24px; background:none; border:1px solid var(--ink-2); cursor:pointer; }

/* Links on the actual wall remain usable as the camera moves closer. */
.wall .tag a, .wall .wall-text a { pointer-events: auto; }

/* Calm, legible room controls on either wall or floor. */
.g-hint { left:50%; right:auto; transform:translateX(-50%); bottom:max(19px,env(safe-area-inset-bottom)); width:max-content; max-width:calc(100% - 140px); padding:6px 12px; border-radius:20px; background:oklch(98% .003 80 / .92); color:var(--ink-2); text-shadow:none; text-transform:none; letter-spacing:.015em; font-size:.75rem; line-height:1.5; }
.room-zoom { gap:0; right:16px; bottom:max(13px,env(safe-area-inset-bottom)); border-radius:24px; background:oklch(98% .003 80 / .92); }
.room-zoom button { width:44px; height:44px; min-width:44px; min-height:44px; border:0; border-radius:50%; background:transparent; font-size:1.15rem; }
.room-zoom button:hover { background:oklch(90% .005 80 / .7); }
@media(max-width:820px) { .g-hint { left:16px; transform:none; max-width:calc(100% - 120px); font-size:.6875rem; padding:6px 9px; } }
/* Architectural edges keep unoccupied walls recognisable as part of the room. */
.wall::after { content:""; position:absolute; left:0; right:0; bottom:0; height:10px; background:linear-gradient(oklch(90% .004 80),oklch(95% .003 80) 25%,oklch(88% .004 80)); box-shadow:0 -1px 3px oklch(30% .01 70 / .08); }
.wall.front { background:linear-gradient(90deg,oklch(92% .005 80),oklch(96% .003 85) 55%,oklch(94% .004 82)); }
