/* ============================================================================
   room.css: the dark room every store page shares (docs/store-room-spec.md 1.1, 3).

   Loaded on every /s/<slug> page, by room-core.js ensureRoom(), after the storefront's own <style>
   and BEFORE store-room.css. It holds the room itself: the ground, the type, the cover, the chapters,
   the wall, the about grid, the reviews, the bar, the footer and the viewer. Since the merge
   (docs/merge-plan.md D5) there is one kind of store; the parts that were a studio's (the slides
   cover, the music hero, the tracks, the packages) are styled in store-room.css. The store-facing
   additions are at the end.

   THE ROOM. A room is a warm near black derived from the KILN ink, not the navy enclosure:
   photographs are graded on neutral black, and navy tints them. The palette.css lesson applies here
   too: a custom property that contains var() is substituted where it is DECLARED, so overriding
   --dark-1 on body would change nothing. The room therefore restates the enclosure tokens themselves
   on body, and every .enclosure, .plate.dark and .glass.dark follows. Sheets, dialogs and toasts keep
   their light paper, because they read --paper and --card, which the room never touches.

   The room steps aside while the owner is in ניהול (body.mg-on): the desk is a light product.

   Measured contrast (WCAG relative luminance):
     --room-tx  #F6F1EA   17.39 on room-0, 16.35 on room-1, 14.76 on room-2
     --room-tx2 72%        9.17 / 8.81 / 8.22   secondary text
     --room-tx3 56%        5.84 / 5.78 / 5.50   captions, timecodes
     --accent-bright       7.99 / 7.51 / 6.78   links, kickers, the played line, focus
     --pri fill, white label 5.05              gold buttons only, never text on the room

   No rule here bleeds to the viewport width (the owner rail pads #app, so a width in vw units slides
   under it), and no rule this file adds sets a Hebrew label in the mono face or letterspaces it
   (tests/room-core.test.mjs).
   ========================================================================== */

:root {
  --st-ease-out: cubic-bezier(.16,1,.3,1);
  --st-ease-slide: cubic-bezier(.2,.8,.2,1);
}

body[data-room="dark"]:not(.mg-on) {
  --room-0: #0D0C0B;
  --room-1: #161412;
  --room-2: #211E1B;
  --room-tx: #F6F1EA;
  --room-tx2: rgba(246,241,234,.72);
  --room-tx3: rgba(246,241,234,.56);
  --room-line: rgba(246,241,234,.14);
  --enc: var(--room-0); --enc-2: var(--room-1); --enc-3: var(--room-2);
  --dark-1-rgb: 13,12,11; --dark-0-rgb: 8,7,6;
  --on-enc: var(--room-tx); --on-enc-soft: var(--room-tx2); --on-enc-steel: var(--room-tx3);
  --enc-line: var(--room-line); --enc-line-soft: rgba(246,241,234,.08); --enc-grid: transparent;
  background: var(--room-0);
  color: var(--room-tx);
}

/* graph paper belongs to the workshop; a photo page does not sit on it */
body[data-room="dark"] #app .enclosure { background: var(--room-0); }
body[data-room="dark"] #app .plate::after { display: none; }

/* ---------------------------------------------------------------- shared structure */
.st-inner { max-width: 1120px; margin-inline: auto; padding-inline: var(--wrap-x); }
.st-inner-wide { max-width: 1440px; }
@media (min-width: 900px) { .st-inner { padding-inline: 32px; } }
.st-sec { padding-block: clamp(56px, 10vw, 128px); }
.st-sec + .st-sec { border-block-start: 1px solid rgba(246,241,234,.06); }
.st-head { max-width: 720px; }
.st-head-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px 24px; flex-wrap: wrap; max-width: none; margin-bottom: 26px; }
.st-head-side { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
#app .st-room .kicker, #app .st-foot .kicker { font-family: var(--font-body); font-weight: 500; letter-spacing: normal; color: var(--accent-bright); }
.st-h2 { margin-top: 12px; font-family: var(--st-display); font-weight: 300; font-size: clamp(30px, 5vw, 52px); line-height: 1.08; color: var(--room-tx); text-wrap: balance; }
.st-room-music .st-h2 { font-weight: 400; font-size: clamp(30px, 5.2vw, 48px); line-height: 1.1; }
.st-lead { margin-top: 14px; max-width: 38em; color: var(--room-tx2); font-size: 1.0625rem; line-height: 1.7; }
.st-count { color: var(--room-tx3); }
#app .st-room .mono-label { letter-spacing: normal; }
@media (pointer: coarse) { .st-fine { display: none; } }
.st-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 2px; color: var(--accent-bright); font-weight: 500; text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px; }
.st-link:hover { text-decoration-thickness: 2px; }
.st-room :focus-visible { outline-color: var(--accent-bright); }

