/* ============================================================================
   galleries.css — ONE full-bleed gallery for "Life at Eden" + "Inside Eden"
   ----------------------------------------------------------------------------
   Client feedback (verbatim):
     · "Life at eden page: need a change in UI, all renders need to seen in
        full screen. keep it simple."
     · "Inside eden: Change UI, all renders need to be seen full screen."

   Direction: the RENDER IS THE SCREEN. One shared pattern for both views —
   an edge-to-edge cover image filling the whole view, swiped left/right, with
   only a few glass pills floating on top of it (title · category · counter ·
   Save · category chips on Life). No copy panel, no orb cluster, no filmstrip
   reel, no scrubber, no "full screen" chip (the view IS full screen).

   Loaded after estate-plan.css; every colour is a token so theme-green.css
   (brighter brand green, loads last) stays the single source of surface truth.
   ============================================================================ */

/* ── The frame ─────────────────────────────────────────────────────────────── */
.gallery-view{
  padding:0!important;
  background:var(--e-ground);
  overflow:hidden;
}
/* the app-wide view rise (finish-kit fkViewIn) translates the whole view, which
   would drag the render up with it — the image must arrive by a pure fade. */
.gallery-view.is-active{animation:none!important}

.gal{
  position:absolute; inset:0;
  overflow:hidden;
  isolation:isolate;
  --gal-gutter:20px;
  --gal-lift:0px;            /* raised when the thumbnail strip is open */
}

/* ── The render ────────────────────────────────────────────────────────────── */
.gal-stage{
  position:absolute; inset:0;
  z-index:0;
  background:var(--e-ground);
  touch-action:none;          /* the swipe is ours — nothing scrolls under it */
  cursor:grab;
  overflow:hidden;            /* a zoomed render is clipped to the frame */
}
.gal-stage:active{cursor:grabbing}

.gal-img{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover; object-position:center center;
  /* swapImage() drives opacity for the decoded crossfade */
  transition:opacity .34s var(--ease);
  /* never a native draggable image — that hijacks the touch stream on iPad */
  -webkit-user-drag:none; user-select:none; -webkit-touch-callout:none;
  pointer-events:none;
}

/* Only legibility, never mood: two short gradients so the pills read on any
   render. Deliberately shallow — the photograph stays the subject. */
.gal-veil{
  position:absolute; inset:0;
  pointer-events:none;
  background:
    linear-gradient(0deg, rgba(255,242,235,.70) 0%, rgba(255,242,235,.28) 13%, rgba(255,242,235,0) 30%),
    linear-gradient(180deg, rgba(255,242,235,.52) 0%, rgba(255,242,235,.14) 12%, rgba(255,242,235,0) 26%);
}

/* ── Shared glass pill ─────────────────────────────────────────────────────── */
/* NOTE ON PLACEMENT — the app runs as a full-screen shell (styles.css forces
   .view-stage{inset:12px}), so three pieces of FLOATING chrome sit over every
   view and the gallery pills must never land under them:
     · .topbar .brand-home  fixed left:31 top:29  (h 42)
     · .top-actions Saved    fixed right:30 top:28 (h 43)
     · .efab-root presenter  fixed right:22 bottom:22 (58px)
   Hence: chips in the free top-CENTRE band, everything else in a bottom-left
   cluster, the counter bottom-centre, and nothing at all in either right-hand
   corner. verify.mjs asserts this stays true. */
.gal-pill{
  position:relative; z-index:3;
  background:var(--e-glass-strong);
  border:1px solid var(--e-glass-line);
  backdrop-filter:blur(var(--e-blur)) saturate(115%);
  -webkit-backdrop-filter:blur(var(--e-blur)) saturate(115%);
  /* two-part warm shadow: the ring keeps the pill from dissolving into a pale
     render, the soft cast keeps it floating over a dark one */
  box-shadow:0 0 0 1px rgba(63,89,58,.10),0 14px 38px rgba(63,89,58,.18);
  color:var(--e-ink);
  border-radius:2px;
}

