/* ====================================================================
   THE PHOTOGRAPHS — /archive/<n>/photos (gallery.js).

   Two movements on the edition's own sky: the galaxy (a fixed layer under
   the page, drawn in WebGL, fading as the page leaves the first screen),
   and the grid. Then the lightbox, the download buttons, and the ruler
   along the right edge.
   ==================================================================== */

/* the sky follows the scroll here, so it must not lag a second behind it */
body.galspace .sky::before,body.galspace .sky #sky3d{transition:opacity .2s linear}
html.glb-on{overflow:hidden}

.gal{position:relative;display:flex;flex-direction:column;gap:clamp(70px,11vh,130px);text-align:left}
.gal .sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* --------------------------------------------------------------------
   1. THE GALAXY
   -------------------------------------------------------------------- */
.gal-sky{position:fixed;inset:0;z-index:-1;pointer-events:none;overflow:hidden}
.gal-sky canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.gal-sky .hall-scene{left:0;top:0;bottom:0;width:100%;transform:none}
.gal-still{position:absolute;object-fit:cover;border-radius:14px;
  box-shadow:0 40px 90px rgba(0,0,0,.55);animation:galstill 1.4s var(--ease) both}
@keyframes galstill{from{opacity:0;transform:scale(.95)}}

/* the first screen itself is empty: the photographs are under it, and it
   only carries a few words in its corners */
.gal-first{position:relative;min-height:calc(100svh - 106px);user-select:none;-webkit-user-select:none}
.gal-hud{position:absolute;left:0;bottom:clamp(70px,9vh,96px);max-width:min(42ch,38vw);
  animation:galup 1.2s var(--ease) 1.1s both}
/* a pool of the page's dark behind the words, so the photographs riding
   past under them never take them */
.gal-hud::before,.gal-hint::before{content:"";position:absolute;z-index:-1;inset:-70px -110px -60px -90px;pointer-events:none;
  background:radial-gradient(closest-side,rgba(4,4,10,.72),rgba(4,4,10,0))}
.gal-kick{margin:0 0 12px;font-family:var(--mono);font-size:10.5px;font-weight:500;letter-spacing:.16em;
  text-transform:uppercase;color:rgba(255,255,255,.62)}
.gal-count{margin:0;font-size:clamp(22px,2.3vw,32px);font-weight:500;line-height:1;letter-spacing:-.01em;color:var(--ink)}
.gal-count b{font-weight:700}
.gal-credit{margin:8px 0 0;font-size:12.5px;color:rgba(255,255,255,.55)}
.gal-hint{position:absolute;right:0;bottom:clamp(70px,9vh,96px);margin:0;max-width:min(28ch,24vw);text-align:right;
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;line-height:1.7;text-transform:uppercase;
  color:rgba(255,255,255,.38);animation:galup 1.2s var(--ease) 1.6s both}
.gal-cue{position:absolute;left:50%;bottom:clamp(60px,8vh,86px);transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:12px;padding:6px 10px;border:0;background:none;
  font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.2em;text-transform:uppercase;
  color:rgba(255,255,255,.72);animation:galupc 1.2s var(--ease) 1.4s both}
.gal-cue i{position:relative;display:block;width:1px;height:46px;overflow:hidden;background:rgba(255,255,255,.18)}
.gal-cue i::after{content:"";position:absolute;left:0;top:-45%;width:1px;height:45%;background:#fff;
  animation:galdrop 2.2s var(--ease) infinite}
