/* ============================================================
   MODULE — media_gallery (.zd-spot)
   Zdorovo Dental — media_gallery module (spotlight variant).
   Loads AFTER zd-blocks.css. No new design tokens.
   · One large focal frame + a scrollable thumbnail filmstrip.
   · Fullscreen via the real Fullscreen API, with a fixed-overlay fallback
   · when the API is blocked (e.g. an iframe with no allow="fullscreen").
   · Progress bar reflects position — this is equipment, not a slideshow;
   · no autoplay, no timer.
   ============================================================ */

/* ============================================================
   MODULE — media_gallery, SPOTLIGHT variant (.zd-spot)
   One large focal frame + a scrollable filmstrip of thumbnails.
   Loads AFTER zd-blocks.css. No new tokens beyond what's below.
   ============================================================ */

.zd-spot { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; }

/* ---------- focal frame ---------- */
.zd-spot__stage {
  position: relative; aspect-ratio: 16/9; border-radius: var(--radius-lg);
  overflow: hidden; background: var(--surface); border: 1px solid var(--zd-line);
  box-shadow: var(--shadow-md);
}
.zd-spot__frame {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  opacity: 0; pointer-events: none;
  transition: opacity .38s var(--ease-out);
}
.zd-spot__frame.is-active { opacity: 1; pointer-events: auto; }
/* .zd-ba__ph is bare with no background outside the --before/--after
   modifiers it ships with, so give it a surface here or it renders
   transparent — leaving the caption's dark gradient with nothing behind it. */