/* ── Bottom-left cluster · Save row over the caption ──────────────────────── */
.gal-info{
  position:absolute; z-index:3;
  left:var(--gal-gutter);
  bottom:calc(var(--gal-gutter) + var(--gal-lift));
  max-width:min(46%,520px);
  display:flex; flex-direction:column; align-items:flex-start; gap:10px;
  transition:bottom .42s var(--ease);
}
.gal-caption{
  padding:14px 22px 16px;
}
.gal-caption .gal-meta{
  margin:0 0 6px;
  color:var(--e-ink);
  font-size:9px;
}
.gal-caption .gal-title{
  margin:0;
  font:400 clamp(26px,2.6vw,40px)/1.06 var(--serif);
  letter-spacing:.005em;
  color:var(--e-ink-strong);
}
/* the room note (Inside Eden) — one quiet line under the title */
.gal-caption .gal-note{
  margin:7px 0 0;
  font-size:12.5px; line-height:1.55;
  color:var(--e-ink);
  max-width:40ch;
}
.gal-caption .gal-note:empty{display:none}

/* ── Counter · bottom-centre · also the strip handle ──────────────────────── */
/* A direct child of .gal on purpose: nested inside .gal-info it would resolve
   its absolute box against that cluster and land on top of the caption. */
.gal-index{
  position:absolute;
  left:50%;
  bottom:calc(var(--gal-gutter) + var(--gal-lift));
  transform:translateX(-50%);
  min-width:104px; min-height:44px;
  padding:0 18px;
  display:flex; align-items:center; justify-content:center; gap:8px;
  font-family:var(--sans);
  transition:bottom .42s var(--ease),border-color .3s var(--ease);
}
.gal-index b{font:500 13px/1 var(--sans);letter-spacing:.16em;color:var(--e-ink-strong)}
.gal-index i{font-style:normal;color:var(--e-ink-soft);font-size:11px}
.gal-index small{font-size:11px;letter-spacing:.16em;color:var(--e-ink)}
.gal-index:hover{border-color:var(--e-line-strong)}
.gal.strip-open .gal-index{border-color:var(--e-ink)}

/* ── Save · in the bottom-left cluster, above the caption ─────────────────── */
.gal-save{
  min-height:44px; padding:0 20px;
  display:flex; align-items:center; gap:10px;
  font-size:9px; text-transform:uppercase; letter-spacing:.2em;
  color:var(--e-ink);
}
/* the mark itself is the shared .bookmark-icon span — one save glyph app-wide */
.gal-save:hover{border-color:var(--e-line-strong)}

/* ── Category chips · the free top-CENTRE band · LIFE only ────────────────── */
/* 210px insets clear the floating brand lockup (left) and Saved pill (right). */
.gal-cats{
  position:absolute; z-index:3;
  left:210px; right:210px;
  top:14px;
  display:flex; flex-wrap:wrap; justify-content:center; align-items:center;
  gap:7px;
}
.gal-cats button{
  min-height:40px; padding:0 19px;
  font-size:9.5px; text-transform:uppercase; letter-spacing:.22em;
  color:var(--e-ink);
  background:var(--e-glass-strong);
  border:1px solid var(--e-glass-line);
  backdrop-filter:blur(var(--e-blur)) saturate(118%);
  -webkit-backdrop-filter:blur(var(--e-blur)) saturate(118%);
  border-radius:999px;
  /* the chips ride the top band where the veil is weakest — a warm cast keeps
     them off a pale sky */
  box-shadow:0 0 0 1px rgba(63,89,58,.08),0 6px 18px rgba(63,89,58,.14);
  transition:background .28s var(--ease),color .28s var(--ease),border-color .28s var(--ease),transform .28s var(--ease),box-shadow .28s var(--ease);
}
.gal-cats button:hover{border-color:var(--e-line-strong);color:var(--e-ink-strong)}
.gal-cats button.is-active{
  background:linear-gradient(180deg,var(--eden-beige-2),var(--eden-beige-1)); color:var(--e-ink-strong);
  border-color:var(--e-line-strong);
  box-shadow:0 6px 18px rgba(109,96,61,.22),0 12px 28px rgba(63,89,58,.14);
  transform:translateY(-1px);
}
.gal-cats button:active{transform:translateY(0) scale(.97)}

