/* =====================================================================
   RSIG IMAGE SCROLLER AND LIGHTBOX (assets/scroller.css, used with assets/scroller.js)
   A horizontal rail of photos with CSS scroll snap. The first photo is featured (larger).
   Every colour, face and easing comes from the tokens in site.css.
   The base lightbox rules (.lb, .lb__bar, .lb__stage, .lb__foot) live in site.css; this file adds to them.
   ===================================================================== */

.scr{--pad:max(var(--gutter),calc((100vw - var(--wrap))/2));--h:clamp(240px,min(27vw,50vh),480px);--gap:clamp(12px,1.6vw,24px);--fade:0px;--fadeL:0px;--fadeR:0px;
  position:relative}
.scr.has-more-r{--fadeR:clamp(40px,7vw,120px)}
.scr.has-more-l{--fadeL:clamp(28px,4vw,72px)}

/* the instrument bar: counter, progress hairline, previous and next */
.scr__bar{display:flex;align-items:center;gap:14px clamp(16px,2.4vw,28px);flex-wrap:wrap;margin-bottom:clamp(16px,2.4vh,26px)}
.scr__count{display:inline-flex;align-items:baseline;gap:.5em;min-width:6.6em;color:var(--text-primary);white-space:nowrap}
.scr__count b{font-weight:500}
.scr__count i{font-style:normal;color:var(--text-secondary)}
.scr__track{position:relative;flex:1 1 140px;min-width:80px;height:11px;
  background:
    linear-gradient(var(--rule),var(--rule)) left center/100% 1px no-repeat,
    linear-gradient(var(--rule-strong),var(--rule-strong)) left center/1px 11px no-repeat,
    linear-gradient(var(--rule-strong),var(--rule-strong)) right center/1px 11px no-repeat}
.scr__thumb{position:absolute;left:0;top:5px;width:var(--tw,25%);height:1px;background:var(--accent);transform:translate3d(var(--tx,0px),0,0)}
.scr__thumb::before,.scr__thumb::after{content:"";position:absolute;top:-4px;width:1px;height:9px;background:var(--text-primary)}
.scr__thumb::before{left:0}.scr__thumb::after{right:0}
.scr__btns{display:flex;gap:10px;margin-left:auto}
.scr__btns .ibtn{width:48px;height:48px}
.scr__hint{flex:1 1 100%;color:var(--text-secondary);font-size:.92rem}