.gal-cue:hover{color:#fff}
@keyframes galdrop{to{top:110%}}
@keyframes galup{from{opacity:0;transform:translateY(14px)}}
@keyframes galupc{from{opacity:0;transform:translate(-50%,14px)}}

/* --------------------------------------------------------------------
   2. THE GRID — wider than the house column: photographs want the room
   -------------------------------------------------------------------- */
.gal-body{--gg:72px;--gw:min(1680px,calc(100vw - 2 * var(--gg)));width:var(--gw);
  margin-left:calc(50% - var(--gw) / 2)}
.gal-head{max-width:880px;margin:0 auto clamp(34px,5vh,60px);text-align:center}
.gal-head-kick{margin:0 0 18px;font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:rgba(255,255,255,.55)}
.gal-title{margin-bottom:clamp(16px,2.2vw,26px)}
.gal-sub{margin:0 auto;max-width:52ch;font-size:clamp(15px,1.3vw,18px);line-height:1.6;color:rgba(229,229,229,.78)}
.gal-meta{margin:16px 0 0;font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.5)}
.gal-meta b{font-weight:500;color:#fff}
.gal-head.reveal{opacity:0;transform:translateY(24px);transition:opacity 1s var(--ease),transform 1.1s var(--ease)}
.gal-head.reveal.in{opacity:1;transform:none}

.gal-grid{display:flex;flex-wrap:wrap;gap:var(--gap,10px)}
.gp{position:relative;margin:0;flex:0 0 auto;overflow:hidden;border-radius:6px;background:var(--c,#202024);
  opacity:0;transform:translateY(34px) scale(.97);clip-path:inset(14% 0 0 0 round 6px);
  transition:opacity .9s var(--ease) calc(var(--d,0) * 70ms),
             transform 1.1s var(--ease) calc(var(--d,0) * 70ms),
             clip-path 1.1s var(--ease) calc(var(--d,0) * 70ms)}
.gp.in{opacity:1;transform:none;clip-path:inset(0 0 0 0 round 6px)}
.gp-open{position:absolute;inset:0;display:block;cursor:zoom-in;outline:none}
.gp-open:focus-visible{box-shadow:inset 0 0 0 2px #fff}
.gp img{display:block;width:100%;height:100%;object-fit:cover;opacity:0;transform:scale(1.08);
  filter:blur(8px);transition:opacity .9s var(--ease),transform 1.4s var(--ease),filter .9s var(--ease)}
.gp.ld img{opacity:1;transform:scale(1.001);filter:none}
.gp::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:0;
  background:linear-gradient(to top,rgba(0,0,0,.55),rgba(0,0,0,0) 46%);transition:opacity .45s var(--ease)}
.gp:hover::after,.gp:focus-within::after{opacity:1}
.gp.ld:hover img{transform:scale(1.045)}

/* ---- THE DOWNLOAD BUTTON: a glass pill in the corner, up on hover; its
   ring fills while the file comes down ---- */
.gp-dl{position:absolute;right:10px;bottom:10px;z-index:2;display:inline-flex;align-items:center;gap:8px;
  padding:7px 12px 7px 7px;border:1px solid rgba(255,255,255,.22);border-radius:999px;
  background:rgba(12,12,16,.5);-webkit-backdrop-filter:blur(14px) saturate(1.3);backdrop-filter:blur(14px) saturate(1.3);
  color:#fff;font-size:12px;font-weight:500;line-height:1;text-transform:lowercase;white-space:nowrap;
  opacity:0;transform:translateY(10px);
  transition:opacity .35s var(--ease),transform .45s var(--ease),background .25s var(--ease),border-color .25s var(--ease)}
.gp:hover .gp-dl,.gp:focus-within .gp-dl,.gp-dl.busy,.gp-dl.done{opacity:1;transform:none}
.gp-dl:hover{background:#fff;border-color:#fff;color:#000}
.gp-dl-i{position:relative;display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;
  border-radius:50%;background:rgba(255,255,255,.12)}
.gp-dl:hover .gp-dl-i{background:rgba(0,0,0,.08)}
.gp-dl-i svg{width:14px;height:14px}
.gp-dl-i::before{content:"";position:absolute;inset:-2px;border-radius:50%;opacity:0;
  background:conic-gradient(var(--accent-bright,#ff9552) calc(var(--pc,0) * 360deg),transparent 0);
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 2px),#000 0);
          mask:radial-gradient(farthest-side,transparent calc(100% - 2px),#000 0)}
.gp-dl.busy .gp-dl-i::before{opacity:1}
.gp-dl.busy .gp-dl-i svg{animation:galdl 1s ease-in-out infinite}
.gp-dl.done .gp-dl-i{background:var(--accent,#ff6a1a)}
@keyframes galdl{50%{transform:translateY(2px)}}
.gp-dl-s{font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:none;opacity:.62}
/* a photo too narrow for the words keeps just the ring */
.gp.narrow .gp-dl{padding:6px}
.gp.narrow :is(.gp-dl-t,.gp-dl-s){display:none}
/* a phone has no hover: a tap opens the photo, and the download is under
   it there — a button on every tile would be a wall of buttons */
@media (hover:none){
  .gal-grid .gp-dl{display:none}
}

.gal-nav{margin-top:clamp(10px,2vh,24px)}
.gal-none .bp-acts{display:flex;flex-wrap:wrap;gap:12px;margin-top:28px}

/* --------------------------------------------------------------------
   3. THE LIGHTBOX
   -------------------------------------------------------------------- */
.glb{position:fixed;inset:0;z-index:400;color:#fff}
.glb[hidden]{display:none}
.glb-shade{position:absolute;inset:0;background:rgba(6,6,10,.9);
  -webkit-backdrop-filter:blur(26px) saturate(1.2);backdrop-filter:blur(26px) saturate(1.2);
  opacity:0;transition:opacity .5s var(--ease)}
.glb.on .glb-shade{opacity:1}
.glb-frame{position:absolute;margin:0;overflow:hidden;border-radius:8px;background:var(--c,#1b1b1f);
  transform-origin:0 0;touch-action:none;cursor:grab;
  box-shadow:0 50px 120px rgba(0,0,0,.6);
  transition:transform .6s var(--ease),left .45s var(--ease),top .45s var(--ease),width .45s var(--ease),height .45s var(--ease),opacity .4s var(--ease)}
.glb-frame img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  user-select:none;-webkit-user-drag:none;pointer-events:none}
.glb-hi{opacity:0;transition:opacity .5s var(--ease)}
.glb-hi.on{opacity:1}
.glb:not(.on) .glb-frame{opacity:.0}
.glb.on .glb-frame{opacity:1}
.glb-frame.nx{animation:glbnx .55s var(--ease)}
.glb-frame.pv{animation:glbpv .55s var(--ease)}
@keyframes glbnx{from{opacity:.2;translate:36px 0}}
@keyframes glbpv{from{opacity:.2;translate:-36px 0}}
.glb-top{position:absolute;left:0;right:0;top:0;height:64px;display:flex;align-items:center;justify-content:space-between;
  padding:0 clamp(16px,2.4vw,32px);opacity:0;transition:opacity .4s var(--ease) .1s}
.glb-n{font-family:var(--mono);font-size:11px;letter-spacing:.18em;color:rgba(255,255,255,.7)}
.glb-x,.glb-nav{display:inline-flex;align-items:center;justify-content:center;border:1px solid rgba(255,255,255,.2);
  border-radius:50%;background:rgba(255,255,255,.04);color:#fff;
  transition:background .25s var(--ease),border-color .25s var(--ease),transform .3s var(--ease),opacity .4s var(--ease)}
.glb-x{width:42px;height:42px}
.glb-x svg{width:18px;height:18px}
.glb-nav{position:absolute;top:50%;width:52px;height:52px;margin-top:-26px;opacity:0}
.glb-nav svg{width:22px;height:22px}
.glb-nav.prev{left:clamp(14px,1.8vw,24px)}
.glb-nav.next{right:clamp(14px,1.8vw,24px)}
.glb-x:hover,.glb-nav:hover{background:#fff;border-color:#fff;color:#000}
.glb-nav:hover{transform:scale(1.06)}
.glb-bar{position:absolute;left:0;right:0;bottom:0;height:88px;display:flex;align-items:center;justify-content:center;
  opacity:0;transition:opacity .4s var(--ease) .15s}
.glb.on :is(.glb-top,.glb-bar,.glb-nav){opacity:1}
.glb-dl{position:static;opacity:1;transform:none;padding:9px 16px 9px 9px;font-size:13px}
.glb-dl .gp-dl-i{width:28px;height:28px}
@media (max-width:760px){
  .glb-frame{border-radius:0}
  .glb-nav{display:none}
  .glb-top{height:56px}
  .glb-bar{height:76px}
  .glb-dl .gp-dl-t,.glb-dl .gp-dl-s{display:inline}
}

/* --------------------------------------------------------------------
   4. THE RULER along the right edge (a desk only)
   -------------------------------------------------------------------- */
.gal-ruler{position:fixed;right:0;top:0;width:60px;height:100vh;z-index:150;pointer-events:none}

/* not wide enough for three things along the bottom: the cue goes to the
   right corner and the hint is left out */
@media (max-width:1180px){
  .gal-hint{display:none}
  .gal-cue{left:auto;right:0;transform:none;align-items:flex-end;animation-name:galup}
}
@media (max-width:899px){
  .gal-body{--gg:16px}
}
@media (max-width:760px){
  .gal-hud{bottom:84px;max-width:72vw}
  .gal-cue{bottom:84px;padding:6px 0}
  .gal-cue span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .gal-cue i{height:64px}
  .gp{border-radius:4px}
}
@media (prefers-reduced-motion:reduce){
  .gp,.gp img{transition:none;transform:none;clip-path:none;opacity:1;filter:none}
  .gal-cue i::after{animation:none}
}

/* --------------------------------------------------------------------
   5. THE DOOR in front of them — the edition's sky, the title, and one
   glass card with whatever this visitor still has to do
   -------------------------------------------------------------------- */
.gal-gated{min-height:calc(100vh - 120px);justify-content:center;gap:clamp(40px,7vh,80px)}
.gal-gate{width:min(560px,calc(100vw - 32px));margin:clamp(40px,12vh,140px) auto 0;
  display:flex;flex-direction:column;align-items:stretch;gap:clamp(26px,4vh,40px)}
.gal-gate-head{text-align:center}
.gal-gate-head .gal-title{margin-bottom:0}
.gal-gate-card{position:relative;padding:clamp(24px,4vw,38px);border-radius:18px;
  background:rgba(10,10,12,.62);border:1px solid rgba(255,255,255,.1);
  -webkit-backdrop-filter:blur(18px) saturate(1.2);backdrop-filter:blur(18px) saturate(1.2);
  box-shadow:0 40px 90px rgba(0,0,0,.45)}
.gal-gate-lead{margin:0 0 18px;font-size:15px;line-height:1.65;color:rgba(255,255,255,.82)}
.gal-gate-lead b{color:#fff;font-weight:600}
.gal-gate-card .btn-row{display:flex;flex-wrap:wrap;gap:10px;margin-top:6px}
.gal-gate-alt{margin:18px 0 0;font-size:13px}
.gal-gate-card .acct{margin-top:6px;padding-top:20px;border-top:1px solid rgba(255,255,255,.08)}
.gal-gated .gal-nav{margin-top:auto}
.gp.bad::after{content:'';position:absolute;inset:0;background:repeating-linear-gradient(135deg,rgba(255,255,255,.04) 0 6px,transparent 6px 12px)}

/* --------------------------------------------------------------------
   6. AN ACCOUNT (account.js) — the same box in the door above and in the
   bar's sign-in
   -------------------------------------------------------------------- */
.acct-h{margin:0 0 6px;font-size:20px;font-weight:600;letter-spacing:-.01em;color:#fff}
.acct-hint{margin:0 0 18px;font-size:13.5px;line-height:1.6;color:var(--muted,rgba(255,255,255,.62))}
.acct-form{display:flex;flex-direction:column;gap:16px}
.acct-fld{display:flex;flex-direction:column;gap:6px}
.acct-fld span{font-size:var(--label-size,12px);font-weight:700;text-transform:lowercase;color:var(--muted2,rgba(255,255,255,.55))}
.acct-fld input{width:100%;background:none;border:none;border-bottom:1px solid var(--field-line,rgba(255,255,255,.22));
  padding:8px 0;font-size:16px;color:#fff;outline:none;transition:border-color .2s}
.acct-fld input:focus{border-bottom-color:var(--field-line-focus,#fff)}
.acct-side{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:2px 0 0;padding:0;border:0}
.acct-side legend,.acct-side>span{width:100%;margin-bottom:6px;font-size:var(--label-size,12px);font-weight:700;
  text-transform:lowercase;color:var(--muted2,rgba(255,255,255,.55))}
.acct-pick{position:relative;display:inline-flex;align-items:center;padding:8px 16px;border-radius:999px;cursor:pointer;
  border:1px solid var(--line,rgba(255,255,255,.18));background:none;color:var(--muted,rgba(255,255,255,.7));
  font:inherit;font-size:14px;transition:border-color .2s,color .2s,background .2s}
.acct-pick input{position:absolute;opacity:0;pointer-events:none}
.acct-pick:hover{border-color:#fff;color:#fff}
.acct-pick.on{border-color:var(--accent,#ff6a1a);color:#fff;background:rgba(255,106,26,.14)}
.acct-row{display:flex;flex-wrap:wrap;align-items:center;gap:16px;margin-top:6px}
.acct-msg:empty{display:none}
.acct-alt{margin:14px 0 0;font-size:13px}
.acct-kick{margin:0;font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted2,rgba(255,255,255,.5))}
.acct-rest .acct-side-rest{margin:4px 0 6px}
@media (max-width:760px){
  .gal-gate{margin-top:clamp(24px,6vh,60px)}
  .gal-gate-card{border-radius:14px}
}

/* ---- the download's choice: JPEG, PNG or AVIF ---- */
.gdl-menu{position:fixed;z-index:400;min-width:210px;padding:8px;border-radius:14px;
  background:rgba(14,14,16,.92);border:1px solid rgba(255,255,255,.12);
  -webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);box-shadow:0 24px 60px rgba(0,0,0,.5);
  opacity:0;transform:translateY(6px) scale(.98);transition:opacity .2s var(--ease),transform .25s var(--ease)}
.gdl-menu.on{opacity:1;transform:none}
.gdl-t{margin:4px 10px 6px;font-family:var(--mono);font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.45)}
.gdl-o{display:flex;width:100%;align-items:baseline;justify-content:space-between;gap:14px;padding:9px 10px;border:0;border-radius:9px;
  background:none;color:#fff;font:inherit;font-size:14px;text-align:left;cursor:pointer;transition:background .15s}
.gdl-o span{font-size:12px;color:rgba(255,255,255,.5)}
.gdl-o:hover,.gdl-o:focus-visible{background:rgba(255,255,255,.1);outline:none}
.gdl-o.on b::after{content:'';display:inline-block;width:6px;height:6px;margin-left:8px;border-radius:50%;
  background:var(--accent,#ff6a1a);vertical-align:middle}
.gp-dl.making .gp-dl-i{animation:gdlpulse 1s ease-in-out infinite}
@keyframes gdlpulse{50%{opacity:.45}}