/* ── Arrows · edge tap zones for non-swipe guests ─────────────────────────── */
.gal-arrow{
  position:absolute; z-index:4;
  top:50%; transform:translateY(-50%);
  width:52px; height:52px;
  display:grid; place-items:center;
  color:var(--e-ink);
  background:var(--e-glass-strong);
  border:1px solid var(--e-glass-line);
  backdrop-filter:blur(16px);
  -webkit-backdrop-filter:blur(16px);
  border-radius:50%;
  box-shadow:0 0 0 1px rgba(63,89,58,.09),0 8px 22px rgba(63,89,58,.16);
  opacity:.7;
  transition:opacity .3s var(--ease),border-color .3s var(--ease),transform .3s var(--ease);
}
.gal-arrow svg{width:20px;height:20px}
.gal-arrow:hover{opacity:1;border-color:var(--e-line-strong)}
.gal-prev{left:14px}
.gal-next{right:14px}
.gal-prev:hover{transform:translateY(-50%) translateX(-2px)}
.gal-next:hover{transform:translateY(-50%) translateX(2px)}

/* ── Thumbnail strip · collapsed by default, opened from the counter ───────── */
.gal-strip{
  position:absolute; z-index:2;
  left:0; right:0; bottom:0;
  height:96px;
  display:flex; gap:8px;
  padding:10px 108px 10px 12px;   /* right pad clears the presenter FAB */
  overflow-x:auto; overflow-y:hidden;
  scrollbar-width:none;
  background:linear-gradient(0deg, rgba(255,242,235,.90) 0%, rgba(255,242,235,.62) 62%, rgba(255,242,235,0) 100%);
  touch-action:pan-x;
  opacity:0; transform:translateY(102%);
  pointer-events:none;
  transition:opacity .38s var(--ease),transform .42s var(--ease);
  cursor:grab;
}
.gal-strip::-webkit-scrollbar{display:none}
.gal-strip:active{cursor:grabbing}
.gal.strip-open .gal-strip{opacity:1;transform:none;pointer-events:auto}
.gal.strip-open{--gal-lift:104px}

.gal-thumb{
  flex:0 0 112px; height:100%;
  position:relative; overflow:hidden;
  border:1px solid var(--e-line);
  border-radius:12px;
  opacity:.58;
  transition:opacity .28s var(--ease),border-color .28s var(--ease),transform .28s var(--ease),box-shadow .28s var(--ease);
}
.gal-thumb.is-active{
  opacity:1;
  border-color:var(--e-ink);
  box-shadow:0 0 0 1px rgba(63,89,58,.35),0 8px 20px rgba(63,89,58,.16);
  transform:translateY(-3px);
}
.gal-thumb img{
  width:100%; height:100%; object-fit:cover;
  -webkit-user-drag:none; user-select:none; -webkit-touch-callout:none;
}
.gal-thumb:hover{opacity:.9}
.gal-thumb.is-active{opacity:1;border-color:var(--e-ink)}

/* ── Entrance · a slow, drift-free fade for the render, pills rise in ─────── */
@keyframes galReveal{from{opacity:0}to{opacity:1}}
@keyframes galRise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes galRiseCentred{from{opacity:0;transform:translateX(-50%) translateY(14px)}to{opacity:1;transform:translateX(-50%)}}
@keyframes galArrowIn{from{opacity:0}to{opacity:.7}}