/* identity, shared by both rooms */
.st-id { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; min-width: 0; }
.st-badges { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.st-name { font-family: var(--st-display); font-weight: 300; font-size: clamp(40px, 11vw, 96px); line-height: 1.02; letter-spacing: -.01em; color: var(--room-tx); text-wrap: balance; overflow-wrap: anywhere; }
.st-room-music .st-name { font-weight: 400; font-size: clamp(40px, 10vw, 84px); letter-spacing: 0; }
.st-name .name-tick { display: inline-flex; vertical-align: .32em; margin-inline-start: 12px; }
.st-tagline { max-width: 34em; color: var(--room-tx2); font-size: clamp(17px, 2.2vw, 20px); line-height: 1.55; }
.st-proof { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 4px; color: var(--room-tx2); font-size: .9375rem; }
.st-proof-t { display: inline-flex; align-items: center; gap: 6px; }
.st-proof .rating-line { display: inline-flex; align-items: center; gap: 6px; color: var(--room-tx); }
.st-proof .rating-line .muted { color: var(--room-tx2); }
.st-proof .stars svg:not(.on) { fill: rgba(246,241,234,.2); }
.st-proof .stars svg.on { fill: #B8800C; }
.st-proof .money { font-weight: 600; color: var(--room-tx); }
.st-sep { font-style: normal; color: var(--room-tx3); }
.st-ctas { display: flex; flex-wrap: wrap; gap: 10px; }
#app .st-icon-btn { width: 56px; padding-inline: 0; flex: none; }

/* ---------------------------------------------------------------- photography: the cover */
.st-cover { isolation: isolate; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end;
  min-height: 88svh; padding-block: calc(var(--bar-h, 64px) + 22px) 30px; }
@media (min-width: 900px) { .st-cover { min-height: min(100svh, 920px); padding-block-end: 52px; } }
#hero.st-cover .hero-bg { position: absolute; inset: 0; z-index: -1; overflow: hidden; background: var(--room-0); }
#hero.st-cover .hero-bg img.st-frame { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 1400ms ease-in-out; }
#hero.st-cover .hero-bg img.st-frame.is-on { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  #hero.st-cover[data-plan="slides"] .st-frame.is-on { animation: st-drift 7400ms linear both; }
}
@keyframes st-drift { from { transform: scale(1.06); } to { transform: none; } }
#hero.st-cover.is-paused .st-frame.is-on, #hero.st-cover.is-paused .st-dwell i { animation-play-state: paused; }
/* Measured against the worst case, a white photograph. The bar's labels sit in the first 56px over at
   least 62% black (5.51:1). On a phone the words climb higher up the cover, so the bottom scrim starts
   earlier there; from 900px the identity sits low and the spec's lighter stops hold. */
#hero.st-cover .hero-bg::before { content: ""; position: absolute; inset-inline: 0; inset-block-start: 0; height: 140px; z-index: 1;
  background: linear-gradient(180deg, rgba(13,12,11,.66) 0, rgba(13,12,11,.62) 56px, rgba(13,12,11,0) 140px); }
#hero.st-cover .hero-bg::after { content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg, transparent 16%, rgba(13,12,11,.62) 42%, rgba(13,12,11,.92) 100%); background-size: auto; }
@media (min-width: 900px) {
  #hero.st-cover .hero-bg::after { background: linear-gradient(180deg, transparent 38%, rgba(13,12,11,.62) 66%, rgba(13,12,11,.92) 100%); }
}
.st-cover-inner { width: 100%; }
.st-cover #notices { margin-bottom: 18px; }
.st-cover-foot { display: grid; gap: 22px; }
@media (min-width: 1040px) { .st-cover-foot { grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 48px; } }
.st-cover .st-name { text-shadow: 0 2px 30px rgba(0,0,0,.35); }
.st-pause { position: absolute; z-index: 3; inset-block-start: calc(var(--bar-h, 64px) + 12px); inset-inline-end: var(--wrap-x);
  width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(13,12,11,.72); color: var(--room-tx); border: 1px solid var(--room-line);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.st-pause svg { width: 18px; height: 18px; }
body.has-owner-bar .st-pause { inset-block-start: 14px; }
.st-dwell { position: absolute; z-index: 3; inset-inline: 0; inset-block-end: 0; height: 2px; background: rgba(246,241,234,.1); overflow: hidden; }
/* sequence follows reading direction, so in Hebrew it fills from the right */
.st-dwell i { position: absolute; inset: 0; background: var(--accent-bright); transform: scaleX(0); transform-origin: 100% 50%; animation: st-dwell 6000ms linear forwards; }
[dir="ltr"] .st-dwell i { transform-origin: 0 50%; }
@keyframes st-dwell { to { transform: scaleX(1); } }

/* ---------------------------------------------------------------- chapters */
.st-chapters-wrap { position: sticky; inset-block-start: 0; z-index: 6; margin: 0 calc(-1 * var(--wrap-x)) 20px; padding: 10px var(--wrap-x);
  background: rgba(13,12,11,.86); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
body.has-owner-bar .st-chapters-wrap { inset-block-start: var(--owner-bar-h, 0px); }
@media (min-width: 900px) { .st-chapters-wrap { margin-inline: -32px; padding-inline: 32px; } }
@media (max-height: 700px) { .st-chapters-wrap { position: static; } }
.st-chapters { display: flex; gap: 8px; overflow-x: auto; scroll-snap-type: x proximity; scrollbar-width: none; padding-block: 2px;
  -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 18px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 18px), transparent); }
.st-chapters::-webkit-scrollbar { display: none; }
#app .st-chip { position: relative; flex: none; min-height: 44px; padding-inline: 16px; gap: 8px; scroll-snap-align: start; white-space: nowrap;
  border-radius: 999px; background: transparent; border: 1px solid var(--room-line); color: var(--room-tx2); font-weight: 400; }
