/* ---------------------------------------------------------------------------
   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;
  --rs-panel: rgba(255, 255, 255, 0.88);
  --rs-ground: #E9E9E9;

  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; }

.rs-stage { position: absolute; inset: 0; overflow: hidden; }
.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); }
.rs-plate-dark { background-image: var(--rs-wall-dark); opacity: 0; transition: opacity 900ms ease; }
.rs-flip { transform: scaleX(-1); }
.rs-gallery.lights-off { background: #0A0A0A; }
.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; }
/* 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); }
.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 */
.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;
}

/* 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: 5;
}
/* 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. */

.rs-nav { display: flex; gap: 0.4rem; align-items: center; }
.rs-nav button {
  appearance: none; font: inherit; color: var(--rs-grey); cursor: pointer;
  width: 3rem; height: 2.1rem; padding: 0;
  display: grid; place-items: center;
  background: rgba(0,0,0,0.045); border: 1px solid var(--rs-hair);
  transition: background .3s, border-color .3s, color .3s;
}
.rs-nav button svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.5; }
.rs-nav button:hover { background: rgba(0,0,0,0.08); color: var(--rs-ink); border-color: #9A9A9A; }
.rs-nav button[disabled] { opacity: 0.35; cursor: default; }
.rs-nav button[disabled]:hover { background: rgba(0,0,0,0.045); color: var(--rs-grey); border-color: var(--rs-hair); }

/* 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.045); border: 1px solid var(--rs-hair);
  transition: background .3s, border-color .3s;
}
.rs-nav .rs-switch:hover { background: rgba(0,0,0,0.08); border-color: #9A9A9A; }
.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: rgba(122,122,122,0.85);
  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 */
.rs-switch .rs-sun { fill: none; stroke: #F0F0F0; stroke-width: 1.7; stroke-linecap: round; }
.rs-switch .rs-moon { fill: #F0F0F0; stroke: none; display: none; }
.rs-switch[aria-pressed="false"] .rs-sun { display: none; }
.rs-switch[aria-pressed="false"] .rs-moon { display: block; }

.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-hint { font-size: 0.5rem; letter-spacing: 0.24em; text-transform: uppercase; color: #9A9A9A; }
.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.l { transform: translateY(-3px); }
.rs-mark.r { transform: translateY(3px); }

/* close: visitor mode only, and only when the gallery is an overlay */
.rs-close {
  position: absolute; top: 1.3rem; right: 1.7rem; z-index: 6;
  appearance: none; font: inherit; cursor: pointer; pointer-events: auto;
  width: 2.4rem; height: 2.4rem; display: grid; place-items: center;
  color: var(--rs-grey); background: rgba(0,0,0,0.045); border: 1px solid var(--rs-hair);
  transition: background .3s, border-color .3s, color .3s;
}
.rs-close:hover { color: var(--rs-ink); border-color: #9A9A9A; background: rgba(0,0,0,0.08); }
.rs-close svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.4; }
.rs-close: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,
.rs-gallery.lights-off .rs-nav button,
.rs-gallery.lights-off .rs-close { border-color: #2C2C2C; color: #8A8A8A; }
.rs-gallery.lights-off .rs-tg:hover,
.rs-gallery.lights-off .rs-nav button:hover,
.rs-gallery.lights-off .rs-close:hover { color: #E6E6E6; border-color: #4A4A4A; }
.rs-gallery.lights-off .rs-nav button { background: rgba(255,255,255,0.05); }
.rs-gallery.lights-off .rs-nav button: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: #2C2C2C; }
.rs-gallery.lights-off .rs-nav .rs-switch:hover { background: rgba(255,255,255,0.09); border-color: #4A4A4A; }
.rs-gallery.lights-off .rs-nav .rs-switch .rs-knob { background: rgba(122,122,122,0.72); }
.rs-gallery.lights-off .rs-switch .rs-sun { stroke: #0E0E0E; }
.rs-gallery.lights-off .rs-switch .rs-moon { fill: #0E0E0E; }
.rs-gallery.lights-off .rs-hint { color: #5A5A5A; }
.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-close: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; }
.rs-gallery[data-mode="editor"] .rs-close { display: none; }
/* with the desk gone, the control block is the only thing in the row — it keeps
   its corner rather than sliding to where the desk used to be */
.rs-gallery:not([data-mode="editor"]) .rs-foot { justify-content: flex-end; }

/* ---- 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; }
  .rs-close { top: 0.85rem; right: 0.85rem; }
}

/* 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`. */