.gallery-view.is-active .gal-stage{animation:galReveal 1.05s var(--ease) both}
.gallery-view.is-active .gal-info{animation:galRise .7s .18s var(--ease) both}
.gallery-view.is-active .gal-cats{animation:galRise .7s .26s var(--ease) both}
.gallery-view.is-active .gal-index{animation:galRiseCentred .7s .26s var(--ease) both}
.gallery-view.is-active .gal-arrow{animation:galArrowIn .8s .42s var(--ease) backwards}

/* ── Portrait (iPad 834×1194) ─────────────────────────────────────────────── */
/* Narrow view: the bottom row cannot hold caption + centred counter without
   them touching, so the counter takes the bottom-right corner and the caption
   keeps the bottom-left. Save stays top-right, chips wrap under it. */
@media (orientation:portrait){
  .gal{--gal-gutter:16px}
  .gal-info{max-width:74%}
  .gal-caption{padding:13px 18px 15px}
  .gal-caption .gal-title{font-size:clamp(23px,4.4vw,32px)}
  /* the brand + Saved pills own the top corners on a narrow screen, so the chip
     rows sit under them, full width */
  .gal-cats{left:var(--gal-gutter);right:var(--gal-gutter);top:86px;justify-content:flex-start;gap:6px}
  .gal-cats button{min-height:36px;padding:0 12px;letter-spacing:.16em}
  /* 810px cannot hold a caption on the left AND a centred counter at the bottom
     without them touching, so portrait parks the counter in the free top-centre
     band between the floating brand lockup and the Saved pill. */
  .gal-index{top:29px;bottom:auto}
  .gal-arrow{width:48px;height:48px}
  .gal-strip{height:84px;padding-right:20px}
  .gal.strip-open{--gal-lift:92px}
  .gal-thumb{flex:0 0 92px}
}

/* ── Short landscape (Tab S7 1280×800) ───────────────────────────────────── */
@media (max-height:840px) and (orientation:landscape){
  .gal{--gal-gutter:16px}
  .gal-caption .gal-title{font-size:clamp(24px,2.4vw,32px)}
  .gal-cats button{min-height:36px;padding:0 13px}
  .gal-strip{height:86px}
  .gal.strip-open{--gal-lift:94px}
  .gal-thumb{flex:0 0 96px}
}

/* ── Reduced motion ──────────────────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  .gal-img{transition:none}
  .gal-strip{transition:none}
  .gal-info,.gal-index{transition:none}
  .gallery-view.is-active .gal-stage,
  .gallery-view.is-active .gal-info,
  .gallery-view.is-active .gal-cats,
  .gallery-view.is-active .gal-index,
  .gallery-view.is-active .gal-arrow{animation-duration:.01ms!important;animation-delay:0s!important}
}

/* ── Inactive views must never trap taps. Views hide by opacity, not display,
      and the strip is now OPEN by default — without this, its invisible
      thumbnails sat over the estate and ate the plot-label taps. ── */
.view:not(.is-active) .gal-stage,
.view:not(.is-active) .gal-strip,
.view:not(.is-active) .gal-cats,
.view:not(.is-active) .gal-arrow,
.view:not(.is-active) .gal-info,
.view:not(.is-active) .gal-index,
.view:not(.is-active) .gal-save{pointer-events:none!important}

/* the render is tappable into the zoomable full-screen view — same cue the
   villa drawing surface uses, so the affordance reads the same app-wide */
.gal-stage{cursor:zoom-in}

/* ── zoom, on the render itself ─────────────────────────────────────────
   Client 2026-09-04: zoom belongs to the full-screen render, not to a panel
   opened on top of it. The chips take the bottom-left corner the caption
   plate used to occupy, clear of the arrows at mid-height and of the
   Annotate pebble on the right.

   Minus never shrinks past the fitted frame — the controller's floor is the
   full-screen fit, so the picture only ever gets bigger from here. */