.zd-spot__frame .zd-ba__ph { position: absolute; inset: 0; background: linear-gradient(150deg, var(--ink-100), #dfe6e2); color: var(--ink-500); }

.zd-spot__caption {
  position: relative; z-index: 2; margin-top: auto; padding: 46px 26px 20px;
  /* a solid dark base at the bottom, not just a fade to transparent — so
     text stays legible over a light photo, not only a dark one */
  background: linear-gradient(to top, rgba(8,14,11,.92) 40%, rgba(8,14,11,.0) 100%);
  color: #fff;
}
.zd-spot__scope { display: inline-block; font: 700 11px/1.3 var(--font-sans); text-transform: uppercase; letter-spacing: .06em; color: var(--green-300); margin: 0 0 6px; }
.zd-spot__title { margin: 0 0 6px; font-family: var(--font-heading); font-weight: 700; font-size: clamp(18px,2.4vw,23px); line-height: 1.28; text-wrap: pretty; color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,.4); }
.zd-spot__text { margin: 0; max-width: 62ch; font-size: 14.5px; line-height: 1.6; color: rgba(255,255,255,.86); text-wrap: pretty; text-shadow: 0 1px 3px rgba(0,0,0,.35); }
.zd-spot__title { text-shadow: 0 1px 4px rgba(0,0,0,.4); }
.zd-spot__scope { text-shadow: 0 1px 3px rgba(0,0,0,.4); }

/* counter, top-right of the stage */
.zd-spot__count { position: absolute; z-index: 2; top: 16px; right: 16px; padding: 5px 11px; border-radius: var(--radius-pill); background: rgba(11,20,16,.55); color: #fff; font: 700 12px/1 "Roboto Mono", monospace; letter-spacing: .02em; }

/* fullscreen toggle — top-left, mirrors the counter's chip treatment */
.zd-spot__fs { position: absolute; z-index: 3; top: 16px; left: 16px; width: 34px; height: 34px; border-radius: 50%; border: 0; background: rgba(11,20,16,.55); color: #fff; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: background .18s; }
.zd-spot__fs:hover { background: rgba(11,20,16,.75); }
.zd-spot__fs svg.is-exit { display: none; }
.zd-spot[data-fullscreen="on"] .zd-spot__fs svg.is-enter { display: none; }
.zd-spot[data-fullscreen="on"] .zd-spot__fs svg.is-exit { display: block; }

/* in fullscreen the stage should fill the screen and the strip sit under it */
/* LOCAL CHANGE — the drop's surround was near-black (#0b1410). Grey instead, to
   match the before/after placeholders and the rest of this light design. Kept as
   two separate rules, not a comma list, because one invalid selector would
   invalidate the whole list and :fullscreen support is not universal. */
.zd-spot:fullscreen { display: flex; flex-direction: column; justify-content: center; background: var(--surface-page); padding: 24px; gap: 16px; }
.zd-spot:fullscreen .zd-spot__stage { flex: 1; max-height: calc(100vh - 160px); aspect-ratio: auto; }
.zd-spot:fullscreen .zd-spot__bar { max-width: 900px; margin: 0 auto; width: 100%; }
.zd-spot:fullscreen .zd-spot__strip { max-width: 900px; margin: 0 auto; width: 100%; }

/* Fallback for when the real Fullscreen API is unavailable/blocked (e.g. an
   iframe preview without allow="fullscreen") — a fixed-position overlay that
   covers the viewport. Same visual result, no browser permission needed. */
.zd-spot.is-pseudo-fullscreen {
  position: fixed; inset: 0; z-index: 999; display: flex; flex-direction: column;
  justify-content: center; background: var(--surface-page); padding: 24px; gap: 16px; margin: 0;
}
.zd-spot.is-pseudo-fullscreen .zd-spot__stage { flex: 1; max-height: calc(100vh - 160px); aspect-ratio: auto; }
.zd-spot.is-pseudo-fullscreen .zd-spot__bar { max-width: 900px; margin: 0 auto; width: 100%; }
.zd-spot.is-pseudo-fullscreen .zd-spot__strip { max-width: 900px; margin: 0 auto; width: 100%; }
body:has(.zd-spot.is-pseudo-fullscreen) { overflow: hidden; }

/* prev/next arrows sit on the stage itself */
.zd-spot__arrow { position: absolute; z-index: 3; top: 50%; transform: translateY(-50%); width: 44px; height: 44px; border-radius: 50%; border: 0; background: rgba(255,255,255,.92); color: var(--zd-accent-strong); display: inline-flex; align-items: center; justify-content: center; box-shadow: var(--shadow-md); cursor: pointer; transition: background .18s, transform .18s; }
.zd-spot__arrow:hover { background: #fff; transform: translateY(-50%) scale(1.06); }
.zd-spot__arrow--prev { left: 14px; }
.zd-spot__arrow--next { right: 14px; }

/* progress bar under the stage — replaces dots at this scale */
.zd-spot__bar { position: relative; height: 3px; border-radius: 999px; background: var(--zd-line); overflow: hidden; }
.zd-spot__bar-fill { position: absolute; inset: 0 auto 0 0; width: 0%; background: var(--zd-accent); border-radius: 999px; transition: width .38s var(--ease-out); }

/* ---------- filmstrip ---------- */
.zd-spot__stripwrap { position: relative; display: flex; align-items: center; gap: 8px; min-width: 0; }
.zd-spot__strip { display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x proximity; scrollbar-width: none; padding: 2px; flex: 1; min-width: 0; }
.zd-spot__strip::-webkit-scrollbar { display: none; }
.zd-spot__striparrow { flex: none; width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--zd-line); background: var(--surface); color: var(--zd-accent-strong); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: background .18s, border-color .18s, opacity .18s; }
.zd-spot__striparrow:hover { background: var(--zd-tint); border-color: var(--border-tint); }
.zd-spot__striparrow[disabled] { opacity: .32; cursor: default; pointer-events: none; }
/* LOCAL CHANGE — the drop gave these a white fill and no border so they would
   stand out against its near-black fullscreen surround. On the grey surround
   above that reads as a pale blob with no edge, so they keep their normal
   treatment instead: surface fill with the standard hairline border. */
.zd-spot.is-pseudo-fullscreen .zd-spot__striparrow, .zd-spot:fullscreen .zd-spot__striparrow { background: var(--surface); border-color: var(--zd-line); }
.zd-spot__thumb {
  flex: 0 0 108px; scroll-snap-align: start; aspect-ratio: 4/3; position: relative;
  border-radius: var(--radius-sm); overflow: hidden; border: 2px solid transparent;
  background: var(--surface); cursor: pointer; padding: 0;
  transition: border-color .18s, transform .18s, opacity .18s;
  opacity: .62;
}
.zd-spot__thumb .zd-ba__ph { position: absolute; inset: 0; background: linear-gradient(150deg, var(--ink-100), #dfe6e2); color: var(--ink-500); }
.zd-spot__thumb .zd-ba__ph-note { display: none; }
.zd-spot__thumb:hover { opacity: .85; transform: translateY(-2px); }
.zd-spot__thumb.is-active { opacity: 1; border-color: var(--zd-accent); box-shadow: 0 0 0 1px var(--zd-accent); }
.zd-spot__thumb-label { position: absolute; left: 0; right: 0; bottom: 0; padding: 4px 6px 4px; font: 600 10px/1.3 var(--font-sans); color: #fff; background: linear-gradient(to top, rgba(11,20,16,.82), transparent); text-align: left; min-height: 34px; box-sizing: border-box; display: flex; align-items: flex-end; }

.zd-spot__note { margin: 4px 2px 0; font-size: 13.5px; line-height: 1.55; color: var(--zd-muted); font-style: italic; }

@media (prefers-reduced-motion: reduce) {
  .zd-spot__frame, .zd-spot__bar-fill, .zd-spot__thumb, .zd-spot__caption { transition: none; }
}

/* mobile: shorter stage, arrows drop to sit on top of thumbnails' row instead of crowding the small frame */
@media (max-width: 599px) {
  .zd-spot__stage { aspect-ratio: 4/3; }

  .zd-spot__caption { padding: 16px 16px 14px; }
  .zd-spot__title { font-size: 16.5px; }
  .zd-spot__thumb { flex: 0 0 84px; }
}

/* ============================================================
   LOCAL ADDITIONS — not part of the design drop.
   Three clauses, because no single one covers every case:
     (max-width: 599px)                          narrow portrait — phone, or a
                                                 narrow desktop window
     (orientation: landscape) and (max-height: 600px)
                                                 SHORT landscape — a handset on
                                                 its side is ~844x390, far too
                                                 wide for a max-width query, so
                                                 height is what identifies it.
                                                 This also makes the behaviour
                                                 testable by resizing a desktop
                                                 window, which a touch-only
                                                 query is not.
     (hover: none) and (pointer: coarse)         any touch device, e.g. a tablet
                                                 in portrait that is neither
                                                 narrow nor short.
   The JS gate uses this exact string — see zd-media-gallery.js.
   ============================================================ */
@media (max-width: 599px), (orientation: landscape) and (max-height: 600px), (hover: none) and (pointer: coarse) {
  /* Show the WHOLE photo. .zd-ba__ph img is object-fit:cover, which crops to
     fill: that slices the sides off a landscape shot and the top and bottom off
     a portrait one. `contain` keeps the stage ratio fixed — so slides never
     jump — and letterboxes the photo instead, on a dark backdrop so the bars
     read as a viewer surround. Thumbnails keep `cover`: cropping is correct at
     that size. */
  /* The letterbox bars keep the module's own grey — the same treatment the
     before/after placeholders use — rather than the dark backdrop this first
     carried. Nothing to declare: removing the override lets the base rule above
     apply, which also keeps the frame identical to the thumbnails. */
  .zd-spot__frame .zd-ba__ph img { object-fit: contain; }

  /* The caption covers a large share of the frame on a handset — worst of all
     in landscape, where the stage is short — so it waits for a tap on the photo.
     The stage is overflow:hidden, so translating it down clips it cleanly. */
  .zd-spot__caption {
    transform: translateY(101%); opacity: 0;
    transition: transform .28s var(--ease-out), opacity .28s var(--ease-out);
  }
  .zd-spot.is-captioned .zd-spot__caption { transform: none; opacity: 1; }

  /* Trim this section's own chrome on handsets. .zd-section is 56px 0 and
     .zd-container adds 20px each side, which on a small screen is a lot of
     nothing around the one thing people came to look at. Scoped to
     .zd-section--spot so no other section is affected. */
  .zd-section--spot { padding: 26px 0; }
  .zd-section--spot > .zd-container { padding-left: 12px; padding-right: 12px; }
}

/* LOCAL ADDITION — per-photo fit, chosen on the item.
   Leaving it empty keeps today's behaviour: cropped on desktop by the base rule,
   fitted whole on mobile by the block above. An explicit choice has to win at
   BOTH widths, so these sit outside that query and carry one class more than it
   does — 0,3,1 against 0,2,1, enough to outrank it without !important.
   Per item rather than per module because a landscape and a portrait photo in
   one gallery rarely want the same treatment. */
.zd-spot__frame.is-fit-cover .zd-ba__ph img { object-fit: cover; }
.zd-spot__frame.is-fit-contain .zd-ba__ph img { object-fit: contain; }

/* LOCAL ADDITION — handset in LANDSCAPE: give the photo the whole screen.
   At ~844x390 a full-width 16/9 stage computes to ~475px tall, i.e. taller than
   the viewport, so the frame ran off the bottom and the picture could never be
   seen whole. Drop the fixed ratio and cap the stage to the viewport instead,
   and hide the progress bar and filmstrip, which cost vertical space the photo
   needs. Navigation is not lost: the stage arrows and swipe both still work,
   and the counter stays. Portrait keeps the filmstrip — there is height for it.
   svh tracks the visible area as mobile browser chrome collapses; the plain vh
   line above it is the fallback for browsers without svh. */
@media (orientation: landscape) and (max-height: 600px), (hover: none) and (pointer: coarse) and (orientation: landscape) {
  .zd-spot__bar,
  .zd-spot__stripwrap { display: none; }

  /* Squeeze the surrounding chrome to almost nothing so the stage really can be
     viewport-tall: whatever padding is left here has to come off the stage. */
  .zd-section--spot { padding: 8px 0; }
  .zd-section--spot > .zd-container { padding-left: 8px; padding-right: 8px; }

  .zd-spot__stage {
    aspect-ratio: auto;
    height: calc(100vh - 16px);
    height: calc(100svh - 16px);
  }
  /* object-fit: contain is already applied by the touch block above, which a
     landscape handset also matches — no need to repeat it here. With the stage
     now roughly the shape of the screen, a landscape photo very nearly fills it
     and any remaining bars are slight. */

  /* FULLSCREEN, same conditions. The fullscreen rules cap the stage at
     calc(100vh - 160px) to leave room for the progress bar and filmstrip
     underneath — but the rules above hide both, so that 160px became dead
     space, and because the overlay centres its children it showed as a large
     gap above AND below the photo. Release the cap and trim the overlay's own
     24px padding so the photo gets the screen.
     :fullscreen and .is-pseudo-fullscreen are kept in SEPARATE rules on
     purpose: one invalid selector invalidates a whole comma-separated list, so
     pairing them would lose the fallback in any browser that does not know
     :fullscreen. The rest of this file follows the same split. */
  .zd-spot:fullscreen { padding: 8px; gap: 0; }
  .zd-spot:fullscreen .zd-spot__stage { max-height: none; }

  .zd-spot.is-pseudo-fullscreen { padding: 8px; gap: 0; }
  .zd-spot.is-pseudo-fullscreen .zd-spot__stage { max-height: none; }
}
