/* =========================================================================
   HVN Gallery - an interactive image-presentation framework.
   One config-driven, keyboard-first, accessible gallery with switchable view
   modes (Cinema / Grid / Interactive Timeline) + a lightbox. Theme-aware via
   the same data-theme mechanism the rest of the suite uses (day + night).
   First use case: Chloe's "A Year of Sweet Moments". Built to generalise to
   family/company stories, history timelines, websites, and about-us pages.
   Structural CSS only references CSS variables; colours live in the :root maps.
   ========================================================================= */

.hvn-gallery {
  /* --- day theme (default) --- */
  --g-page:      #FFFCF7;   /* page background for grid + timeline */
  --g-stage:     #211a14;   /* immersive cinema stage (photos pop on warm dark) */
  --g-ink:       #574A3B;
  --g-ink-soft:  #6E6052;
  --g-accent:    #BC8228;   /* honey */
  --g-accent-2:  #D67E74;   /* coral */
  --g-panel:     #ffffff;   /* cards */
  --g-panel-2:   #FBF3E7;
  --g-line:      #EADFCB;
  --g-chrome:    rgba(255,255,255,.72);   /* control bar / buttons */
  --g-chrome-ink:#6E6052;
  --g-on-dark:   rgba(255,255,255,.92);   /* text drawn over the cinema stage */
  --g-on-dark-soft: rgba(255,255,255,.62);
  --g-spine:     linear-gradient(to bottom, #E59B94, #D49A41, #A7BD96);
  --g-dur:       .55s;      /* base transition; reduced-motion drops to .01ms */

  position: fixed; inset: 0;
  background: var(--g-page);
  color: var(--g-ink);
  font-family: 'Mulish', system-ui, sans-serif;
  overflow: hidden;          /* mode roots own their own scroll */
}

html[data-theme="night"] .hvn-gallery {
  --g-page:      #1b1d34;
  --g-stage:     #111223;
  --g-ink:       #DAD4E8;
  --g-ink-soft:  #B9B2CC;
  --g-accent:    #F4D27A;
  --g-accent-2:  #F0ABA4;
  --g-panel:     #232653;
  --g-panel-2:   #272a4e;
  --g-line:      #3b3e66;
  --g-chrome:    rgba(38,42,77,.62);
  --g-chrome-ink:#F4D27A;
  --g-on-dark:   rgba(255,255,255,.94);
  --g-on-dark-soft: rgba(255,250,232,.66);
  --g-spine:     linear-gradient(to bottom, #F0ABA4, #F4D27A, #AFC59E);
}

.hvn-gallery * { box-sizing: border-box; }
.hvn-gallery button { font-family: inherit; }

/* ---- chrome: top bar -------------------------------------------------- */
.g-bar {
  position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  display: flex; align-items: center; gap: 12px;
  padding: calc(14px + env(safe-area-inset-top)) 16px 14px;
  pointer-events: none;   /* only the controls inside are clickable */
}
.g-bar > * { pointer-events: auto; }
.g-bar.is-cinema { background: linear-gradient(to bottom, rgba(0,0,0,.34), transparent); }
.g-spacer { flex: 1 1 auto; }

.g-home {
  font-family: 'Jost', sans-serif; font-size: .72rem; letter-spacing: .12em; text-transform: uppercase;
  text-decoration: none; color: var(--g-chrome-ink);
  background: var(--g-chrome); border: 1px solid var(--g-line);
  padding: 8px 15px; border-radius: 22px; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  white-space: nowrap;
}
.g-bar.is-cinema .g-home { color: var(--g-on-dark); background: rgba(0,0,0,.26); border-color: rgba(255,255,255,.16); }

.g-title {
  font-family: 'Cormorant Garamond', serif; font-weight: 600; font-size: 1.05rem;
  color: var(--g-chrome-ink); letter-spacing: .01em; white-space: nowrap;
  opacity: .9;
}
.g-bar.is-cinema .g-title { color: var(--g-on-dark); }
@media (max-width: 720px){ .g-title { display: none; } }

/* round icon buttons (fullscreen, help, theme sits here too via theme.js) */
.g-iconbtn {
  width: 44px; height: 44px; border-radius: 50%; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--g-chrome); border: 1px solid var(--g-line); color: var(--g-chrome-ink);
  cursor: pointer; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: transform .18s ease, background .25s ease;
}
.g-iconbtn:hover { transform: translateY(-2px); }
.g-iconbtn:active { transform: scale(.94); }
.g-iconbtn svg { width: 19px; height: 19px; display: block; }
.g-bar.is-cinema .g-iconbtn { color: var(--g-on-dark); background: rgba(0,0,0,.26); border-color: rgba(255,255,255,.16); }

/* ---- mode switcher (segmented) --------------------------------------- */
.g-modes {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 22px; z-index: 41;
  display: inline-flex; gap: 2px; padding: 4px;
  background: var(--g-chrome); border: 1px solid var(--g-line); border-radius: 30px;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  box-shadow: 0 6px 22px rgba(0,0,0,.14);
}
.g-mode {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: 'Jost', sans-serif; font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--g-chrome-ink); background: transparent; border: 0; cursor: pointer;
  padding: 9px 16px; border-radius: 24px; transition: background .2s ease, color .2s ease;
  white-space: nowrap;
}
.g-mode svg { width: 16px; height: 16px; }
.g-mode[aria-pressed="true"] { background: var(--g-accent); color: #fff; }
html[data-theme="night"] .g-mode[aria-pressed="true"] { color: #1b1d34; }
.g-mode:not([aria-pressed="true"]):hover { background: rgba(0,0,0,.05); }
@media (max-width: 560px){ .g-mode { padding: 9px 13px; } .g-mode .g-mode-lab { display: none; } }

/* ---- mode root + generic scroll area ---------------------------------- */
.g-mode-root { position: fixed; inset: 0; }
.g-scroll { position: fixed; inset: 0; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; }

/* ===== CINEMA mode ===================================================== */
.g-cinema { background: var(--g-stage); }
.g-slide { position: fixed; inset: 0; opacity: 0; transition: opacity 1.2s ease; }
.g-slide.is-on { opacity: 1; }
.g-slide .g-bg {
  position: absolute; inset: 0; background-size: cover; background-position: center;
  filter: blur(46px) brightness(.5) saturate(1.15); transform: scale(1.14);
}
.g-slide .g-fg {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; padding: 4vh 4vw 11vh;
}
.g-slide.is-on .g-fg { animation: g-ken var(--g-ken,18s) ease-out forwards; }
@keyframes g-ken {
  from { transform: scale(1) translate(0,0); }
  to   { transform: scale(var(--g-ks,1.12)) translate(var(--g-kx,0), var(--g-ky,0)); }
}

.g-caption {
  position: fixed; left: 0; right: 0; bottom: 150px; z-index: 22; text-align: center;
  padding: 0 8vw; pointer-events: none;
}
.g-caption .c-t { font-family: 'Cormorant Garamond', serif; font-weight: 600; color: var(--g-on-dark);
  font-size: clamp(1.3rem, 3.4vw, 2.4rem); line-height: 1.15; text-shadow: 0 2px 18px rgba(0,0,0,.5); }
.g-caption .c-s { font-family: 'Jost', sans-serif; letter-spacing: .14em; text-transform: uppercase;
  color: var(--g-on-dark-soft); font-size: .72rem; margin-top: 8px; }

/* segmented progress (story-mode style) */
.g-segs { position: fixed; top: 0; left: 0; right: 0; z-index: 30; display: flex; gap: 4px; padding: calc(9px + env(safe-area-inset-top)) 12px 9px; }
.g-seg { flex: 1 1 0; height: 3px; border-radius: 3px; background: rgba(255,255,255,.26); overflow: hidden; }
.g-seg > i { display: block; height: 100%; width: 0; background: var(--g-on-dark); }
.g-seg.is-done > i { width: 100%; }
.g-seg.is-live > i { animation: g-fill var(--g-dwell,6000ms) linear forwards; }
.g-cinema.is-paused .g-seg.is-live > i { animation-play-state: paused; }
@keyframes g-fill { from { width: 0; } to { width: 100%; } }

/* cinema controls (prev / play-pause / next) */
.g-cine-ctrls { position: fixed; left: 50%; transform: translateX(-50%); bottom: 84px; z-index: 23;
  display: flex; align-items: center; gap: 18px; }
.g-cine-ctrls.hide-on-mobile { }
.g-cbtn { width: 46px; height: 46px; border-radius: 50%; padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.30); border: 1px solid rgba(255,255,255,.2); color: var(--g-on-dark);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); transition: transform .15s ease, background .2s ease; }
.g-cbtn:hover { transform: scale(1.06); background: rgba(0,0,0,.44); }
.g-cbtn svg { width: 20px; height: 20px; }
.g-cbtn.g-play { width: 56px; height: 56px; }
.g-cbtn.g-play svg { width: 24px; height: 24px; }
@media (max-width: 560px){ .g-caption { bottom: 158px; } .g-cine-ctrls { bottom: 90px; gap: 14px; } }