.gal-zoom{
  position:absolute; z-index:28;
  left:clamp(18px,2.2vw,34px);
  bottom:calc(96px + 22px);
  display:flex; gap:6px;
  padding:6px;
  border-radius:18px;
  border:1px solid var(--eg-hair,rgba(255,255,255,.58));
  background:linear-gradient(155deg,rgba(255,250,246,.32),rgba(254,236,222,.18));
  -webkit-backdrop-filter:blur(24px) saturate(160%);
  backdrop-filter:blur(24px) saturate(160%);
  box-shadow:0 10px 30px -12px rgba(63,89,58,.34),inset 0 1px 0 rgba(255,255,255,.62);
}
.gal-zoom button{
  width:40px; height:40px;
  display:grid; place-items:center;
  border:1px solid transparent; border-radius:13px;
  background:transparent; color:var(--e-ink-strong);
  font:500 17px/1 var(--sans);
  cursor:pointer;
  text-shadow:0 1px 2px rgba(255,248,243,.92),0 0 9px rgba(255,248,243,.75);
  transition:background .26s ease,border-color .26s ease,transform .26s cubic-bezier(.22,1,.36,1);
}
.gal-zoom button:hover{background:rgba(255,250,246,.30);border-color:rgba(63,89,58,.14)}
.gal-zoom button:active{transform:scale(.94)}
/* while zoomed the render is being inspected — the cursor says so, and the
   paging arrows step back so a pan is never mistaken for a page turn */
.gal.is-zoomed .gal-stage{cursor:grab}
.gal.is-zoomed .gal-arrow{opacity:.25;pointer-events:none}

/* ── Walkthrough pane ───────────────────────────────────────────────────
   The film gets the same full-bleed stage the renders get. It is letterboxed
   rather than cropped — a walkthrough is a composed shot and cropping it
   would cut the frame the film-maker chose. */
.gal-pane.gal-film{background:var(--e-ground)}
.film-stage{
  position:absolute; inset:0;
  display:grid; place-items:center;
  background:#efe6de;
  overflow:hidden;
}
.film-video{
  width:100%; height:100%;
  object-fit:contain;
  background:#efe6de;
  display:block;
}
.film-picker{
  position:absolute; z-index:28;
  left:50%; transform:translateX(-50%);
  bottom:clamp(20px,3vh,34px);
  display:flex; gap:6px;
  padding:7px;
  border-radius:22px;
  border:1px solid var(--eg-hair,rgba(255,255,255,.58));
  background:linear-gradient(155deg,rgba(255,250,246,.32),rgba(254,236,222,.18));
  -webkit-backdrop-filter:blur(24px) saturate(160%);
  backdrop-filter:blur(24px) saturate(160%);
  box-shadow:0 10px 30px -12px rgba(63,89,58,.34),inset 0 1px 0 rgba(255,255,255,.62);
}
.film-picker button{
  display:flex; flex-direction:column; align-items:center; gap:4px;
  min-width:132px; padding:10px 16px 9px;
  border:1px solid transparent; border-radius:16px;
  background:transparent; cursor:pointer;
  color:var(--e-ink-strong); font-family:var(--sans);
  text-shadow:0 1px 2px rgba(255,248,243,.92),0 0 9px rgba(255,248,243,.75);
  transition:background .26s ease,border-color .26s ease,transform .26s cubic-bezier(.22,1,.36,1);
}
.film-picker button b{font-size:11px;font-weight:500;letter-spacing:.16em;text-transform:uppercase}
.film-picker button small{font-size:9px;letter-spacing:.18em;text-transform:uppercase;opacity:.72}
.film-picker button:hover{background:rgba(255,250,246,.30);border-color:rgba(63,89,58,.14)}
.film-picker button:active{transform:scale(.96)}
.film-picker button.is-active{
  background:rgba(255,250,246,.56);
  border-color:rgba(63,89,58,.20);
  font-weight:600;
}
/* the film pane owns the bottom of the screen — the render chrome steps off */
.gal-pane.gal-film .gal-zoom{display:none}
