/* ---------------------------------------------------------------------------
   richardsaad.com — gallery walk
   One print per wall. Ported from the "One Print Per Wall" prototype.

   Everything is scoped to .rs-gallery so the component can run as a full-screen
   overlay on the site and as an inline box in the panel without the two fighting
   over the page. The prototype keyed off `body`; nothing here may.

   Editor instruments are hidden unless the root carries data-mode="editor".
   One flag, not two code paths.
   --------------------------------------------------------------------------- */

.rs-gallery {
  --rs-ink: #1A1A1A;
  --rs-grey: #6E6E6E;
  --rs-hair: #D6D6D6;
  /* the control block carries its own pair, darker than the room's hairlines:
     it has to be found against a bright wall, where a hairline cannot be */
  --rs-nav-ink: #4A4A4A;
  --rs-nav-frame: #A0A0A0;
  --rs-panel: rgba(255, 255, 255, 0.88);
  --rs-ground: #E9E9E9;

  /* ---- the glass wall ----------------------------------------------------
     Settled in simulation. One blur, one tint, one ink: opening the glass dims
     the room, so the type never has to work against a lit wall and there is no
     second contrast case to keep balanced. */
  --glass-blur:   6px;
  --glass-tint:   rgba(28, 22, 15, 0.70);
  --glass-ink:    #C9C4BB;
  --glass-edge:   rgba(255, 255, 255, 0.12);
  --glass-inset:  2.5%;
  --glass-width:  66%;
  --read-dim:     0.27;
  --glass-slide:  900ms;
  --glass-ease:   cubic-bezier(.22,.61,.36,1);
  --text-clear:   8rem;    /* the text stops here */
  --btn-zone:     4.2rem;  /* 1.3 hud pad + 2.1 button + 0.8 air */
  --glass-size:   12px;    /* the statement */
  --glass-title:  2.9;     /* the code, as a multiple of the statement */
  --glass-cols:   2;
  --glass-lead:   1.6;
  --glass-para:   1;       /* paragraph gap in LINES, never a loose em */
  --glass-weight: 400;

  position: relative;
  overflow: hidden;
  background: var(--rs-ground);
  color: var(--rs-ink);
  font-family: 'Raleway', system-ui, sans-serif;
  font-weight: 300;
  /* the walk is measured in whole viewports of THIS box, so it must have one */
  contain: paint;
  transition: background 900ms ease;
}

.rs-gallery *,
.rs-gallery *::before,
.rs-gallery *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* full-screen overlay mode, used on the site */
.rs-gallery[data-fill="screen"] { position: fixed; inset: 0; z-index: 9000; }

/* pan-y, not none: a horizontal drag is the walk's and a vertical one is the
   page's, and the component decides which it is on the first six pixels */
.rs-stage { position: absolute; inset: 0; overflow: hidden; touch-action: pan-y; cursor: grab; }
.rs-gallery.is-dragging .rs-stage { cursor: grabbing; }
.rs-gallery.is-dragging .rs-print img { pointer-events: none; }
.rs-run { position: absolute; top: 0; left: 0; height: 100%; display: flex; will-change: transform; }

/* one wall = one viewport of the stage. Alternate walls mirror so the joins fall
   on matching edges of the plate and there is nothing to catch the eye. */
.rs-wall { position: relative; height: 100%; flex: 0 0 auto; overflow: hidden; }

/* Only the plates mirror. Flipping the wall itself mirrors the POSITION of every
   child too, which silently swaps left for right on alternate walls. */
.rs-plate,
.rs-plate-dark {
  position: absolute; inset: 0; pointer-events: none;
  background-size: cover;
  background-position: center var(--rs-plate-y, 60%);
}
.rs-plate { background-image: var(--rs-wall); }
/* The night wall is the dark plate multiplied down, not a different picture: the
   asset stays untouched and one value says how deep the room goes. A background
   blend rather than a `filter`, because the plate travels with the run and a
   filter on a travelling layer is re-rasterised on every frame. Raise
   --rs-night-dim towards #FFF for a paler room, lower it for a darker one. */