/* ===== GRID mode ======================================================= */
.g-grid-wrap { padding: 78px 16px 96px; max-width: 1180px; margin: 0 auto; }
.g-grid-head { text-align: center; margin-bottom: 22px; }
.g-grid-head h2 { font-family: 'Cormorant Garamond', serif; font-weight: 600; color: var(--g-accent);
  font-size: clamp(1.7rem, 5vw, 2.6rem); margin: 0 0 4px; }
.g-grid-head p { font-family: 'Jost', sans-serif; letter-spacing: .14em; text-transform: uppercase;
  font-size: .64rem; color: var(--g-ink-soft); margin: 0; }
.g-grid { columns: 4 220px; column-gap: 14px; }
@media (max-width: 900px){ .g-grid { columns: 3 180px; } }
@media (max-width: 560px){ .g-grid { columns: 2 140px; column-gap: 10px; } }
.g-cell {
  display: block; width: 100%; margin: 0 0 14px; padding: 0; border: 0; cursor: pointer;
  break-inside: avoid; border-radius: 14px; overflow: hidden; background: var(--g-panel-2);
  box-shadow: 0 3px 10px rgba(0,0,0,.10); transition: transform .2s ease, box-shadow .2s ease;
  position: relative;
}
.g-cell:hover, .g-cell:focus-visible { transform: translateY(-3px); box-shadow: 0 10px 22px rgba(0,0,0,.16); outline: none; }
.g-cell:focus-visible { box-shadow: 0 0 0 3px var(--g-accent); }
.g-cell img { display: block; width: 100%; height: auto; }
.g-cell .g-cap {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 18px 12px 9px;
  font-family: 'Mulish', sans-serif; font-size: .8rem; color: #fff; text-align: left;
  background: linear-gradient(to top, rgba(0,0,0,.6), transparent); opacity: 0; transition: opacity .2s ease;
}
.g-cell:hover .g-cap, .g-cell:focus-visible .g-cap { opacity: 1; }