#app .st-chip:hover { color: var(--room-tx); border-color: rgba(246,241,234,.3); }
#app .st-chip[aria-pressed="true"] { color: var(--room-tx); border-color: rgba(232,144,95,.55); background: rgba(232,144,95,.1); font-weight: 500; }
.st-chip .cnt { font-size: .75rem; color: var(--room-tx3); }
/* the extrusion underline: the one warm thing that draws under whatever is active */
.st-chip[aria-pressed="true"]::after { content: ""; position: absolute; inset-inline: 16px; inset-block-end: 7px; height: 2px; border-radius: 2px;
  background: var(--accent-bright); transform-origin: 100% 50%; animation: st-extrude 280ms var(--ease) both; }
@keyframes st-extrude { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.st-chapter + .st-chapter { margin-top: clamp(44px, 7vw, 88px); }
.st-chap-h { display: flex; align-items: baseline; gap: 14px; margin-bottom: 18px; font-weight: 400; }
.st-chap-n { font-family: var(--font-mono); font-size: .75rem; color: var(--room-tx3); letter-spacing: .08em; white-space: nowrap; }
.st-chap-name { font-family: var(--st-display); font-weight: 500; font-size: 1.5rem; line-height: 1.2; color: var(--room-tx); }
.st-room-music .st-chap-name { font-weight: 400; font-size: 1.25rem; }

/* ---------------------------------------------------------------- the justified wall */
.st-gallery, .st-strip { --st-row: 190px; --st-gap: 4px; }
@media (min-width: 480px) { .st-gallery, .st-strip { --st-row: 230px; --st-gap: 5px; } }
@media (min-width: 900px) { .st-gallery, .st-strip { --st-row: 300px; --st-gap: 6px; } }
@media (min-width: 1400px) { .st-gallery, .st-strip { --st-row: 360px; --st-gap: 8px; } }
.st-gallery { transition: opacity 160ms linear; }
.st-gallery.is-out { opacity: 0; }
.st-grid { display: flex; flex-wrap: wrap; gap: var(--st-gap); }
.st-grid::after { content: ""; flex-grow: 999; }
/* The basis is 82% of the target row so two wide frames still share a row on a laptop; flex-grow then
   brings every tile in the row back up to one common height, which lands close to the target. */
.st-tile { --a: calc(var(--w) / var(--h)); position: relative; flex-grow: var(--a); flex-basis: calc(var(--a) * var(--st-row) * .82);
  aspect-ratio: var(--w) / var(--h); max-width: 100%; padding: 0; border: 0; border-radius: 2px; overflow: hidden;
  background: var(--tone, var(--room-1)); cursor: zoom-in; }
@media (max-width: 479px) { .st-tile.is-pano { flex-basis: 100%; } }
/* The develop: a photograph arrives faded and pale and comes up to full colour, the way a print does
   in the tray. Opacity and filter only, and only once the file is decoded and the tile is on screen. */
.st-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; filter: saturate(.15) brightness(1.1);
  transition: opacity 700ms ease-out, filter 1100ms ease-out, transform 600ms var(--st-ease-out); }
.st-tile.is-dev img { opacity: 1; filter: none; }
@media (prefers-reduced-motion: no-preference) {
  .st-tile { transform: translateY(10px); transition: transform 520ms var(--ease) var(--d, 0ms); }
  .st-tile.is-seen { transform: none; }
  .st-gallery.is-in .st-tile { animation: st-in 320ms var(--ease) calc(var(--k, 0) * 24ms) both; }
}
@keyframes st-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.st-cap { position: absolute; inset-inline: 0; inset-block-end: 0; padding: 30px 12px 10px; font-size: .875rem; line-height: 1.4; text-align: start;
  color: var(--room-tx); background: linear-gradient(transparent, rgba(13,12,11,.78)); opacity: 0; transition: opacity 180ms ease; pointer-events: none; }
@media (hover: hover) and (pointer: fine) {
  .st-tile:hover .st-cap, .st-tile:focus-visible .st-cap { opacity: 1; }
  .st-tile.is-dev:hover img { transform: scale(1.02); }
}
@media (hover: none) { .st-cap { display: none; } }
#app .st-tile:focus-visible, #app .st-feature-btn:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; border-radius: 2px; }

.st-feature { margin: 0 auto; max-width: 1200px; display: grid; justify-items: center; gap: 16px; }
.st-feature-btn { position: relative; display: block; padding: 0; border: 0; border-radius: 2px; overflow: hidden; cursor: zoom-in;
  aspect-ratio: var(--w) / var(--h); width: min(100%, calc(80svh * var(--w) / var(--h))); background: var(--tone, var(--room-1)); }
.st-feature-btn img { width: 100%; height: 100%; object-fit: contain; }
.st-feature figcaption { font-family: var(--st-display); font-size: 1.125rem; color: var(--room-tx2); text-align: center; }

.st-wall { display: grid; justify-items: center; gap: 12px; padding: 30px 16px; text-align: center; }
.st-wall-frames { display: flex; align-items: flex-end; gap: 14px; margin-bottom: 16px; }
.st-wall-frames i { display: block; height: clamp(84px, 16vw, 132px); aspect-ratio: var(--w) / var(--h); border: 1.5px dashed rgba(246,241,234,.22); border-radius: 2px; }
.st-wall h3 { font-family: var(--st-display); font-weight: 300; font-size: 1.75rem; color: var(--room-tx); }
.st-wall p { max-width: 30em; color: var(--room-tx2); line-height: 1.7; }