.rs-plate-dark {
  background-image: var(--rs-wall-dark);
  background-color: var(--rs-night-dim, #7A7A7A);
  background-blend-mode: multiply;
  opacity: 0; transition: opacity 900ms ease;
}
.rs-flip { transform: scaleX(-1); }
.rs-gallery.lights-off { background: #060606; }
.rs-gallery.lights-off .rs-plate-dark { opacity: 1; }

/* ---- the print ---------------------------------------------------------- */

.rs-print {
  position: absolute;
  background-size: cover; background-position: center;
  z-index: 2;                       /* over the joints, which are over the plates */
  opacity: 0;                       /* until its own ratio is known */
  transition: filter 900ms ease, box-shadow 900ms ease, opacity 600ms ease;
}
.rs-print.is-ready { opacity: 1; }
/* The light a print puts into the room, and the shadow it takes out of it: five
   layers per print, positioned by _light() — contact, cast, near field, floor wash,
   reflection, in that paint order, so the light falls on top of the shadow rather
   than under it. They sit under the print and under the joints, and the field
   layers are plain scaled bitmaps — the softening is baked into a small canvas
   rather than done with a CSS blur, so the compositor moves them for free. */
.rs-lit { position: absolute; pointer-events: none; background-repeat: no-repeat; }

/* a real <img>, not a background: the print carries alt text, and because its
   width is derived from its own ratio there is nothing to crop or letterbox */
.rs-print img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Retro-lit: the panel holds its own light and gives none of it to the room.
   Its edges go dark rather than catching a rim that has no source. */
.rs-gallery.lights-off .rs-print { filter: brightness(1.04) contrast(1.02); }
.rs-gallery.lights-off .rs-print::after {
  border-right-color: rgba(0, 0, 0, 0.55);
  border-bottom-color: rgba(0, 0, 0, 0.62);
  border-left-color: rgba(0, 0, 0, 0.55);
  border-top-color: rgba(0, 0, 0, 0.45);
}
.rs-gallery.lights-off .rs-print .rs-sheen {
  background: radial-gradient(120% 120% at 50% 45%, rgba(0,0,0,0) 55%, rgba(0,0,0,0.35) 100%);
  mix-blend-mode: multiply;
}
.rs-print::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  border-right: var(--rs-edge) solid rgba(255,255,255,0.55);
  border-bottom: var(--rs-edge) solid rgba(0,0,0,0.10);
  border-left: var(--rs-edge) solid rgba(0,0,0,0.06);
  border-top: var(--rs-edge) solid rgba(255,255,255,0.35);
}
.rs-print .rs-sheen {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to bottom, rgba(255,255,255,0.05), rgba(0,0,0,0.05));
  mix-blend-mode: soft-light;
}

/* ---- the joints --------------------------------------------------------- */
/* Always drawn, never toggled: they are the system the wall is set out on. One
   medium grey serves both rooms — it reads dark on the lit wall and light on the
   dark one, which is the whole reason for choosing a mid value. */