/* the viewport bleeds to the page edge on the right, and carries the edge fade that shows there is more */
.scr__vp{position:relative;margin-inline:calc(50% - 50vw)}
.scr__rail{display:flex;align-items:flex-end;gap:var(--gap);margin:0;padding:8px var(--pad) 18px;list-style:none;
  overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;scroll-padding-inline:var(--pad);overscroll-behavior-x:contain;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;cursor:grab;
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 var(--fadeL),#000 calc(100% - var(--fadeR)),transparent 100%);
          mask-image:linear-gradient(to right,transparent 0,#000 var(--fadeL),#000 calc(100% - var(--fadeR)),transparent 100%)}
.scr__rail::-webkit-scrollbar{display:none}
.scr__rail:focus-visible{outline:2px solid var(--accent);outline-offset:-4px;box-shadow:inset 0 0 0 5px var(--text-primary)}
.scr__rail.is-drag{scroll-snap-type:none;cursor:grabbing;-webkit-user-select:none;user-select:none}
.scr__rail.is-drag a{pointer-events:none}
.scr--one .scr__rail{cursor:default}

/* one photo: a framed plate with a drawn index, a hairline that fills on hover, and its caption below */
.scr__item{position:relative;flex:none;width:calc(var(--h)*.8*1.333);scroll-snap-align:start;margin:0}
.scr__item--feat{width:min(calc(var(--h)*1.25*1.5),calc(100vw - 2*var(--pad)))}
.scr__ph{position:relative;display:block;height:calc(var(--h)*.8);overflow:hidden;background:var(--panel);border:1px solid var(--rule);
  color:inherit;text-decoration:none;cursor:zoom-in;transition:border-color .5s var(--ease-out)}
.scr__item--feat .scr__ph{height:calc(var(--h)*1.25)}
.scr__ph img{width:100%;height:100%;object-fit:cover;opacity:.84;transform:scale(1.001);
  transition:opacity .8s var(--ease-out),transform 1.2s var(--ease-out);-webkit-user-drag:none;user-select:none}
.scr__item.is-cur .scr__ph img,.scr__ph:hover img,.scr__ph:focus-visible img{opacity:1}
.scr__ph:hover img{transform:scale(1.035)}
/* ROUND 4 (owner 2026-09-26: no outlined box lights under the cursor on photos of people): the frame keeps its colour on hover */
.scr__ph:focus-visible{outline-offset:3px}
/* a soft Charcoal Umber floor under the index, so the numeral always reads */
.scr__ph::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(to bottom,rgba(38,32,26,0) 70%,rgba(38,32,26,.6))}
/* the Sanguine hairline along the bottom edge, drawn in on hover and on the current photo */
.scr__ph::after{content:"";position:absolute;left:0;right:0;bottom:0;z-index:2;height:2px;background:var(--accent);
  transform:scaleX(0);transform-origin:left center;transition:transform .9s var(--ease-out)}
.scr__item.is-cur .scr__ph::after,.scr__ph:hover::after,.scr__ph:focus-visible::after{transform:scaleX(1)}
/* ROUND1 (programs-events builder): the index is a small folio tab in the corner on its own ink ground, never a large numeral over faces */
.scr__num{position:absolute;left:0;top:0;z-index:2;display:inline-flex;align-items:center;gap:.5em;padding:7px 10px 7px 9px;
  font-family:var(--f-mono);font-size:11px;font-weight:400;line-height:1;letter-spacing:.16em;color:var(--text-primary);
  background:rgba(24,19,15,.84);border-right:1px solid var(--rule);border-bottom:1px solid var(--rule);font-variant-numeric:tabular-nums}
.scr__num::before{content:"";width:10px;height:1px;background:var(--accent)}
.scr__open{position:absolute;right:12px;bottom:12px;z-index:2;display:inline-flex;align-items:center;gap:.6em;min-height:32px;padding:0 12px;
  background:var(--chip-bg);border:1px solid var(--rule);border-radius:2px;color:var(--text-primary);opacity:0;transform:translateY(4px);
  transition:opacity .5s var(--ease-out),transform .5s var(--ease-out)}
.scr__ph:hover .scr__open,.scr__ph:focus-visible .scr__open{opacity:1;transform:none}
.scr__item--feat .scr__open{opacity:1;transform:none}
.scr__cap{display:grid;gap:4px;padding:12px 2px 0;color:var(--text-secondary);font-size:.92rem;line-height:1.45}
.scr__cap p{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.scr__cap .t-mono{color:var(--text-secondary)}
.scr__cap a{display:inline-flex;align-items:center;min-height:44px;color:var(--text-primary);font-family:var(--f-head);font-weight:600;font-size:.9rem;letter-spacing:.03em;
  text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:4px;text-decoration-color:var(--rule-strong)}
.scr__cap a:hover{text-decoration-color:currentColor}

/* the source note under a gallery */
.scr__note{margin-top:clamp(14px,2vh,22px);color:var(--text-secondary);font-size:.92rem;max-width:62ch}

@media (max-width:720px){
  .scr{--h:min(64vw,320px)}
  .scr__item{width:min(calc(var(--h)*.8*1.333),72vw)}
  .scr__item--feat{width:calc(100vw - 2*var(--pad))}
  .scr__open{opacity:1;transform:none}
  .scr__track{flex:1 1 60px}
  .scr__bar{gap:12px 16px}
}
@media (pointer:coarse){.scr__rail{cursor:auto}.scr__ph{cursor:pointer}}

/* ---------- the lightbox additions: the full image link, the event link, a calm entrance ---------- */
.lb__tools{display:flex;align-items:center;gap:8px clamp(12px,2vw,24px);flex-wrap:wrap;justify-content:flex-end}
.lb__tools .link{font-size:.9rem}
.lb__lead{display:flex;align-items:center;gap:16px;min-width:0}
.lb__stage img{transition:opacity .45s var(--ease-out)}
.lb__stage img.is-loading{opacity:0}
.lb__stage{touch-action:pan-y pinch-zoom}   /* FORM FACTOR: two fingers zoom into the picture natively; one finger sideways still changes it */
.lb__cap a{color:var(--text-primary)}
.lb[open]{animation:lbIn .5s var(--ease-out) both}
@keyframes lbIn{from{opacity:0}to{opacity:1}}
@media (max-width:560px){.lb__bar{flex-wrap:wrap}.lb__tools{justify-content:flex-start}}

/* ---------- motion gates: reduced motion (unless the visitor chose Motion: on) and the Motion switch ---------- */
@media (prefers-reduced-motion: reduce){
  html:not(.motion-on) .scr__rail{scroll-behavior:auto}
  html:not(.motion-on) .scr__ph img,html:not(.motion-on) .scr__ph::after,html:not(.motion-on) .scr__open,html:not(.motion-on) .lb__stage img{transition:none !important}
  html:not(.motion-on) .scr__ph:hover img{transform:none}
  html:not(.motion-on) .lb[open]{animation:none}
}
html.still .scr__rail{scroll-behavior:auto}
html.still .scr__ph img,html.still .scr__ph::after,html.still .scr__open,html.still .lb__stage img{transition:none !important}
html.still .scr__ph:hover img{transform:none}
html.still .lb[open]{animation:none}

@media (forced-colors:active){.scr__rail{-webkit-mask-image:none;mask-image:none}.scr__thumb{background:Highlight}.scr__ph{border-color:CanvasText}}
/* without JavaScript the rail is still a plain scrolling list of links to the full photos */
html.no-js .scr__bar{display:none}

/* =====================================================================
   SLIDER OUTLINE (owner, 2026-09-21): "image slider should have the same moving outline". Every photo in the scroller gets a thin ember
   frame and a small glowing bead that keeps travelling around it, like the spark on the portrait rings and the light on the picture plates.
   Drawn on the slide (.scr__item), around the photo area only (the caption below is left out), because the photo box clips its overflow.
   Phased by position so neighbours never move in step. html.still: the calm frame only.
   ===================================================================== */
.scr__item{--ph:calc(var(--h) * .8)}
.scr__item--feat{--ph:calc(var(--h) * 1.25)}
.scr__item::before{content:"";position:absolute;left:-1px;right:-1px;top:-1px;height:calc(var(--ph) + 2px);z-index:3;pointer-events:none;
  border:1px solid rgba(217,138,75,.45);box-shadow:0 0 16px rgba(168,67,46,.2)}
@supports (offset-path: inset(0 round 0)) {
  .scr__item::after{content:"";position:absolute;left:0;top:0;width:6px;height:6px;border-radius:50%;z-index:4;pointer-events:none;background:#FFF1DE;
    box-shadow:0 0 6px 2px rgba(255,210,160,.95),0 0 16px 5px rgba(255,160,100,.42);
    offset-path:inset(-1px -1px calc(100% - var(--ph) - 1px) -1px);offset-anchor:center;offset-rotate:0deg;
    animation:scrTrace 12s linear var(--sd, 0s) infinite}
}
@keyframes scrTrace{from{offset-distance:0%}to{offset-distance:100%}}
.scr__item:nth-child(4n+2){--sd:-3s}.scr__item:nth-child(4n+3){--sd:-6s}.scr__item:nth-child(4n+4){--sd:-9s}
html.still .scr__item::after{display:none}
@media (forced-colors:active){.scr__item::before,.scr__item::after{display:none}}
/* phones: the large first photo keeps the photo's own 3:2 shape, so a group photo never loses people at the sides */
@media (max-width:720px){
  .scr__item--feat{--ph:calc((100vw - 2 * var(--pad)) / 1.5)}
  .scr__item--feat .scr__ph{height:var(--ph)}
}
/* FORM FACTOR: phone reading size for the captions and the swipe hint (this file loads after site.css, so the rule lives here) */
@media (max-width:560px){.scr__cap,.scr__hint{font-size:1rem}}

/* =====================================================================
   PERFECTION PASS (chrome builder, 2026-09-22, site-todo 77: "make sure they are framed properly", "it shouldn't hang despite file size").
   1. Every rail frame takes its photo's own shape (--ar, set by scroller.js from the photo's width and height, 1 to 1.8), so a 3:2 group
      photo is never cut at the sides. Photos without sizes keep the old 4:3 frame. A phone caps a frame at 80 % of the screen width; the
      panel's "Keep in view" choice (object-position) then decides which side stays.
   2. The travelling bead runs only on the photos in view (.is-vis from an IntersectionObserver), not on all 36.
   3. The viewer keeps the current picture while the next one decodes, dimmed only if the wait is long.
   ===================================================================== */
.scr__item{width:calc(var(--h) * .8 * var(--ar,1.333))}
.scr__item--feat{width:min(calc(var(--h) * 1.25 * var(--ar,1.5)),calc(100vw - 2 * var(--pad)))}
@media (max-width:720px){
  .scr__item{width:min(calc(var(--h) * .8 * var(--ar,1.333)),80vw)}
  .scr__item--feat{width:calc(100vw - 2 * var(--pad));--ph:calc((100vw - 2 * var(--pad)) / var(--ar,1.5))}
}
.scr--io .scr__item:not(.is-vis)::after{display:none}
.lb__stage img.is-wait{opacity:.35;transition:opacity .25s var(--ease-out)}
/* END PERFECTION PASS */

/* =====================================================================
   ROUND 2 (programs-events builder): the phone strip. Every photo is large (84 % of the screen wide, the next one peeking in) and keeps
   its own shape (owner item 72: a group photo never loses people at the sides); the caption sits under each photo; the counter and the
   arrows follow the strip; the swipe hint steps aside (the peeking photo says it).
   ===================================================================== */
@media (max-width:720px){
  .scr{display:flex;flex-direction:column}
  .scr__bar{order:2;margin:6px 0 0}
  .scr__hint{display:none}
  .scr__rail{align-items:flex-start;padding-bottom:6px}
  .scr__item,.scr__item--feat{width:84vw;--ph:calc(84vw / var(--ar,1.333))}
  .scr__ph,.scr__item--feat .scr__ph{height:var(--ph)}
  .scr--one .scr__item{width:calc(100vw - 2 * var(--pad))}
}