/* ===== TIMELINE mode =================================================== */
.g-tl-wrap { padding: 84px 18px 110px; max-width: 920px; margin: 0 auto; position: relative; }
.g-tl-head { text-align: center; margin-bottom: 34px; }
.g-tl-head h2 { font-family: 'Cormorant Garamond', serif; font-weight: 600; color: var(--g-accent);
  font-size: clamp(1.8rem, 5vw, 2.7rem); margin: 0 0 4px; }
.g-tl-head p { font-family: 'Jost', sans-serif; letter-spacing: .14em; text-transform: uppercase;
  font-size: .64rem; color: var(--g-ink-soft); margin: 0; }
.g-tl { position: relative; padding: 8px 0; }
/* the spine + the growing progress fill */
.g-tl::before { content: ''; position: absolute; top: 0; bottom: 0; left: 50%; width: 2px;
  transform: translateX(-50%); background: var(--g-line); }
.g-tl-fill { position: absolute; top: 0; left: 50%; width: 3px; transform: translateX(-50%);
  background: var(--g-spine); border-radius: 3px; height: 0; }
@media (max-width: 680px){
  .g-tl::before, .g-tl-fill { left: 18px; }
}
.g-ms { position: relative; width: 50%; padding: 0 40px 36px 0; }
.g-ms:nth-child(even) { margin-left: 50%; padding: 0 0 36px 40px; }
.g-ms .g-dot { position: absolute; top: 6px; right: -7px; width: 14px; height: 14px; border-radius: 50%;
  background: var(--g-accent); border: 3px solid var(--g-page); z-index: 2; }
