/* uc-lightbox.css -- the lightbox, on any page that has one.
 *
 * SPLIT OUT OF uc-product.css AT F4.5, unchanged. F4.4 built one vanilla
 * lightbox to replace fancybox v2 and v3 on the product page (`S26`), and
 * category-pages.md criterion 31 requires the vendor route's certificates to
 * use that one rather than a second implementation -- `vendor.html:71` was the
 * last `$(...).fancybox()` caller on the site.
 *
 * Two templates load it now, so it is its own file. Nothing here changed in
 * the move; the rules are F3.7's, signed off 2026-09-06.
 */
/* P3 and P10. ONE implementation, serving both call styles: the gallery's
 * `data-fancybox="gallery"` and the certificates' older
 * `class="fancybox-group" rel="…"`. That is criterion 4, and retiring both
 * fancybox v2 and v3 is what closes `S26`.
 *
 * It matches P10's behaviour table and adds nothing outside it. fancybox's own
 * `buttons` array on this page is ["zoom","close"], so there is no slideshow,
 * no thumbnail rail, no fullscreen and no download here either.
 *
 * IT DOES NOT REUSE THE DIALOG'S SCRIM, and that was the first thing browsing
 * it showed. --scrim-dialog is rgba(23,39,43,.5), which is right behind a white
 * card: the card supplies the contrast. Here the content IS the photograph,
 * most product shots are on a white ground, and at 50% the image did not
 * separate from the half-dimmed page behind it -- the fixed callback button
 * showed through beside the close control. A lightbox is judged on the image,
 * so the ground has to get out of the way. fancybox uses ~.87 black; this is
 * the chrome's own ink at .92, which keeps the palette. */
.lb { position: fixed; inset: 0; z-index: 80; display: flex; flex-direction: column;
  background: rgba(23, 39, 43, .92); }
/* THE hidden ATTRIBUTE HAS TO BE RESTORED FOR EVERY RULE THAT SETS display,
 * and this is the second time the project has learned it. `hidden` is styled by
 * the user agent as `display: none` at the LOWEST possible specificity, so any
 * class rule setting `display` beats it -- uc-chrome.css carries the same note
 * for `.dlg`, written when the dialog rendered open on every page and could not
 * be closed.
 *
 * Here it was `.lb-b { display: flex }` against the arrows: `show()` sets
 * `hidden` on both whenever the group holds one image, and they stayed on
 * screen anyway. So a single photograph and a lone certificate both offered a
 * previous and a next that went nowhere. Owner, 2026-09-07.
 *
 * ANY FUTURE .lb-* RULE THAT SETS display MUST BE ADDED HERE. */
.lb[hidden], .lb-b[hidden] { display: none; }
/* NO FLEX CENTRING HERE, and that is not a simplification -- it is the fix for
 * a bug browsing found. An absolutely positioned child of a centring flex
 * container takes its STATIC POSITION from that centring, so the image's origin
 * was already the middle of the stage and the script's translate moved it again
 * from there: a 1500px image opened at (-251,-351), most of it off the corner.
 * The script owns placement, so the box must not also have an opinion. */
.lb-stage {
  flex: 1; min-height: 0; position: relative; overflow: hidden;
  touch-action: none;              /* we own the gestures -- P10's mechanism */
}
.lb-img {
  position: absolute; top: 0; left: 0; transform-origin: 0 0;
  max-width: none; max-height: none;   /* the script sizes it, not the box */
  user-select: none; -webkit-user-drag: none;
}
.lb-img.is-zoomed { cursor: grab; }
.lb-img.is-dragging { cursor: grabbing; }
.lb-bar {
  flex: none; display: flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-3); color: #fff;
}
.lb-count { font-size: 13px; font-variant-numeric: tabular-nums; opacity: .8; flex: none; }
.lb-cap { font-size: 13px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-b {
  width: var(--target); height: var(--target); flex: none;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--r); background: rgba(255,255,255,.12);
  color: #fff; cursor: pointer;
}
.lb-b:hover { background: rgba(255,255,255,.24); }
.lb-b[disabled] { opacity: .35; cursor: not-allowed; }
.lb-b .ds-ic { width: 22px; height: 22px; }
/* The arrows are over the image, and they are 44px targets like everything
 * else -- P1 does not stop at the page edge.
 *
 * THE BOX STAYS TRANSPARENT AND THE GLYPH CARRIES ITS OWN CONTRAST. The owner
 * reported the arrows invisible on white photographs from a phone, 2026-09-06;
 * the first answer was an opaque teal button, and the owner rejected it the
 * same day for the right reason -- a 44px filled square sits on top of the
 * picture and hides whatever is under it, and on this catalogue that can be a
 * model number or a dimension printed on the product.
 *
 * So the arrow is outlined instead of backed. A white chevron reads on a dark
 * image; the dark halo around it reads on a white one; and between them they
 * cover four stroke-widths of picture rather than 1,936 square pixels of it.
 * Two shadows rather than one: the tight pass draws the edge, the loose pass
 * keeps it from disappearing into a busy mid-tone. */
.lb-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 1;
  width: var(--target); height: var(--target);
}
/* Three passes, and they are stacked rather than widened on purpose. A single
 * soft shadow reads as a smudge and disappears on white; identical tight
 * shadows compound their alpha into something closer to an outline, which is
 * what a stroked glyph needs and what `paint-order` would give it if the path
 * had a fill to paint under. The last, wider pass keeps it off a busy
 * mid-tone. */
.lb-nav .ds-ic {
  filter: drop-shadow(0 0 1px #17272b) drop-shadow(0 0 1px #17272b)
          drop-shadow(0 0 1px #17272b) drop-shadow(0 0 5px rgba(23, 39, 43, .55));
}
.lb-prev { left: var(--s-2); }
.lb-next { right: var(--s-2); }
.lb-b:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .lb-img { transition: none !important; } }
