/*
 * Image viewer (functions/inspiratie/index.js): a photo at the largest size the
 * screen allows, with its caption and products beside it (from 1024px) or
 * under it. A native <dialog> opened with showModal(): top layer, the page
 * behind it inert, Escape to close. The stage is dark so the photo, whatever
 * its proportions, sits in it without a frame of its own; the panel is the
 * page's own surface, so the product links read as they do in the gallery.
 * Decision 21.
 */

.image-viewer {
    /* combined.css gives every dialog position: absolute, top: 0 and (below
       640px) min-height: 100vh - a modal laid out at the top of the document,
       which focusing it then scrolls the page up to. The browser's own
       fixed position, answered here (Decision 4b). */
    position: fixed;
    inset: 0;
    width: 100%;
    max-width: none;
    height: 100%;
    max-height: none;
    margin: 0;
    padding: 0;
    overflow-y: auto;
    min-height: 0;
    border: 0;
    box-shadow: none;
    background: var(--shop-surface-dark);
    color: var(--shop-ink);
}

/* Below 1024px the photo, then the panel, then the navigation as a footer:
   the dialog scrolls when the photo and the panel do not fit (a short or
   landscape phone, zoom, a long list of products), the photo is never covered,
   and the footer stays at the bottom of the screen - sticky when the content
   is long, at the end of the stretched panel when it is short. So previous,
   the count and next stay under the thumb from one photo to the next, whatever
   its proportions or text. */
.image-viewer[open] {
    display: grid;
    grid-template-rows: auto 1fr auto;
}

.image-viewer::backdrop {
    background: var(--shop-surface-dark);
}

/* The page behind does not scroll under the viewer. */
html:has(.image-viewer[open]) {
    overflow: hidden;
}

.image-viewer__stage {
    display: grid;
    /* Horizontal swipes are the viewer's (previous/next); vertical ones scroll, and a
       pinch zooms in on the photo - the reason to open it (the scripts ignore a swipe
       while zoomed in, which is then panning). */
    touch-action: pan-y pinch-zoom;
    user-select: none;
    place-items: center;
    padding: calc(var(--shop-tap) + var(--shop-space-4) + env(safe-area-inset-top)) var(--shop-space-4) var(--shop-space-4);
}

/* As wide as the stage and as tall as its proportions make it (the width and
   height attributes carry them, before the file is in), never taller than
   what the screen leaves the stage - on a phone about two thirds, so the
   caption shows below. The photo is contained in that box, so the gallery's
   copy shown first and the large file that replaces it take the same place. */
.image-viewer__image {
    display: block;
    width: 100%;
    height: auto;
    max-height: calc(70vh - var(--shop-tap));
    max-height: calc(70dvh - var(--shop-tap));
    object-fit: contain;
}

/* An item the page has not loaded shows its small fill image first, softened
   until the large photo replaces it. */
.image-viewer__image.is-loading {
    filter: blur(8px);
}

.image-viewer__panel {
    display: grid;
    align-content: start;
    gap: var(--shop-space-5);
    padding: var(--shop-space-5) var(--shop-space-4) var(--shop-space-6);
    background: var(--shop-surface);
}

.image-viewer__info {
    display: grid;
    align-content: start;
    gap: var(--shop-space-4);
}

.image-viewer__caption {
    color: var(--shop-ink);
    font-size: var(--shop-text-base);
    line-height: var(--shop-leading-normal);
}

.image-viewer__nav {
    position: sticky;
    inset-block-end: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--shop-space-3);
    padding: var(--shop-space-3) var(--shop-space-4) calc(var(--shop-space-3) + env(safe-area-inset-bottom));
    border-block-start: 1px solid var(--shop-divider);
    background: var(--shop-surface);
}

.image-viewer__position {
    margin: 0;
    text-align: center;
    color: var(--shop-text-soft);
    font-size: var(--shop-text-sm);
    line-height: var(--shop-leading-normal);
    font-variant-numeric: tabular-nums;
}

/* button.-qualified: base.css hands buttons back to the browser at (0,1,1)
   on :hover/:focus, and the close button has focus from the moment the viewer
   opens (Decision 5). */
button.image-viewer__step,
button.image-viewer__close {
    display: inline-grid;
    place-items: center;
    width: var(--shop-tap);
    height: var(--shop-tap);
    padding: 0;
    border-radius: 50%;
    cursor: pointer;
}

button.image-viewer__step,
button.image-viewer__step:hover,
button.image-viewer__step:focus {
    border: 1px solid var(--shop-border);
    background: var(--shop-surface);
    color: var(--shop-ink);
}

button.image-viewer__step:hover:not(:disabled) {
    border-color: var(--shop-accent);
    color: var(--shop-accent);
}

button.image-viewer__step:disabled {
    opacity: 0.35;
    cursor: default;
}

.image-viewer__step svg,
.image-viewer__close svg {
    width: 20px;
    height: 20px;
}

/* In the screen's corner, also while the dialog scrolls. On the dark stage:
   light on dark, and the dark surface's focus colour. */
button.image-viewer__close {
    position: fixed;
    inset-block-start: calc(var(--shop-space-3) + env(safe-area-inset-top));
    inset-inline-end: calc(var(--shop-space-3) + env(safe-area-inset-right));
    z-index: 1;
}

button.image-viewer__close,
button.image-viewer__close:hover,
button.image-viewer__close:focus {
    border: 1px solid var(--shop-on-dark-rule);
    background: var(--shop-surface-dark);
    color: var(--shop-on-dark);
}

button.image-viewer__close:hover {
    border-color: var(--shop-on-dark);
}

button.image-viewer__close:focus-visible {
    outline-color: var(--shop-on-dark-focus);
}

/* Beside the photo: the photo takes the height of the screen, the panel a
   reading column that scrolls on its own, with the navigation at its foot. */
@media (min-width: 1024px) {
    .image-viewer[open] {
        grid-template-columns: minmax(0, 1fr) 22rem;
        grid-template-rows: minmax(0, 1fr) auto;
        overflow: hidden;
    }

    .image-viewer__stage {
        grid-row: 1 / -1;
        min-height: 0;
        padding: var(--shop-space-8);
    }

    .image-viewer__image {
        max-height: calc(100vh - 2 * var(--shop-space-8));
        max-height: calc(100dvh - 2 * var(--shop-space-8));
    }

    .image-viewer__panel {
        padding: calc(var(--shop-tap) + var(--shop-space-6)) var(--shop-space-6) var(--shop-space-5);
        overflow-y: auto;
    }

    .image-viewer__nav {
        position: static;
        grid-column: 2;
        padding: 0 var(--shop-space-6) var(--shop-space-6);
        border-block-start: 0;
    }
}

@media (forced-colors: active) {
    .image-viewer__panel {
        border-block-start: 1px solid CanvasText;
    }
}