.g-ms:nth-child(even) .g-dot { left: -7px; right: auto; }
.g-card { background: var(--g-panel); border: 1px solid var(--g-line); border-radius: 16px; overflow: hidden;
  box-shadow: 0 4px 14px rgba(0,0,0,.10); cursor: pointer;
  transition: opacity .6s ease, transform .6s ease; }
/* cards are visible by default; the entrance animation only applies once JS has
   added .anim (so a failed reveal never leaves content invisible) */
.g-tl.anim .g-card { opacity: 0; transform: translateY(22px); }
.g-tl.anim .g-ms.in .g-card { opacity: 1; transform: none; }
.g-card img { display: block; width: 100%; height: 190px; object-fit: cover; }
.g-card .g-body { padding: 12px 15px 15px; }
.g-card .g-when { font-family: 'Jost', sans-serif; letter-spacing: .12em; text-transform: uppercase;
  font-size: .6rem; color: var(--g-accent); }
.g-card .g-ttl { font-family: 'Cormorant Garamond', serif; font-weight: 600; font-size: 1.2rem;
  color: var(--g-ink); margin: 2px 0 0; }
@media (max-width: 680px){
  .g-ms, .g-ms:nth-child(even) { width: 100%; margin-left: 0; padding: 0 0 30px 46px; }
  .g-ms .g-dot, .g-ms:nth-child(even) .g-dot { left: 11px; right: auto; }
}

/* ===== LIGHTBOX ======================================================== */
.g-lb { position: fixed; inset: 0; z-index: 60; display: none; align-items: center; justify-content: center;
  background: rgba(8,7,12,.93); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.g-lb.is-open { display: flex; }
.g-lb img { max-width: 92vw; max-height: 84vh; object-fit: contain; border-radius: 6px;
  box-shadow: 0 20px 60px rgba(0,0,0,.6); }
.g-lb-cap { position: fixed; left: 0; right: 0; bottom: 26px; text-align: center; padding: 0 8vw;
  font-family: 'Cormorant Garamond', serif; color: rgba(255,255,255,.92); font-size: 1.15rem; }
.g-lb-nav { position: fixed; top: 50%; transform: translateY(-50%); width: 52px; height: 52px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.22); background: rgba(255,255,255,.08); color: #fff; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; transition: background .2s ease; }
.g-lb-nav:hover { background: rgba(255,255,255,.18); }
.g-lb-nav svg { width: 22px; height: 22px; }
.g-lb-prev { left: 18px; } .g-lb-next { right: 18px; }
.g-lb-close { position: fixed; top: calc(18px + env(safe-area-inset-top)); right: calc(18px + env(safe-area-inset-right)); width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.22); background: rgba(255,255,255,.08); color: #fff; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; }
.g-lb-close svg { width: 20px; height: 20px; }

/* ===== HELP overlay ==================================================== */
.g-help { position: fixed; inset: 0; z-index: 70; display: none; align-items: center; justify-content: center;
  background: rgba(8,7,12,.72); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); padding: 20px; }
.g-help.is-open { display: flex; }
.g-help-card { background: var(--g-panel); color: var(--g-ink); border: 1px solid var(--g-line);
  border-radius: 18px; padding: 26px 28px; max-width: 460px; width: 100%; box-shadow: 0 24px 70px rgba(0,0,0,.4); }
.g-help-card h3 { font-family: 'Cormorant Garamond', serif; font-weight: 600; color: var(--g-accent);
  font-size: 1.5rem; margin: 0 0 14px; }
.g-help-row { display: flex; align-items: baseline; gap: 12px; padding: 5px 0; font-size: .92rem; }
.g-help-row kbd { font-family: 'Jost', sans-serif; font-size: .7rem; letter-spacing: .04em;
  background: var(--g-panel-2); border: 1px solid var(--g-line); border-radius: 6px; padding: 3px 8px;
  min-width: 58px; text-align: center; color: var(--g-ink); }
