'use client'; /** * LightboxChrome - Restrained, macOS-grade floating controls for the * fullscreen image lightbox. * * Design intent (Apple HIG / Quick Look / Preview): * - Minimal chrome: a single close affordance (top-right), prev/next only * when there is more than one image, and one unobtrusive status pill * (counter + live zoom %). * - Everything floats on liquid-glass and fades together when the pointer * goes idle, reappearing on the slightest movement. * - No checkerboard, no rotate/flip slab — the image is the subject. */ import { ChevronLeft, ChevronRight, X } from 'lucide-react'; import { cn } from '@djangocfg/ui-core/lib'; import { MiddleEllipsis } from './MiddleEllipsis'; interface LightboxChromeProps { /** Visible (recent pointer activity) vs faded (idle). */ active: boolean; /** 1-based index for the counter. */ index: number; total: number; /** Live zoom scale (1 = fit). The % pill only shows when zoomed in/out. */ scale: number; fileName?: string; onPrev: () => void; onNext: () => void; onClose: () => void; /** Pin chrome open while the pointer hovers a control. */ onPinChange: (pinned: boolean) => void; labels: { prev: string; next: string; close: string }; } // Liquid-glass circular control — light icon on translucent vibrancy so it // stays legible over any photo (bright or dark) without a hard slab. const GLASS_BTN = 'glass-liquid pointer-events-auto inline-flex items-center justify-center ' + 'rounded-full text-white/90 transition-[background-color,transform,opacity] ' + 'hover:text-white hover:bg-white/15 active:scale-95 ' + 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/70'; export function LightboxChrome({ active, index, total, scale, fileName, onPrev, onNext, onClose, onPinChange, labels, }: LightboxChromeProps) { const hasMultiple = total > 1; // Only surface the zoom pill once the image is meaningfully off fit — at // exactly fit (1.0) the % is noise. const zoomed = Math.abs(scale - 1) > 0.01; const zoomPct = `${Math.round(scale * 100)}%`; // Whole chrome layer fades as one. `pointer-events-none` on the layer means // the faded state never eats clicks meant for the image (pan/double-click). return (