.st-strip { --st-row: 142px; }
@media (min-width: 480px) { .st-strip { --st-row: 172px; } }
@media (min-width: 900px) { .st-strip { --st-row: 225px; } }
@media (min-width: 1400px) { .st-strip { --st-row: 270px; } }
.st-strip.is-clipped { max-height: calc(2.7 * var(--st-row) + var(--st-gap)); overflow: hidden;
  -webkit-mask-image: linear-gradient(#000 70%, transparent); mask-image: linear-gradient(#000 70%, transparent); }
.st-strip-all { margin-top: 14px; }

/* ---------------------------------------------------------------- about */
.st-about-grid { display: grid; gap: 40px; }
@media (min-width: 900px) { .st-about-grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 72px; align-items: start; } }
.st-bio { margin-top: 24px; max-width: 34em; font-family: var(--st-display); font-weight: 300; font-size: 1.25rem; line-height: 1.8; color: var(--room-tx); white-space: pre-wrap; overflow-wrap: anywhere; }
.st-room-music .st-bio { font-family: var(--font-body); font-weight: 400; font-size: 1.0625rem; color: var(--room-tx2); }
.st-bio.is-empty { color: var(--room-tx3); }
.st-about-text .links { margin-top: 22px; }
.st-portrait .avatar { width: min(100%, 360px); height: auto; aspect-ratio: 3 / 4; border-radius: 4px; background: var(--room-1);
  box-shadow: 0 40px 80px -30px rgba(0,0,0,.9); }
.st-room-music .st-portrait .avatar { aspect-ratio: 1; border-radius: 14px; }
/* a character is a square disc: the 3:4 photo frame would crop both its sides (toolpath.css rounds it) */
.st-portrait .avatar[data-pic], .st-room-music .st-portrait .avatar[data-pic] { aspect-ratio: 1; }
.st-facts { display: grid; gap: 10px; margin-top: 22px; }
.st-fact { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; border-radius: 12px; background: var(--room-1); border: 1px solid var(--room-line); min-width: 0; }
.st-fact-ic { width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center; flex: none; background: rgba(232,144,95,.12); color: var(--accent-bright); }
.st-fact-ic svg { width: 18px; height: 18px; }
.st-fact dt { font-size: .8125rem; color: var(--room-tx3); }
.st-fact dd { margin: 3px 0 0; font-weight: 500; line-height: 1.5; color: var(--room-tx); overflow-wrap: anywhere; }
.st-onmap { margin-top: 10px; }

/* ---------------------------------------------------------------- reviews */
.st-reviews #reviews { padding-block: clamp(56px, 10vw, 128px); }
.st-room-photo .st-reviews .sec-head h2 { font-family: var(--st-display); font-weight: 300; }
.st-reviews .sec-head .kicker { font-family: var(--font-body); letter-spacing: normal; }
.st-quote { margin: 30px 0 6px; max-width: 42em; padding-inline-start: 22px; border-inline-start: 2px solid var(--accent-bright); }
.st-quote blockquote { font-family: var(--st-display); font-weight: 300; font-size: clamp(22px, 3vw, 32px); line-height: 1.45; color: var(--room-tx); overflow-wrap: anywhere; }
.st-room-music .st-quote blockquote { font-family: var(--font-body); font-weight: 400; font-size: clamp(20px, 2.6vw, 26px); }
.st-quote figcaption { margin-top: 14px; font-size: .9375rem; color: var(--room-tx2); }
.st-reviews .plate:not(.dark) { background: var(--room-1); border-color: var(--room-line); color: var(--room-tx); box-shadow: none; }
#app .st-reviews .plate:not(.dark) p { color: var(--room-tx2); }
.st-reviews .plate.rev-empty img { opacity: .9; }

/* ---------------------------------------------------------------- the action bar */
#app .st-bar { background: rgba(13,12,11,.86); border-color: var(--room-line); }
.st-bar-acts { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; }
.st-bar-acts > .btn { flex: 1; min-width: 0; }
.st-bar-acts > .btn-icon { flex: 0 0 48px; }
body.st-viewing .st-bar { visibility: hidden; }

/* ---------------------------------------------------------------- footer on the room */
.st-foot.enclosure { border-block-start: 1px solid rgba(246,241,234,.06); }
.st-foot-h { margin-top: 10px; font-family: var(--st-display); font-weight: 300; color: var(--room-tx); }
/* the footer links are tap targets too: 44px both ways, which the store footer never measured */
.st-foot .f-brand { min-height: 44px; }
.st-foot .linkish { min-width: 44px; display: inline-flex; align-items: center; justify-content: center; }
.st-music .st-foot-h { font-weight: 400; }

/* ---------------------------------------------------------------- the viewer */
.st-viewer { position: fixed; inset: 0; z-index: 95; color: #F6F1EA; overscroll-behavior: contain; }
.st-v-back { position: absolute; inset: 0; background: rgba(8,7,6,.97); transition: opacity 240ms linear; }
.st-viewer.is-opening .st-v-back { opacity: 0; transition: none; }
.st-viewer.is-closing .st-v-back { opacity: 0; transition-duration: 280ms; }
.st-viewer.is-closing .st-v-top, .st-viewer.is-closing .st-v-bottom, .st-viewer.is-closing .st-v-nav { opacity: 0; }
.st-viewer.is-fading-in { animation: st-fade 180ms ease both; }
.st-viewer.is-fading { opacity: 0; transition: opacity 180ms ease; }
.st-v-stage { position: absolute; inset: 0; overflow: hidden; touch-action: none; user-select: none; -webkit-user-select: none; }
.st-v-slide { position: absolute; inset: 0; }
.st-v-slide.is-fade { animation: st-fade 120ms linear both; }
.st-v-pic { position: absolute; inset: calc(64px + var(--safe-t)) 12px calc(96px + var(--safe-b)); transform-origin: 50% 50%; }
@media (min-width: 900px) { .st-v-pic { inset: 76px 96px 108px; } }
.st-v-pic img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; -webkit-user-drag: none; }
.st-v-pic .hi { opacity: 0; transition: opacity 240ms ease; }
.st-v-pic .hi.is-ready { opacity: 1; }
.st-viewer.is-zoomed .st-v-stage { cursor: grab; }
.st-v-top { position: absolute; inset-inline: 0; inset-block-start: 0; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: calc(10px + var(--safe-t)) 12px 10px; pointer-events: none; transition: opacity 300ms ease; }
.st-v-top > .st-v-btn { pointer-events: auto; }
.st-v-count { display: flex; align-items: baseline; gap: 12px; min-width: 0; padding-inline: 8px; font-size: .875rem; color: rgba(246,241,234,.72); }
.st-v-chap { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.st-v-btn { width: 44px; height: 44px; flex: none; border-radius: 50%; display: grid; place-items: center; color: #F6F1EA;
  background: rgba(22,20,18,.72); border: 1px solid rgba(246,241,234,.12); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); transition: background .15s, opacity 300ms ease; }
.st-v-btn:hover { background: rgba(33,30,27,.9); }
.st-v-btn svg { width: 20px; height: 20px; }
.st-viewer :focus-visible { outline: 2px solid #E8905F; outline-offset: 2px; }
.st-v-nav { position: absolute; inset-block-start: 50%; transform: translateY(-50%); display: none; }
@media (min-width: 900px) and (hover: hover) { .st-v-nav:not([hidden]) { display: grid; } }
.st-v-prev { inset-inline-start: 24px; }
.st-v-prev svg { transform: scaleX(-1); }
.st-v-next { inset-inline-end: 24px; }
.st-v-bottom { position: absolute; inset-inline: 0; inset-block-end: 0; display: flex; align-items: flex-end; justify-content: space-between; gap: 12px;
  padding: 12px 18px calc(16px + var(--safe-b)); pointer-events: none; transition: opacity 300ms ease; }
.st-v-cap { max-width: 60ch; font-size: .9375rem; line-height: 1.5; }
.st-v-tools { display: none; gap: 8px; pointer-events: auto; }
@media (min-width: 900px) { .st-v-tools { display: flex; } }
.st-viewer.is-idle .st-v-top, .st-viewer.is-idle .st-v-bottom, .st-viewer.is-idle .st-v-nav { opacity: 0; }
.st-viewer.is-idle .st-v-btn, .st-viewer.is-idle .st-v-tools { pointer-events: none; }
.st-v-hint { position: absolute; inset-inline: 0; inset-block-end: calc(104px + var(--safe-b)); width: max-content; max-width: calc(100% - 40px); margin-inline: auto;
  padding: 10px 16px; border-radius: 999px; background: rgba(22,20,18,.9); font-size: .875rem; pointer-events: none; }
@keyframes st-fade { from { opacity: 0; } to { opacity: 1; } }

/* ---------------------------------------------------------------- reduced motion: every moment above has an instant path */
@media (prefers-reduced-motion: reduce) {
  .st-gallery, .st-v-back, .st-cap, .st-tile img, .st-v-pic .hi { transition: none !important; }
  .st-chip[aria-pressed="true"]::after, .st-dwell i, .st-frame, .st-viewer.is-fading-in { animation: none !important; }
  .st-viewer.is-idle .st-v-top, .st-viewer.is-idle .st-v-bottom, .st-viewer.is-idle .st-v-nav { opacity: 1; }
  .st-viewer.is-idle .st-v-btn, .st-viewer.is-idle .st-v-tools { pointer-events: auto; }
}

/* ============================================================================
   Added with the store room (docs/store-room-spec.md P1, P3, P7). A store renders its room with these
   rules too; a studio page is unchanged by them unless a line says otherwise.
   ========================================================================== */

/* the display face of a room: Suez One; a slides cover sets Frank Ruhl on itself (store-room.css) */
.st-room, .st-foot { --st-display: var(--font-display); }
body[data-room="dark"]:not(.mg-on) { --room-line-soft: rgba(246,241,234,.06); }

/* The bar never covers the control a keyboard user just tabbed to (WCAG 2.4.11): a scroll into view
   stops above it. Studios get this too; the owner rail's own offset (the storefront's inline rule)
   is on the other edge. */
html:has(body[data-room="dark"] #stBar) { scroll-padding-block-end: calc(84px + env(safe-area-inset-bottom, 0px)); }
@media (min-width: 900px) { html:has(body[data-room="dark"] #stBar) { scroll-padding-block-end: 100px; } }

/* ---------------------------------------------------------------- the uniform wall
   Every work has the same shape (or none is known yet): a grid instead of justified rows. The columns
   come from room-wall.js uniformPlan() as --cols-s (under 720px), --cols-m (720px to 1099px) and
   --cols-l (1100px up), and its span classes close every row at every width:
   m-row the whole row on a phone, t-wide two of three columns, d-hero 2x2, d-half two of four,
   d-row and d-solo the whole row. A spanned tile that shares its row with single tiles (t-wide,
   d-hero) takes that row's height instead of its own shape, so no sliver opens beside it. */
.st-grid[data-uniform] { display: grid; grid-template-columns: repeat(var(--cols-s, 2), minmax(0, 1fr)); align-items: start; }
.st-grid[data-uniform]::after { content: none; }
.st-grid[data-uniform] > .st-tile { min-width: 0; aspect-ratio: var(--w) / var(--h); }
@media (max-width: 719px) {
  .st-grid[data-uniform] > .m-row { grid-column: 1 / -1; aspect-ratio: calc(var(--w) * 2) / var(--h); }
}
@media (min-width: 720px) and (max-width: 1099px) {
  .st-grid[data-uniform] { grid-template-columns: repeat(var(--cols-m, 3), minmax(0, 1fr)); }
  .st-grid[data-uniform] > .t-wide { grid-column: span 2; aspect-ratio: auto; align-self: stretch; }
}
@media (min-width: 1100px) {
  .st-grid[data-uniform] { grid-template-columns: repeat(var(--cols-l, 4), minmax(0, 1fr)); }
  .st-grid[data-uniform][data-lplan="layout"] > .d-hero { grid-column: span 2; grid-row: span 2; aspect-ratio: auto; align-self: stretch; }
  .st-grid[data-uniform][data-lplan="layout"] > .d-half { grid-column: span 2; aspect-ratio: calc(var(--w) * 2) / var(--h); }
  .st-grid[data-uniform][data-lplan="layout"] > .d-row { grid-column: 1 / -1; aspect-ratio: calc(var(--w) * 4) / var(--h); }
  .st-grid[data-uniform][data-lplan="layout"] > .d-solo { grid-column: 1 / -1; aspect-ratio: calc(var(--w) * 2) / var(--h); }
}

/* a text button a fact carries as its extra (the business details, later) */
.st-fact .linkish { display: inline-flex; align-items: center; min-height: 44px; margin-top: 2px; padding: 0 2px;
  background: none; border: 0; font: inherit; font-weight: 500; color: var(--accent-bright); cursor: pointer;
  text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px; }
.st-fact .linkish:hover { text-decoration-thickness: 2px; }

/* the portrait with its caption (a store's STORY): a square picture and the name under it; a studio's
   portrait is a plain div and keeps the frame above */
figure.st-portrait { display: grid; gap: 14px; justify-items: start; margin: 0; }
figure.st-portrait .avatar { width: min(100%, 300px); aspect-ratio: 1; border-radius: 14px; }
figure.st-portrait figcaption { display: grid; gap: 2px; min-width: 0; }
figure.st-portrait figcaption b { font-family: var(--st-display); font-weight: 400; font-size: 1.25rem; line-height: 1.3; color: var(--room-tx); overflow-wrap: anywhere; }
figure.st-portrait figcaption span { color: var(--room-tx3); font-size: .9375rem; overflow-wrap: anywhere; }
@media (max-width: 899px) {
  figure.st-portrait { grid-template-columns: 96px minmax(0, 1fr); align-items: center; }
  figure.st-portrait .avatar { width: 96px; }
}

/* Hebrew labels in the body face with normal tracking. The storefront's kept inline rules put the
   footer's year line in the mono stack (which has no Hebrew) and letterspace the receipt header,
   which pulls a Hebrew word apart; these outrank them on every room. */
footer.site.st-foot .m { font-family: var(--font-body); letter-spacing: normal; }
.st-reviews .receipt .rh { font-family: var(--font-body); letter-spacing: normal; font-size: .8125rem; }

/* ---------------------------------------------------------------- the viewer: the heart and the report
   Outside .st-v-tools (hidden under 900px, where most buyers are), 44px like every viewer control, at
   every width. The heart's label never changes; aria-pressed carries its state, and the fill shows it
   as a shape as well as a colour. */
.st-v-acts { display: flex; align-items: center; gap: 16px; flex: none; margin-inline-start: auto; pointer-events: auto; }
/* the count belongs to the heart, so it sits right beside it and apart from the report */
.st-v-likebox { display: inline-flex; align-items: center; gap: 6px; }
.st-v-like[aria-pressed="true"] { color: #E8905F; border-color: rgba(232,144,95,.55); }
.st-v-like[aria-pressed="true"] svg { fill: currentColor; }
.st-v-likes { min-width: 1.5ch; font-size: .875rem; color: rgba(246,241,234,.72); }
.st-v-likes:empty { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .st-v-like[aria-pressed="true"] svg { animation: st-beat 280ms var(--ease); }
}
@keyframes st-beat { 50% { transform: scale(1.18); } }
@media (forced-colors: active) {
  .st-v-like[aria-pressed="true"] svg { forced-color-adjust: none; fill: Highlight; }
}

/* ---------------------------------------------------------------- one work, several photos (supabase/066)
   The tile says how many: a stack and the number, top inline-end (the like count holds the other
   corner). The viewer walks photo by photo; the work buttons, the prints and the wider gap between
   works appear only when some work has more than one photo, so a store of single photos is unchanged. */
.st-photos { position: absolute; z-index: 1; inset-block-start: 10px; inset-inline-end: 10px;
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px; border-radius: 999px;
  background: rgba(13,12,11,.82); box-shadow: 0 0 0 1px rgba(246,241,234,.18);
  color: var(--room-tx); font-size: .75rem; font-weight: 600; line-height: 1.5; pointer-events: none; }
.st-photos svg { width: 14px; height: 14px; flex: none; }

.st-v-works { display: flex; align-items: center; gap: 8px; margin-inline-start: auto; }
.st-v-work { height: 44px; display: inline-flex; align-items: center; gap: 4px; padding-inline: 10px 14px; border-radius: 999px;
  color: #F6F1EA; font-size: .8125rem; background: rgba(22,20,18,.72); border: 1px solid rgba(246,241,234,.12);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); pointer-events: auto; transition: background .15s, opacity 300ms ease; }
.st-v-work-next { padding-inline: 14px 10px; }
.st-v-work[hidden] { display: none; }
.st-v-work:hover { background: rgba(33,30,27,.9); }
.st-v-work svg { width: 18px; height: 18px; flex: none; }
.st-v-work-prev svg { transform: scaleX(-1); }
/* a phone: the work buttons take a row of their own under the counter, previous at the start */
@media (max-width: 559px) {
  .st-viewer.has-works .st-v-top { flex-wrap: wrap; row-gap: 6px; }
  .st-viewer.has-works .st-v-works { order: 3; flex-basis: 100%; justify-content: space-between; margin-inline-start: 0; }
  .st-viewer.has-works .st-v-work-next { margin-inline-start: auto; }
  .st-viewer.has-works .st-v-pic { inset-block-start: calc(116px + var(--safe-t)); }
}
/* The prints: every photo of the work on screen, small under the photo, the way prints lie on a table
   (room-viewer.js thumbsHtml). Each leans its own degree or two (--tilt); the one on screen
   straightens, lifts and has the extrusion line drawn under it, the others sit back at 60%. The strip
   is one row, the cover at inline-start, centred while it fits and scrolled (never wrapped) when it
   does not; its gaps let a drag through to the stage, only the prints take the pointer, so a drag
   that starts ON a print belongs to the strip (it scrolls it when the prints do not fit) and a swipe
   anywhere else, the gaps included, moves the photo.
   A print is --tw wide and its button --th tall: 48 by 62 on a phone, 60 by 78 from 900px, both past
   the 44px target. The prints stand 72px above the bottom; the strip is a scroll container and clips,
   so its box reaches 12px over them (the lifted print plus its focus ring need 10) and 14px under
   them (the deal rises from 22px lower). The photo keeps that box clear: 146px of 148, 162 of 164.
   Measured on the viewer's ground (#080706, and #0F0E0D with a white page under the 97% backdrop):
   the line, --accent-bright, 7.88:1; a print's paper at 60% 6.07:1, at full 15.6:1; the focus ring,
   --accent-bright again, 7.88:1. The photo on screen is marked by the line, the lift and the full
   light together, never by colour alone. */
.st-v-thumbs { --tw: 48px; --th: 62px; position: absolute; inset-inline: 0; inset-block-end: calc(58px + var(--safe-b)); display: flex; gap: 6px;
  margin: 0; padding-block: 12px 14px; padding-inline: 12px; list-style: none; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: none;
  touch-action: pan-x; pointer-events: none; transition: opacity 300ms ease, visibility 0s; }
.st-v-thumbs::-webkit-scrollbar { display: none; }
.st-v-thumbs[hidden] { display: none; }
.st-v-thumbs > li { flex: none; }
.st-v-thumbs > li:first-child { margin-inline-start: auto; }
.st-v-thumbs > li:last-child { margin-inline-end: auto; }
.st-v-thumb { position: relative; width: var(--tw); height: var(--th); display: block; padding: 0; border: 0; background: none;
  color: inherit; cursor: pointer; pointer-events: auto; -webkit-tap-highlight-color: transparent; }
.st-v-print { display: block; padding: 3px 3px 7px; border-radius: 3px; background: #EDE6DC;
  box-shadow: 0 6px 14px rgba(0,0,0,.5); opacity: .6; transform: rotate(var(--tilt, 0deg));
  transition: transform 260ms var(--st-ease-out), opacity 200ms ease, box-shadow 260ms ease; }
.st-v-print img { display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; border-radius: 1px; background: var(--tone, #2A2622); -webkit-user-drag: none; }
@media (hover: hover) { .st-v-thumb:hover .st-v-print { opacity: .9; } }
.st-v-thumb[aria-current="true"] .st-v-print { opacity: 1; transform: translateY(-3px) scale(1.06); box-shadow: 0 10px 22px rgba(0,0,0,.6); }
/* the extrusion line: laid from the reading start under the print on screen, lifted off the one left */
.st-v-thumb::after { content: ""; position: absolute; inset-inline: 7px; inset-block-end: 2px; height: 3px; border-radius: 2px;
  background: var(--accent-bright, #E8905F); transform: scaleX(0); transform-origin: 100% 50%; transition: transform 160ms ease; }
.st-viewer:dir(ltr) .st-v-thumb::after { transform-origin: 0 50%; }
.st-v-thumb[aria-current="true"]::after { transform: scaleX(1); transition: transform 340ms var(--st-ease-out) 60ms; }
.st-viewer .st-v-thumb:focus-visible { outline: none; }
.st-v-thumb:focus-visible .st-v-print { opacity: 1; outline: 2px solid var(--accent-bright, #E8905F); outline-offset: 3px; }
.st-v-thumbs.is-leaving .st-v-thumb { pointer-events: none; }
@media (min-width: 900px) {
  .st-v-thumbs { --tw: 60px; --th: 78px; gap: 10px; }
  .st-v-print { padding: 4px 4px 9px; }
}
/* zoomed in, the prints step aside (and out of the tab order) until the photo is back at rest */
.st-viewer.is-zoomed .st-v-thumbs { opacity: 0; visibility: hidden; transition: opacity 200ms ease, visibility 0s linear 200ms; }
.st-viewer.has-photos .st-v-pic { inset-block-end: calc(148px + var(--safe-b)); }
@media (min-width: 900px) { .st-viewer.has-photos .st-v-pic { inset-block-end: 164px; } }
.st-viewer.has-thumbs .st-v-hint { inset-block-end: calc(148px + var(--safe-b)); }
/* While the prints show, the caption keeps to two lines under them: 16px + 2 x 22.5px ends at 61px,
   the prints stand at 72px (at the 18px root of a wide screen, 67px). A longer caption paints over the
   prints, cream on their cream paper; the full text stays the photo's alt and the live line. */
.st-viewer.has-thumbs .st-v-cap { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.st-viewer.is-closing .st-v-thumbs, .st-viewer.is-idle .st-v-thumbs, .st-viewer.is-idle .st-v-work { opacity: 0; }
.st-viewer.is-idle .st-v-thumb, .st-viewer.is-idle .st-v-work { pointer-events: none; }
/* a tapped print: the photo that was on screen dissolves over the new one (room-viewer.js dissolve) */
.st-v-ghost { pointer-events: none; animation: st-dissolve 220ms ease both; }
@keyframes st-dissolve { to { opacity: 0; } }
@media (prefers-reduced-motion: no-preference) {
  /* dealt onto the table when a work with several photos opens, one after another */
  .st-v-thumbs:not(.is-leaving) .st-v-print { animation: st-deal 460ms var(--st-ease-out) calc(var(--j, 0) * 55ms + 80ms) backwards; }
  /* and gathered up when the next work has one photo */
  .st-v-thumbs.is-leaving .st-v-print { opacity: 0; transform: translateY(12px) rotate(calc(var(--tilt, 0deg) * 3));
    transition: transform 200ms ease-in, opacity 200ms ease-in; }
}
@keyframes st-deal { from { opacity: 0; transform: translateY(22px) rotate(calc(var(--tilt, 0deg) * 4)) scale(.9); } }

/* the one-work strip: the cover's frame, swiped or stepped, never moving by itself */
.st-feat { position: relative; display: grid; gap: 10px; width: min(100%, calc(80svh * var(--w) / var(--h))); }
.st-feat-track { display: flex; gap: 8px; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
  scrollbar-width: none; padding-inline: 16px; scroll-padding-inline: 16px; }
.st-feat-track::-webkit-scrollbar { display: none; }
.st-feat .st-feat-slide { flex: 0 0 100%; width: 100%; scroll-snap-align: center; scroll-snap-stop: always; }
/* fixed tracks, so a button hidden at its end leaves the counter where it was */
.st-feat-bar { display: grid; grid-template-columns: 44px auto 44px; align-items: center; justify-content: center; gap: 14px; }
.st-feat-prev { grid-column: 1; }
.st-feat-count { grid-column: 2; }
.st-feat-next { grid-column: 3; }
.st-feat-go { width: 44px; height: 44px; display: grid; place-items: center; padding: 0; border-radius: 50%;
  color: var(--room-tx); background: var(--room-1); border: 1px solid var(--room-line); }
.st-feat-go svg { width: 20px; height: 20px; }
.st-feat-prev svg { transform: scaleX(-1); }
.st-feat-count { min-width: 5ch; text-align: center; font-size: .875rem; color: var(--room-tx2); }
#app .st-feat-go:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .st-viewer.is-idle .st-v-thumbs, .st-viewer.is-idle .st-v-work { opacity: 1; }
  .st-viewer.is-idle .st-v-thumb, .st-viewer.is-idle .st-v-work { pointer-events: auto; }
  /* the prints change state at once: no tilt, no lift, no line drawn, no dissolve */
  .st-v-thumbs, .st-v-print, .st-v-thumb::after { transition: none !important; }
  .st-v-print, .st-v-thumb[aria-current="true"] .st-v-print { transform: none; }
  .st-v-ghost { animation: none !important; display: none; }
}
@media (forced-colors: active) {
  .st-photos { border: 1px solid CanvasText; }
  .st-v-print { border: 1px solid CanvasText; }
  .st-v-thumb::after { forced-color-adjust: none; background: Highlight; }
  .st-v-thumb:focus-visible .st-v-print { outline-color: Highlight; }
}
