/* File: /assets/css/image-zoom.css
   Module: The image viewer for article figures (assets/js/image-zoom.js)

   Two parts. The Zoom pill on every figure in the article, and the viewer
   itself: a full screen native <dialog>, dark in both themes because it is
   an overlay (CLAUDE.md, LIGHT MODE HAS NO DARK PANELS lists overlays among
   what is dark by nature).

   Every accent reads the heat engine's phase variables (--ch-ekg-color,
   --ch-ekg-glow, --ch-ekg-speed from heat-engine.css and heat-engine.js), so
   the viewer wears the reader's current phase and Premium's steady emerald.
   Small text in the phase color is mixed 35% toward white first: the blue
   phase (#2563EB) is 4.1:1 on the viewer's near-black and the mix is 7:1.

   Buttons declare color and background on every state: GeneratePress paints
   button:hover and :focus #3f4047 with white text at 0,1,1. */

/* ==========================================================================
   1. THE ZOOM PILL ON ARTICLE FIGURES
   ========================================================================== */
.entry-content .ch-zoomable {
    position: relative;
    cursor: zoom-in;
}

.entry-content .ch-zoom-btn,
.entry-content .ch-zoom-btn:hover,
.entry-content .ch-zoom-btn:focus,
.entry-content .ch-zoom-btn:active {
    position: absolute;
    right: 12px;
    bottom: 12px;
    z-index: 4;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    margin: 0;
    padding: 0 12px 0 10px;
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 999px;
    background-color: rgba(15, 23, 42, 0.8);
    background-image: none;
    color: #FFFFFF;
    font-family: Inter, -apple-system, 'Segoe UI', Roboto, sans-serif;
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1;
    cursor: zoom-in;
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    box-shadow: 0 10px 22px -12px rgba(2, 6, 23, 0.7);
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 0.25s ease, transform 0.35s cubic-bezier(0.22, 1, 0.36, 1), background-color 0.2s ease, box-shadow 0.25s ease;
}

.entry-content .ch-zoom-btn svg {
    flex-shrink: 0;
}

.entry-content .ch-zoomable:hover .ch-zoom-btn,
.entry-content .ch-zoom-btn:focus-visible {
    opacity: 1;
    transform: none;
}

.entry-content .ch-zoom-btn:hover,
.entry-content .ch-zoom-btn:focus-visible {
    background-color: rgba(15, 23, 42, 0.94);
    color: #FFFFFF;
    box-shadow: 0 10px 22px -12px rgba(2, 6, 23, 0.7), 0 0 0 3px var(--ch-ekg-glow, rgba(16, 185, 129, 0.3));
}

.entry-content .ch-zoom-btn:focus-visible {
    outline: 2px solid #FFFFFF;
    outline-offset: 2px;
}

/* Gallery tiles carry their caption inside the tile: the pill moves up. */
.entry-content .wp-block-gallery .ch-zoom-btn,
.entry-content .gallery .ch-zoom-btn {
    top: 10px;
    right: 10px;
    bottom: auto;
}

/* Touch screens have no hover: a small round button, always there. */
@media (hover: none) {
    .entry-content .ch-zoom-btn,
    .entry-content .ch-zoom-btn:hover,
    .entry-content .ch-zoom-btn:focus,
    .entry-content .ch-zoom-btn:active {
        width: 36px;
        height: 36px;
        padding: 0;
        justify-content: center;
        opacity: 1;
        transform: none;
    }

    .entry-content .ch-zoom-btn span {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }
}

/* ==========================================================================
   2. SCROLL LOCK
   ========================================================================== */
html.ch-zoom-open {
    overflow: hidden;
}

html.ch-zoom-open body {
    padding-right: var(--ch-zoom-gap, 0px);
}

/* ==========================================================================
   3. THE VIEWER
   ========================================================================== */