.g-help-row span { color: var(--g-ink-soft); }
.g-help-close { margin-top: 16px; width: 100%; font-family: 'Jost', sans-serif; letter-spacing: .14em;
  text-transform: uppercase; font-size: .7rem; padding: 11px; border-radius: 12px; cursor: pointer;
  background: var(--g-accent); color: #fff; border: 0; }
html[data-theme="night"] .g-help-close { color: #1b1d34; }

/* ===== empty / loading ================================================= */
.g-empty { position: fixed; inset: 0; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 12px; text-align: center; background: var(--g-page); }
.g-empty .e-b { font-size: 64px; }
.g-empty .e-t { font-family: 'Cormorant Garamond', serif; font-weight: 600; font-size: 1.9rem; color: var(--g-accent); }
.g-empty .e-s { font-family: 'Mulish', sans-serif; color: var(--g-ink-soft); }

/* ===== reduced motion ================================================== */
@media (prefers-reduced-motion: reduce) {
  .hvn-gallery { --g-dur: .01ms; }
  .g-slide { transition: opacity .3s ease; }
  .g-slide.is-on .g-fg { animation: none; }
  .g-seg.is-live > i { animation: none; width: 100%; }
  .g-card { transition: opacity .3s ease; transform: none; }
  .g-cell { transition: none; }
  .g-cine-ctrls { transition: none; }
}

/* ===== review pass: focus-visible, contrast, auto-hide, safe-area ====== */
.hvn-gallery :focus-visible { outline: 3px solid var(--g-accent); outline-offset: 2px; }
.g-lb :focus-visible, .g-cbtn:focus-visible, .g-lb-nav:focus-visible,
.g-lb-close:focus-visible, .g-bar.is-cinema :focus-visible { outline-color: #fff; }

/* play/pause is first in the DOM (tab order) but stays centered visually */
.g-cine-ctrls .g-prev { order: 1; }
.g-cine-ctrls .g-play { order: 2; }
.g-cine-ctrls .g-next { order: 3; }

/* auto-hide cinema controls during playback (revealed on any interaction) */
.g-cine-ctrls { transition: opacity .4s ease; }
.g-cinema.controls-off .g-cine-ctrls { opacity: 0; pointer-events: none; }

/* timeline date label: WCAG-AA contrast on the day card, gold at night */
.g-card .g-when { color: #8a5e17; }
html[data-theme="night"] .g-card .g-when { color: var(--g-accent); }

/* lightbox photo counter */
.g-lb-counter { position: fixed; top: calc(20px + env(safe-area-inset-top)); left: calc(22px + env(safe-area-inset-left)); z-index: 61;
  font-family: 'Jost', sans-serif; letter-spacing: .12em; font-size: .72rem; color: rgba(255,255,255,.8); }
.g-lb img { max-height: 84dvh; }   /* dynamic viewport height; falls back to 84vh above */

/* visually-hidden screen-reader live region */
.g-sr { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* iOS safe-area for bottom-fixed chrome (home indicator) */
@supports (padding: env(safe-area-inset-bottom)) {
  .g-modes { bottom: calc(22px + env(safe-area-inset-bottom)); }
  .g-grid-wrap { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
  .g-tl-wrap { padding-bottom: calc(110px + env(safe-area-inset-bottom)); }
}

/* ===== VIDEO (a third of Meg's album) ================================= */
/* cinema video layer: shown only when the slide carries a video */
.g-slide .g-fg-vid {
  display: none; position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; padding: 4vh 4vw 11vh; background: transparent;
}
.g-slide.is-video .g-fg-vid { display: block; }
.g-slide.is-video .g-fg { display: none; }
/* lightbox video */
.g-lb-vid { max-width: 92vw; max-height: 84vh; max-height: 84dvh; border-radius: 6px;
  box-shadow: 0 20px 60px rgba(0,0,0,.6); background: #000; }
/* play badge on grid cells + timeline cards that are videos */
.g-card { position: relative; }
.g-vid-badge { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 46px; height: 46px; border-radius: 50%; background: rgba(0,0,0,.45); color: #fff;
  display: inline-flex; align-items: center; justify-content: center; pointer-events: none;
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); box-shadow: 0 2px 10px rgba(0,0,0,.3); }
.g-vid-badge svg { width: 22px; height: 22px; margin-left: 2px; }
.g-card .g-vid-badge { top: 95px; }   /* center over the 190px card image, not the body */

/* ===== KIOSK / TV mode: zero-chrome, auto-looping display ============== */
.g-kiosk .g-cine-ctrls { display: none; }
.g-kiosk .g-caption { bottom: 48px; }
.g-kiosk .g-bar { opacity: 0; pointer-events: none; transition: opacity .5s ease; }
.g-kiosk.chrome-on .g-bar { opacity: 1; pointer-events: auto; }