.rs-rule { position: absolute; inset: 0; pointer-events: none; }
.rs-joints { left: 0; top: 0; height: 100%; will-change: transform; z-index: 1; }
.rs-dims { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.rs-rule i { position: absolute; background: rgba(122,122,122,0.62); }
.rs-rule i.h { left: 0; right: 0; height: 1px; }
.rs-rule i.v { width: 1px; top: 0; }        /* height set per line: stops at the base */
.rs-rule i.datum { background: rgba(122,122,122,0.85); }
/* the picture's own sill and top: the same system, one step quieter, and they
   travel with the wall instead of holding still like the room's datums */
.rs-rule i.h.pic { background: rgba(122,122,122,0.45); }
.rs-gallery.lights-off .rs-rule i.h.pic { background: rgba(58,58,58,0.50); }
.rs-gallery.lights-off .rs-rule i { background: rgba(64,64,64,0.50); }
.rs-gallery.lights-off .rs-rule i.datum { background: rgba(72,72,72,0.62); }
.rs-gallery.lights-off .rs-rule b { color: rgba(82,82,82,0.85); }

/* dimensions, in millimetres, unlabelled — the number is the whole annotation.
   The room is dimensioned on the left and the picture on the right, so the two
   families never collide mid-walk. */
.rs-rule b {
  position: absolute; font: 400 0.5rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.16em; color: rgba(122,122,122,0.95);
  font-variant-numeric: tabular-nums;
}
.rs-rule b.r { right: 10px; color: rgba(122,122,122,0.78); }
.rs-gallery.lights-off .rs-rule b.r { color: rgba(76,76,76,0.85); }

/* human scale: an editor instrument, off by default */
.rs-scale { position: absolute; inset: 0; pointer-events: none; display: none; }
.rs-gallery.show-scale .rs-scale { display: block; }
.rs-scale i { position: absolute; background: rgba(0,0,0,0.14); }
.rs-scale i.h { left: 0; right: 0; height: 1px; }
.rs-scale i.thin { background: rgba(0,0,0,0.09); }
.rs-scale b {
  position: absolute; font: 400 0.5rem/1 ui-monospace, Menlo, monospace;
  letter-spacing: 0.18em; color: rgba(0,0,0,0.42); background: rgba(255,255,255,0.7);
  padding: 2px 4px;
}
/* a 170 cm figure: the reference the plate itself does not contain */
.rs-scale u {
  position: absolute; text-decoration: none; background: rgba(0,0,0,0.07);
  -webkit-mask: radial-gradient(circle at 50% 9%, #000 0 9%, transparent 9.5%),
                linear-gradient(#000 0 0) 50% 100%/38% 82% no-repeat;
          mask: radial-gradient(circle at 50% 9%, #000 0 9%, transparent 9.5%),
                linear-gradient(#000 0 0) 50% 100%/38% 82% no-repeat;
}
.rs-gallery.lights-off .rs-scale i { background: rgba(255,255,255,0.16); }
.rs-gallery.lights-off .rs-scale i.thin { background: rgba(255,255,255,0.10); }
.rs-gallery.lights-off .rs-scale b { color: rgba(255,255,255,0.5); background: rgba(0,0,0,0.5); }
.rs-gallery.lights-off .rs-scale u { background: rgba(255,255,255,0.06); }

/* ---- the instruments ---------------------------------------------------- */

.rs-hud {
  position: absolute; inset: 0; pointer-events: none;
  display: grid; grid-template-rows: auto 1fr auto;
  padding: 1.3rem 1.7rem; z-index: 7;
}
/* Only the instruments take clicks. Giving every grid child pointer-events:auto
   puts an invisible full-width band across the middle of the box — right over the
   1 m axis, which is exactly where the switch lives. */
.rs-hud > * { pointer-events: none; }
.rs-desk, .rs-readout, .rs-nav, .rs-toggles { pointer-events: auto; }

.rs-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 2rem; }
.rs-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 1.4rem; flex-wrap: wrap; }

.rs-code { font-size: 0.7rem; letter-spacing: 0.42em; text-transform: uppercase; font-weight: 300; color: #4A4A4A; }
.rs-readout-dims {
  font-family: ui-monospace, Menlo, monospace; font-size: 0.57rem; color: #7A7A7A;
  text-align: right; line-height: 1.8; font-variant-numeric: tabular-nums;
}
.rs-readout-dims b { color: var(--rs-ink); font-weight: 400; }
.rs-ok { color: #4F7A5C; }
.rs-warn { color: #B2593A; }

.rs-desk {
  display: grid; gap: 0.6rem; background: var(--rs-panel); backdrop-filter: blur(10px);
  border: 1px solid var(--rs-hair); padding: 0.9rem 1rem; max-width: 23rem;
}
.rs-desk h2 { font-size: 0.5rem; letter-spacing: 0.3em; text-transform: uppercase; color: var(--rs-grey); font-weight: 300; }
.rs-ctl { display: grid; grid-template-columns: 6rem 1fr 3.2rem; align-items: center; gap: 0.7rem; }
.rs-ctl label { font-size: 0.55rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--rs-grey); }
.rs-ctl output { font-family: ui-monospace, Menlo, monospace; font-size: 0.6rem; text-align: right; font-variant-numeric: tabular-nums; }

.rs-gallery input[type=range] { appearance: none; -webkit-appearance: none; width: 100%; height: 1px; background: #C4C4C4; }
.rs-gallery input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 9px; height: 9px; border-radius: 50%; background: var(--rs-ink); cursor: pointer; }
.rs-gallery input[type=range]::-moz-range-thumb { width: 9px; height: 9px; border: 0; border-radius: 50%; background: var(--rs-ink); cursor: pointer; }
.rs-gallery input[type=range]:focus-visible { outline: 1px solid rgba(0,0,0,0.55); outline-offset: 4px; }

.rs-toggles { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.rs-tg {
  appearance: none; background: none; border: 1px solid var(--rs-hair); font: inherit; color: var(--rs-grey);
  cursor: pointer; font-size: 0.52rem; letter-spacing: 0.2em; text-transform: uppercase;
  padding: 0.5rem 0.85rem; transition: color .3s, border-color .3s, background .3s;
}
.rs-tg:hover { color: var(--rs-ink); border-color: #9A9A9A; }
.rs-tg[aria-pressed="true"] { color: #FFFFFF; background: var(--rs-ink); border-color: var(--rs-ink); }

/* ---- navigation --------------------------------------------------------- */
/* Arrows in frames, no words. The frame is a touch darker than the ground so the
   pair reads as one control block with the toggle between them. */

/* Measured against the lit plate, which reads #E3E3E4 where the controls sit.
   The old frame at #D6D6D6 came to 1.13:1 there — no edge at all, so the arrow
   floated as a stray mark rather than reading as a control. Darkening the frame
   and lifting the fill does the work; an area at low contrast is far easier to
   find than a hairline at the same ratio, which keeps it quiet on the wall.
     ink   #4A4A4A  6.9:1     frame #A0A0A0  2.4:1 */
.rs-nav { display: flex; gap: 0.4rem; align-items: center; }
.rs-nav button {
  appearance: none; font: inherit; color: var(--rs-nav-ink); cursor: pointer;
  width: 3rem; height: 2.1rem; padding: 0;
  display: grid; place-items: center;
  background: rgba(0,0,0,0.07); border: 1px solid var(--rs-nav-frame);
  transition: background .3s, border-color .3s, color .3s;
}
.rs-nav button svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.2; }
.rs-nav button:hover { background: rgba(0,0,0,0.11); color: var(--rs-ink); border-color: #7E7E7E; }
/* A disabled arrow fades its ink, not the whole control: at 0.35 opacity the
   frame went with it and Prev on the first wall disappeared. With the loop there
   are no ends, so this is only reached by a single-wall series. */
.rs-nav button[disabled] { color: #8E8E8E; border-color: #C2C2C2; background: rgba(0,0,0,0.03); cursor: default; }
.rs-nav button[disabled]:hover { color: #8E8E8E; border-color: #C2C2C2; background: rgba(0,0,0,0.03); }

/* The light toggle wears the same frame as the arrows — no solid block. The knob
   is the one grey the joints use, so the control belongs to the drawing rather
   than shouting over it.
   Scoped as `.rs-nav .rs-switch`: `.rs-nav button { width: 3rem }` otherwise wins
   on specificity and silently squashes the track. */
.rs-nav .rs-switch {
  position: relative; appearance: none; cursor: pointer;
  width: 5rem; height: 2.1rem; padding: 3px;
  background: rgba(0,0,0,0.07); border: 1px solid var(--rs-nav-frame);
  transition: background .3s, border-color .3s;
}
.rs-nav .rs-switch:hover { background: rgba(0,0,0,0.11); border-color: #7E7E7E; }
.rs-nav .rs-switch .rs-knob {
  position: absolute; top: 3px; left: 3px;
  width: calc(2.1rem - 8px); height: calc(2.1rem - 8px);
  display: grid; place-items: center;
  background: #6A6A6A;
  transition: transform 300ms cubic-bezier(.33,.02,.16,1), background .3s;
}
/* inner width minus knob width: the 3px paddings cancel out exactly */
.rs-nav .rs-switch[aria-pressed="false"] .rs-knob { transform: translateX(calc(5rem - 2.1rem)); }
.rs-switch .rs-knob svg { width: 14px; height: 14px; }
/* the pictogram is cut out of the knob in the page's own ground colour */
/* The knob shows the DESTINATION, not the state: a moon while the room is lit,
   a bulb while it is dark. That is how a light switch behaves; a status light
   would do the opposite. */
.rs-switch .rs-bulb { fill: none; stroke: #F0F0F0; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; display: none; }
.rs-switch .rs-moon { fill: #F0F0F0; stroke: none; display: block; }
.rs-switch[aria-pressed="false"] .rs-bulb { display: block; }
.rs-switch[aria-pressed="false"] .rs-moon { display: none; }
/* while reading there is nothing for it to offer but undoing the dim */
.rs-nav .rs-switch[disabled] { cursor: default; border-color: #C2C2C2; background: rgba(0,0,0,0.03); }
.rs-nav .rs-switch[disabled]:hover { border-color: #C2C2C2; background: rgba(0,0,0,0.03); }
.rs-nav .rs-switch[disabled] .rs-knob { background: #8E8E8E; }

.rs-gallery .rs-tg:focus-visible,
.rs-gallery .rs-nav button:focus-visible,
.rs-gallery .rs-switch:focus-visible { outline: 1px solid rgba(0,0,0,0.55); outline-offset: 3px; }

.rs-readout { display: grid; gap: 0.5rem; justify-items: end; text-align: right; }
.rs-plan { display: flex; align-items: center; gap: 5px; }
.rs-mark { width: 16px; height: 3px; background: #C9C9C9; }
.rs-mark.on { background: var(--rs-ink); }
.rs-mark.grouped { width: 26px; }
.rs-mark.l { transform: translateY(-3px); }
.rs-mark.r { transform: translateY(3px); }

/* ---- the left of the control row: leaving ---------------------------------
   Exit came down from the top-right corner to sit in the row. Everything a
   visitor can do now lives on one line instead of one control in a corner.
   The glass leader moved on again, into .rs-nav between the back arrow and the
   light, so .rs-lead usually carries Exit alone. Its rules stay here: the
   button keeps an arrow's footprint either way, and .rs-nav button restates the
   same width, height, fill and frame at higher specificity, so nothing shifts. */
.rs-lead { display: flex; align-items: center; gap: 0.4rem; order: -1; pointer-events: auto; }

.rs-exit {
  appearance: none; font-family: 'Raleway', system-ui, sans-serif; font-weight: 400;
  cursor: pointer; height: 2.1rem; padding: 0 0.85rem;
  display: grid; place-items: center;
  font-size: 0.72rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--rs-nav-ink); background: rgba(0,0,0,0.07); border: 1px solid var(--rs-nav-frame);
  transition: background .3s, border-color .3s, color .3s;
}
.rs-exit:hover { color: var(--rs-ink); border-color: #7E7E7E; background: rgba(0,0,0,0.11); }

/* the leader wears an arrow's footprint exactly */
.rs-leader {
  position: relative; appearance: none; font: inherit; cursor: pointer;
  width: 3rem; height: 2.1rem; padding: 0; display: grid; place-items: center;
  color: var(--rs-nav-ink); background: rgba(0,0,0,0.07); border: 1px solid var(--rs-nav-frame);
  transition: background .3s, border-color .3s, color .3s;
}
.rs-leader:hover { color: var(--rs-ink); border-color: #7E7E7E; background: rgba(0,0,0,0.11); }
.rs-leader svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round; }
.rs-leader .rs-ico { position: absolute; inset: 0; display: grid; place-items: center; }

/* Open is a pressed button, not a different button. The frame closes in and the
   fill deepens; the mark on it never changes, so nothing has to be re-read. */
.rs-gallery.reading .rs-nav .rs-leader {
  color: #E6E6E6; border-color: #9A9A9A; background: rgba(255,255,255,0.14);
}
.rs-gallery.reading .rs-nav .rs-leader:hover {
  color: #FFF; border-color: #B4B4B4; background: rgba(255,255,255,0.19);
}

.rs-exit:focus-visible, .rs-leader:focus-visible { outline: 1px solid rgba(0,0,0,0.55); outline-offset: 3px; }

/* ---- the instruments follow the room ------------------------------------ */

.rs-gallery.lights-off .rs-code { color: #B4B4B4; }
.rs-gallery.lights-off .rs-readout-dims { color: #7E7E7E; }
.rs-gallery.lights-off .rs-readout-dims b { color: #E6E6E6; }
.rs-gallery.lights-off .rs-desk { background: rgba(12,12,12,0.86); border-color: #2C2C2C; }
.rs-gallery.lights-off .rs-desk h2,
.rs-gallery.lights-off .rs-ctl label { color: #8A8A8A; }
.rs-gallery.lights-off .rs-ctl output { color: #E6E6E6; }
.rs-gallery.lights-off input[type=range] { background: #3A3A3A; }
.rs-gallery.lights-off input[type=range]::-webkit-slider-thumb { background: #E6E6E6; }
.rs-gallery.lights-off input[type=range]::-moz-range-thumb { background: #E6E6E6; }
.rs-gallery.lights-off .rs-tg { border-color: #2C2C2C; color: #8A8A8A; }
.rs-gallery.lights-off .rs-tg:hover { color: #E6E6E6; border-color: #4A4A4A; }
/* the dark wall reads #181818 where the controls sit, so the lit room's problem
   was here in mirror image: the old #2C2C2C frame came to 1.27:1.
     ink #9E9E9E  6.6:1     frame #5A5A5A  2.6:1  — the lit room's pair, inverted */
.rs-gallery.lights-off {
  --rs-nav-ink: #9E9E9E;
  --rs-nav-frame: #5A5A5A;
}
.rs-gallery.lights-off .rs-nav button:hover,
.rs-gallery.lights-off .rs-exit:hover,
.rs-gallery.lights-off .rs-leader:hover { color: #E6E6E6; border-color: #8A8A8A; }
.rs-gallery.lights-off .rs-nav button[disabled],
.rs-gallery.lights-off .rs-nav button[disabled]:hover {
  color: #6A6A6A; border-color: #3A3A3A; background: rgba(255,255,255,0.03);
}
.rs-gallery.lights-off .rs-nav button,
.rs-gallery.lights-off .rs-exit,
.rs-gallery.lights-off .rs-leader { background: rgba(255,255,255,0.05); }
.rs-gallery.lights-off .rs-nav button:hover,
.rs-gallery.lights-off .rs-exit:hover,
.rs-gallery.lights-off .rs-leader:hover { background: rgba(255,255,255,0.09); }
.rs-gallery.lights-off .rs-tg[aria-pressed="true"] { background: #E6E6E6; color: #0A0A0A; border-color: #E6E6E6; }
.rs-gallery.lights-off .rs-nav .rs-switch { background: rgba(255,255,255,0.05); border-color: var(--rs-nav-frame); }
.rs-gallery.lights-off .rs-nav .rs-switch:hover { background: rgba(255,255,255,0.09); border-color: #8A8A8A; }
.rs-gallery.lights-off .rs-nav .rs-switch .rs-knob { background: #7E7E7E; }
.rs-gallery.lights-off .rs-switch .rs-bulb { stroke: #0E0E0E; }
.rs-gallery.lights-off .rs-switch .rs-moon { fill: #0E0E0E; }
.rs-gallery.lights-off .rs-mark { background: #3A3A3A; }
.rs-gallery.lights-off .rs-mark.on { background: #E6E6E6; }
.rs-gallery.lights-off .rs-tg:focus-visible,
.rs-gallery.lights-off .rs-nav button:focus-visible,
.rs-gallery.lights-off .rs-switch:focus-visible,
.rs-gallery.lights-off .rs-exit:focus-visible,
.rs-gallery.lights-off .rs-leader:focus-visible { outline-color: rgba(255,255,255,0.7); }

/* ---- visitor mode ------------------------------------------------------- */
/* One flag. What survives: the wall, the print, the joints and their dimensions,
   and the control block. Nothing else. */

.rs-gallery:not([data-mode="editor"]) .rs-desk,
.rs-gallery:not([data-mode="editor"]) .rs-readout-dims,
.rs-gallery:not([data-mode="editor"]) .rs-code,
.rs-gallery:not([data-mode="editor"]) .rs-plan,
.rs-gallery:not([data-mode="editor"]) .rs-scale { display: none; }
/* The control block used to be alone in this row, so it was pinned right. It no
   longer is: Exit and the leader hold the left end. */
.rs-gallery:not([data-mode="editor"]) .rs-foot { justify-content: space-between; }
/* The desk leaves the control row entirely. As a flex item it was shunting the
   leader and the walk around every time it changed size or side; docked, the row
   below reads the same in the editor as it does for a visitor — leader at the
   left end, walk at the right — and the desk is simply an instrument over the
   room. It sits top left to design the hang, top right to design the glass,
   which is the side the panel does not cover. */
.rs-gallery[data-mode="editor"] .rs-desk {
  position: absolute; top: 1.3rem; left: 1.7rem; right: auto; margin: 0;
  max-height: calc(100% - 7rem);
}

/* ---- the desk, organised -------------------------------------------------
   The desk carries twenty-five controls now. As one column it is taller than a
   laptop screen, and the toggles at its foot were running off the bottom — so
   it is two panes behind a tab strip, and it never grows past the room it is in. */
.rs-desk { max-height: calc(100vh - 6rem); overflow-y: auto; overscroll-behavior: contain; }
.rs-gallery[data-fill="box"] .rs-desk { max-height: none; }

.rs-tabs { display: flex; gap: 0.3rem; }
.rs-tab {
  appearance: none; font: inherit; cursor: pointer; flex: 1 1 0;
  font-size: 0.52rem; letter-spacing: 0.2em; text-transform: uppercase;
  padding: 0.5rem 0.6rem; color: var(--rs-grey);
  background: none; border: 1px solid var(--rs-hair);
  transition: color .3s, border-color .3s, background .3s;
}
.rs-tab:hover { color: var(--rs-ink); border-color: #B4B4B4; }
.rs-tab[aria-pressed="true"] { background: var(--rs-ink); color: #FFF; border-color: var(--rs-ink); }
.rs-tab:focus-visible { outline: 1px solid rgba(0,0,0,0.55); outline-offset: 2px; }
.rs-pane { display: grid; gap: 0.6rem; }
.rs-pane[hidden] { display: none; }

.rs-gallery[data-mode="editor"][data-tab="glass"] .rs-desk { left: auto; right: 1.7rem; }

.rs-gallery.lights-off .rs-tab { color: #9E9E9E; border-color: #5A5A5E; }
.rs-gallery.lights-off .rs-tab:hover { color: #E6E6E6; border-color: #8A8A8A; }
.rs-gallery.lights-off .rs-tab[aria-pressed="true"] { background: #E6E6E6; color: #0A0A0A; border-color: #E6E6E6; }

/* ---- narrow ------------------------------------------------------------- */

@media (max-width: 860px) {
  .rs-hud { padding: 0.85rem; }
  .rs-row { flex-direction: column; gap: 0.8rem; }
  .rs-readout-dims { text-align: left; }
  .rs-foot { flex-direction: column; align-items: stretch; }
  .rs-readout { justify-items: start; text-align: left; }
}

/* The walk is the content here, so Reduce Motion shortens it rather than cutting
   it to a jump — handled in JS, deliberately not with `transition: none`. */

/* this wall's own height — the one per-wall decision the desk carries */
.rs-gallery .rs-own output.is-own { color: var(--rs-ink); }


/* ═══ THE GLASS WALL ════════════════════════════════════════════════════════
   The wall carries the photograph. Title, subtitle and the edition statement
   arrive together on a glass layer that slides in from the left, or not at all.
   Opening it dims the room — you dim a room to read in it. */

.rs-scrim {
  position: absolute; inset: 0; z-index: 5; background: #000;
  opacity: 0; pointer-events: none;
  transition: opacity var(--glass-slide) var(--glass-ease);
}
.rs-gallery.reading .rs-scrim { opacity: var(--read-dim); }

/* reading dims the room without touching the visitor's own lights setting,
   which is restored untouched when the glass closes */
.rs-gallery.reading .rs-plate-dark { opacity: 1; }

.rs-glass {
  position: absolute; top: 0; bottom: 0; left: 0; z-index: 6;
  width: var(--glass-width);
  transform: translateX(-101%);
  transition: transform var(--glass-slide) var(--glass-ease);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(0.92);
  backdrop-filter: blur(var(--glass-blur)) saturate(0.92);
  background: var(--glass-tint);
  border-right: 1px solid var(--glass-edge);
  box-shadow: 14px 0 46px rgba(0,0,0,0.42);
  display: flex; flex-direction: column;
  padding: var(--glass-inset) var(--glass-inset) var(--text-clear);
  overflow: hidden; color: var(--glass-ink);
  font-family: 'Raleway', system-ui, sans-serif;
}
.rs-gallery.reading .rs-glass { transform: translateX(0); }
/* at full bleed there is no edge left to catch light */
.rs-gallery.glass-full .rs-glass { border-right: 0; box-shadow: none; }

.rs-glass-head { display: flex; align-items: baseline; gap: 0.9em; flex-wrap: wrap;
  margin-bottom: 1.1em; flex: 0 0 auto; }
.rs-glass-code { font-weight: 200; line-height: 1; letter-spacing: 0.04em;
  font-size: calc(var(--glass-size) * var(--glass-title)); }
.rs-glass-sub  { font-style: italic; font-weight: 400;
  font-size: calc(var(--glass-size) * 1.18); }

.rs-glass-body {
  font-size: var(--glass-size);
  column-count: var(--glass-cols);
  column-gap: calc(var(--glass-size) * 2.4);
  font-weight: var(--glass-weight); line-height: var(--glass-lead);
  text-align: left; hyphens: auto; orphans: 2; widows: 2;
  flex: 1 1 auto; min-height: 0; overflow: hidden; column-fill: balance;
}
/* Every vertical increment is a whole multiple of the line box, so a paragraph
   break cannot shift a column off the rhythm and the columns keep matching
   baselines. A fractional gap here is what breaks that. */
.rs-glass-body p { margin: 0 0 calc(var(--glass-lead) * var(--glass-para) * 1em); }
.rs-glass-body p:last-child { margin-bottom: 0; }

/* the rule and the imprint sit below the text's keep-out and above the row */
.rs-glass-foot {
  position: absolute; left: var(--glass-inset); right: var(--glass-inset);
  bottom: var(--btn-zone); padding-top: 0.7em;
  border-top: 1px solid currentColor; opacity: 0.62;
  font-family: ui-monospace, Menlo, monospace;
  font-size: calc(var(--glass-size) * 0.62);
  letter-spacing: 0.14em; text-transform: uppercase;
}

/* On a phone the panel is the page and two columns of 12px is not reading. */
@media (max-width: 860px) {
  .rs-gallery { --glass-width: 100%; --glass-cols: 1; }
  .rs-gallery .rs-glass { border-right: 0; box-shadow: none; }
}

/* the instruments follow the dimmed room exactly as they follow lights-off */
.rs-gallery.reading .rs-nav button,
.rs-gallery.reading .rs-exit,
.rs-gallery.reading .rs-leader {
  color: #9E9E9E; border-color: #5A5A5E; background: rgba(255,255,255,0.05);
}
.rs-gallery.reading .rs-nav button:hover,
.rs-gallery.reading .rs-exit:hover,
.rs-gallery.reading .rs-leader:hover { color: #E6E6E6; border-color: #8A8A8A; }

@media (prefers-reduced-motion: reduce) {
  .rs-glass, .rs-scrim { transition-duration: 1ms; }
}