.ch-zoom {
    --zoom-accent: #CBD5E1;
    --zoom-accent: color-mix(in srgb, var(--ch-ekg-color, #10B981) 65%, #FFFFFF);
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    max-width: none;
    max-height: none;
    margin: 0;
    padding: 0;
    border: 0;
    overflow: hidden;
    background: transparent;
    color: #E2E8F0;
    font-family: Inter, -apple-system, 'Segoe UI', Roboto, sans-serif;
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
}

.ch-zoom::backdrop {
    background: transparent;
}

.ch-zoom:focus {
    outline: none;
}

.ch-zoom p {
    margin: 0;
}

.ch-zoom-scrim {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse at 50% 45%, rgba(15, 23, 42, 0.9) 0%, rgba(2, 6, 23, 0.97) 70%),
        rgba(2, 6, 23, 0.96);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    opacity: 0;
    transition: opacity 0.32s ease;
}

.ch-zoom.is-open .ch-zoom-scrim {
    opacity: var(--ch-zoom-fade, 1);
}

.ch-zoom.is-dragging .ch-zoom-scrim {
    transition: none;
}

.ch-zoom-stage {
    position: absolute;
    inset: 0;
    overflow: hidden;
    cursor: zoom-in;
}

.ch-zoom.is-zoomed .ch-zoom-stage {
    cursor: grab;
}

.ch-zoom.is-dragging .ch-zoom-stage {
    cursor: grabbing;
}

/* The free area the image fits into: clear of the toolbar, the arrows and
   the caption. image-zoom.js reads its box; nothing paints it. */
.ch-zoom-area {
    position: absolute;
    top: 76px;
    right: 88px;
    bottom: 96px;
    left: 88px;
    pointer-events: none;
}

/* Laid out at the file's own pixel size and scaled down by image-zoom.js, so
   it is rasterized from full resolution at every zoom. The white fill keeps a
   transparent chart readable on the dark scrim. */
.ch-zoom-pic {
    position: absolute;
    top: 0;
    left: 0;
    max-width: none;
    max-height: none;
    margin: 0;
    border: 0;
    border-radius: 0;
    background-color: #FFFFFF;
    box-shadow: 0 40px 90px -40px rgba(0, 0, 0, 0.9), 0 0 0 1px rgba(148, 163, 184, 0.16);
    transform-origin: 0 0;
    will-change: transform;
    -webkit-user-drag: none;
    pointer-events: none;
}

/* --- 3.1 Toolbar: figure number left, controls right ------------------- */
.ch-zoom-top {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: max(14px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) 14px max(16px, env(safe-area-inset-left));
    background: linear-gradient(180deg, rgba(2, 6, 23, 0.72) 0%, rgba(2, 6, 23, 0) 100%);
    pointer-events: none;
}

.ch-zoom-top > * {
    pointer-events: auto;
}

.ch-zoom-count {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    padding: 8px 12px;
    border: 1px solid rgba(148, 163, 184, 0.2);
    border-radius: 12px;
    background-color: rgba(15, 23, 42, 0.72);
    color: #CBD5E1;
    font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    line-height: 1.2;
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
}

.ch-zoom-count b {
    color: var(--zoom-accent);
    font-weight: 800;
}

.ch-zoom-tools {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 4px;
    border: 1px solid rgba(148, 163, 184, 0.22);
    border-radius: 14px;
    background-color: rgba(15, 23, 42, 0.76);
    box-shadow: 0 14px 34px -18px rgba(0, 0, 0, 0.9);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
}

.ch-zoom .ch-zoom-tool,
.ch-zoom .ch-zoom-tool:visited,
.ch-zoom .ch-zoom-tool:hover,
.ch-zoom .ch-zoom-tool:focus,
.ch-zoom .ch-zoom-tool:active {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 38px;
    height: 38px;
    margin: 0;
    padding: 0 8px;
    border: 0;
    border-radius: 10px;
    background-color: transparent;
    background-image: none;
    color: #E2E8F0;
    font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
    font-size: 0.78rem;
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.ch-zoom .ch-zoom-tool:hover,
.ch-zoom .ch-zoom-tool:focus-visible {
    background-color: rgba(148, 163, 184, 0.2);
    color: #FFFFFF;
}

.ch-zoom .ch-zoom-tool:focus-visible,
.ch-zoom .ch-zoom-nav:focus-visible {
    outline: 2px solid var(--zoom-accent);
    outline-offset: 1px;
}

.ch-zoom .ch-zoom-tool:disabled,
.ch-zoom .ch-zoom-tool:disabled:hover {
    background-color: transparent;
    color: #64748B;
    cursor: default;
}

.ch-zoom .ch-zoom-level,
.ch-zoom .ch-zoom-level:hover,
.ch-zoom .ch-zoom-level:focus {
    min-width: 62px;
    color: var(--zoom-accent);
    font-variant-numeric: tabular-nums;
}

.ch-zoom .ch-zoom-level:hover,
.ch-zoom .ch-zoom-level:focus-visible {
    color: #FFFFFF;
}

.ch-zoom .ch-zoom-tool.is-close:hover,
.ch-zoom .ch-zoom-tool.is-close:focus-visible {
    background-color: rgba(239, 68, 68, 0.24);
    color: #FFFFFF;
}

.ch-zoom-sep {
    width: 1px;
    height: 22px;
    margin: 0 4px;
    background-color: rgba(148, 163, 184, 0.28);
}

/* --- 3.2 Previous and next --------------------------------------------- */
.ch-zoom .ch-zoom-nav,
.ch-zoom .ch-zoom-nav:hover,
.ch-zoom .ch-zoom-nav:focus,
.ch-zoom .ch-zoom-nav:active {
    position: absolute;
    top: 50%;
    display: grid;
    place-items: center;
    width: 52px;
    height: 52px;
    margin: -26px 0 0;
    padding: 0;
    border: 1px solid rgba(148, 163, 184, 0.24);
    border-radius: 50%;
    background-color: rgba(15, 23, 42, 0.72);
    background-image: none;
    color: #E2E8F0;
    cursor: pointer;
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.25s ease, opacity 0.25s ease;
}

.ch-zoom .ch-zoom-nav.is-prev {
    left: max(18px, env(safe-area-inset-left));
}

.ch-zoom .ch-zoom-nav.is-next {
    right: max(18px, env(safe-area-inset-right));
}

.ch-zoom .ch-zoom-nav:hover,
.ch-zoom .ch-zoom-nav:focus-visible {
    background-color: rgba(30, 41, 59, 0.94);
    color: #FFFFFF;
    box-shadow: 0 0 0 4px var(--ch-ekg-glow, rgba(16, 185, 129, 0.3));
}

.ch-zoom .ch-zoom-nav[hidden] {
    display: none;
}

/* --- 3.3 Caption --------------------------------------------------------- */
.ch-zoom-cap {
    position: absolute;
    left: 50%;
    bottom: max(18px, env(safe-area-inset-bottom));
    width: min(780px, calc(100% - 32px));
    max-height: 30vh;
    overflow: auto;
    padding: 11px 18px;
    border: 1px solid rgba(148, 163, 184, 0.2);
    border-radius: 12px;
    background-color: rgba(15, 23, 42, 0.76);
    color: #E2E8F0;
    font-size: 0.88rem;
    line-height: 1.5;
    text-align: center;
    transform: translateX(-50%);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    transition: opacity 0.25s ease, transform 0.3s ease;
}

.ch-zoom-cap[hidden] {
    display: none;
}

/* While zoomed the caption steps aside for the map. */
.ch-zoom.is-zoomed .ch-zoom-cap {
    opacity: 0;
    transform: translate(-50%, 10px);
    pointer-events: none;
}

/* --- 3.4 The map: where in the image the screen is ---------------------- */
.ch-zoom-map {
    position: absolute;
    right: max(18px, env(safe-area-inset-right));
    bottom: max(18px, env(safe-area-inset-bottom));
    overflow: hidden;
    border: 1px solid rgba(148, 163, 184, 0.35);
    border-radius: 8px;
    background-color: #0F172A;
    box-shadow: 0 16px 34px -16px rgba(0, 0, 0, 0.9);
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.2s ease, transform 0.25s ease;
    pointer-events: none;
    touch-action: none;
    cursor: pointer;
}

.ch-zoom-map.is-on {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.ch-zoom-map img {
    display: block;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0.8;
    pointer-events: none;
}

.ch-zoom-map span {
    position: absolute;
    top: 0;
    left: 0;
    border: 2px solid var(--ch-ekg-color, #10B981);
    border-radius: 3px;
    box-shadow: 0 0 0 999px rgba(2, 6, 23, 0.5), 0 0 10px var(--ch-ekg-glow, rgba(16, 185, 129, 0.3));
    pointer-events: none;
}

/* --- 3.5 Loading: the EKG trace, at the phase's own speed --------------- */
.ch-zoom-loader {
    position: absolute;
    top: 74px;
    left: 50%;
    width: 120px;
    height: 24px;
    margin-left: -60px;
    opacity: 0;
    transition: opacity 0.2s ease;
    pointer-events: none;
}

.ch-zoom.is-loading .ch-zoom-loader {
    opacity: 1;
}

.ch-zoom-loader svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.ch-zoom-loader path {
    fill: none;
    stroke: var(--ch-ekg-color, #10B981);
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 70 190;
    filter: drop-shadow(0 0 4px var(--ch-ekg-glow, rgba(16, 185, 129, 0.3)));
    animation: chZoomTrace var(--ch-ekg-speed, 1.6s) linear infinite;
}

@keyframes chZoomTrace {
    from { stroke-dashoffset: 260; }
    to   { stroke-dashoffset: 0; }
}

/* --- 3.6 First-open hint -------------------------------------------------- */
.ch-zoom-hint {
    position: absolute;
    left: 50%;
    bottom: calc(max(18px, env(safe-area-inset-bottom)) + 70px);
    padding: 10px 18px;
    border: 1px solid rgba(148, 163, 184, 0.3);
    border-radius: 999px;
    background-color: rgba(15, 23, 42, 0.9);
    color: #F1F5F9;
    font-size: 0.84rem;
    font-weight: 600;
    white-space: nowrap;
    box-shadow: 0 0 0 4px var(--ch-ekg-glow, rgba(16, 185, 129, 0.3));
    opacity: 0;
    transform: translate(-50%, 8px);
    transition: opacity 0.3s ease, transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
    pointer-events: none;
}

.ch-zoom.has-hint .ch-zoom-hint {
    opacity: 1;
    transform: translate(-50%, 0);
}

/* --- 3.7 Showing, leaving, bare ------------------------------------------ */
.ch-zoom-top,
.ch-zoom .ch-zoom-nav,
.ch-zoom-cap {
    opacity: 0;
}

.ch-zoom.is-open .ch-zoom-top,
.ch-zoom.is-open .ch-zoom-nav,
.ch-zoom.is-open .ch-zoom-cap {
    opacity: 1;
    transition: opacity 0.3s ease 0.08s, transform 0.3s ease;
}

.ch-zoom.is-open.is-zoomed .ch-zoom-cap {
    opacity: 0;
}

/* A single tap clears the screen for the image, a second brings it back. */
.ch-zoom.is-open.is-bare .ch-zoom-top,
.ch-zoom.is-open.is-bare .ch-zoom-nav,
.ch-zoom.is-open.is-bare .ch-zoom-cap,
.ch-zoom.is-open.is-bare .ch-zoom-map {
    opacity: 0;
    pointer-events: none;
}

.ch-zoom.is-leaving .ch-zoom-pic {
    opacity: 0;
    transition: opacity 0.2s ease;
}

/* ==========================================================================
   4. PHONES
   ========================================================================== */
@media (max-width: 640px) {
    .ch-zoom-area {
        top: 68px;
        right: 8px;
        bottom: 88px;
        left: 8px;
    }

    .ch-zoom-top {
        padding-right: max(10px, env(safe-area-inset-right));
        padding-left: max(10px, env(safe-area-inset-left));
    }

    /* Swipe sideways instead. */
    .ch-zoom .ch-zoom-nav,
    .ch-zoom .ch-zoom-nav:hover,
    .ch-zoom .ch-zoom-nav:focus {
        display: none;
    }

    .ch-zoom-count {
        padding: 8px 10px;
        font-size: 0.7rem;
    }

    .ch-zoom .ch-zoom-tool,
    .ch-zoom .ch-zoom-tool:visited,
    .ch-zoom .ch-zoom-tool:hover,
    .ch-zoom .ch-zoom-tool:focus,
    .ch-zoom .ch-zoom-tool:active {
        min-width: 40px;
        height: 40px;
        padding: 0 6px;
    }

    .ch-zoom .ch-zoom-level,
    .ch-zoom .ch-zoom-level:hover,
    .ch-zoom .ch-zoom-level:focus {
        min-width: 54px;
    }

    .ch-zoom-sep {
        display: none;
    }

    .ch-zoom-cap {
        padding: 9px 14px;
        font-size: 0.8rem;
    }

    .ch-zoom-hint {
        font-size: 0.78rem;
    }
}

@media (max-width: 360px) {
    .ch-zoom .ch-zoom-tool[data-z="file"] {
        display: none;
    }
}

/* ==========================================================================
   5. REDUCED MOTION
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    .entry-content .ch-image-frame img,
    .entry-content .ch-image-wrapper:hover .ch-image-frame img {
        transform: none;
        transition: none;
    }

    .entry-content .ch-zoom-btn,
    .ch-zoom-scrim,
    .ch-zoom-top,
    .ch-zoom .ch-zoom-nav,
    .ch-zoom-cap,
    .ch-zoom-map,
    .ch-zoom-hint,
    .ch-zoom.is-open .ch-zoom-top,
    .ch-zoom.is-open .ch-zoom-nav,
    .ch-zoom.is-open .ch-zoom-cap {
        transition: none;
    }

    .ch-zoom-loader path {
        animation-duration: 3s;
    }
}
