/* ===================================================================
   Lumen - every photo in its own passe-partout
   Version: 1.0.2
   Author: Reveloni
   For: Reveloni CMS 7.0.0+ (built and tested on 7.6.9)

   Changelog:
   1.0.0 - first release. Built on the mechanics of Fotolab 1.0.1: the
           development effect, the loupe and the closing hero frame work
           exactly as there; the darkroom props are replaced by a neutral
           language of mounted prints so the theme suits any business
           that sells with pictures.
   1.0.1 - the loupe works on nested pages too (/parent/child): it took
           the large file from a relative 'uploads/' address, which
           resolves under the page path there, and showed an empty
           glass. The folder now comes from the thumbnail's absolute
           address.
   1.0.2 - wider text column: about 115 characters per line instead of
           about 75 - at 75 the text stood as a narrow pillar on a
           desktop screen. Phones are unchanged.

   THE ONE RULE (carried over from Fotolab): THE PHOTOGRAPH IS NEVER
   TOUCHED. Nothing here tints, blurs, blends or crops a gallery photo.
   The colour scheme lives around the pictures, never on them. The
   development effect is the only thing that ever puts a filter on an
   image, it runs once, and it ends at filter: none.

   The page is a framing studio:
   - the gallery is a wall of PASSE-PARTOUTS: every mat is the same size,
     and every window is cut to the shape of its own photo, so upright,
     square and wide pictures are all shown whole. The window has a white
     bevel, as a real mat cut at 45 degrees does;
   - page cards are PRINTS with a white border lying on the table;
   - the hero is a LIT PRINT: two crop corners close in on it and the
     lamp comes on (first page of a visit only);
   - the lightbox is the viewing table: neutral black.

   What the panel drives:
   - colour scheme = the MARKER: crop corners on hover, the stroke under
     headings, the menu's centre dot, the palette card on pages without
     a photo, and the tint of the hero's base. The marker never carries
     text; where text needs the scheme (links, buttons) it is mixed
     toward the ink so it stays legible on all 48 schemes;
   - animation slider = how strongly photos develop (read by head.html)
     and how far the hero corners travel; at 0 photos appear at once;
   - animations off = no development at all, photos are there at once;
   - footer colour is the panel's, taken halfway to black (see FOOTER);
   - dark mode = the studio at night: neutral graphite, black mats with a
     white bevel, and the room lit by a lamp in the scheme colour.
   =================================================================== */

/* ===================================================================
   TOKENS
   =================================================================== */

:root {
    --lu-table: #e5e4e0;
    --lu-paper: #fbfbf9;
    --lu-paper-2: #f0efeb;
    --lu-rule: #d0cec8;
    --lu-ink: #1c1d1f;
    --lu-ink-soft: #55575b;

    /* The scheme as marker (ornament) and as legible ink (text). */
    --lu-marker: color-mix(in srgb, var(--primary) 78%, var(--lu-ink));
    --lu-mark: color-mix(in srgb, var(--primary) 30%, var(--lu-ink));
    --lu-on-mark: var(--lu-paper);

    /* Passe-partout. */
    --lu-mat: #f4f3ef;           /* mat board face */
    --lu-core: #ffffff;          /* white core showing in the bevel */
    --lu-cut: rgba(0, 0, 0, 0.18);
    --lu-window: #e9e8e3;        /* behind a photo that is still loading */

    /* The hero: a base tinted by the scheme, white lamp light on the print. */
    --lu-base: color-mix(in srgb, var(--primary) 26%, #161616);
    --lu-light: #fffdf7;
    --lu-corner: color-mix(in srgb, var(--primary) 45%, #f4f2ec);

    /* Development: strength 0..1 and duration, overwritten by head.html
       from the panel slider. */
    --lu-dev-s: 1;
    --lu-dev-time: 1.15s;
    --lu-travel: calc(var(--animation-offset, 20px) * 4);

    --lu-sans: 'Hanken Grotesk', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --lu-serif: 'Brygada 1918', Georgia, 'Times New Roman', serif;

    /* Aliases some engine markup and inline styles expect. */
    --text: var(--lu-ink);
    --text-light: var(--lu-ink-soft);
    --bg-light: var(--lu-paper-2);
}

html[data-theme="dark"] {
    --lu-table: #0f1011;
    --lu-paper: #191a1c;
    --lu-paper-2: #222327;
    --lu-rule: #35373b;
    --lu-ink: #ecebe7;
    --lu-ink-soft: #b4b3ae;

    --lu-marker: color-mix(in srgb, var(--primary) 62%, #ecebe7);
    --lu-mark: color-mix(in srgb, var(--primary) 45%, #ecebe7);
    --lu-on-mark: #121314;

    --lu-mat: #121315;
    --lu-core: #d8d5cd;
    --lu-cut: rgba(0, 0, 0, 0.6);
    --lu-window: #1d1e21;

    --lu-base: color-mix(in srgb, var(--primary) 20%, #0b0b0c);

    /* The lamp in the scheme colour, lifted toward white so that dark
       schemes still give a visible light. */
    --lu-glow: color-mix(in srgb, color-mix(in srgb, var(--primary) 75%, #fff) 26%, transparent);
    --lu-glow-soft: color-mix(in srgb, color-mix(in srgb, var(--primary) 75%, #fff) 11%, transparent);
}

/* ===================================================================
   BASE
   =================================================================== */

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: var(--lu-sans);
    font-size: 1.0625rem;
    line-height: 1.65;
    color: var(--lu-ink);
    background: var(--lu-table);
    -webkit-font-smoothing: antialiased;
}

/* The lamp. A static fixed layer with no blending, so it is composited
   once and costs nothing while scrolling (Preparat audit). */
html[data-theme="dark"] body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(900px 620px at 88% -8%, var(--lu-glow), transparent 62%),
        radial-gradient(760px 520px at 4% 108%, var(--lu-glow-soft), transparent 60%);
}

h1,
h2,
h3,
h4 {
    font-family: var(--lu-serif);
    font-weight: 500;
    line-height: 1.15;
    color: var(--lu-ink);
    letter-spacing: -0.005em;
}

a {
    color: var(--lu-mark);
}

/* 1440px: on a 1920px screen each side margin is 12.5% of the width. */
.container {
    max-width: 1440px;
    margin: 0 auto;
    padding: 0 20px;
}

/* ===================================================================
   HEADER - sticky, fleet convention. No position: relative here: it
   would silently override sticky. No overflow either: the engine renders
   the dropdown inside the header (Zest 1.0.1).
   =================================================================== */

header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: var(--lu-paper);
    border-bottom: 1px solid var(--lu-rule);
}

html[data-theme="dark"] header {
    background: #141517;
}

/* The dropdown anchors here: top: 100% is the bottom of the bar. */
header .container {
    position: relative;
}

.header-content {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    padding: 0.75rem 0;
}

.logo-container img {
    height: 80px;
    width: auto;
    display: block;
}

.site-title {
    font-family: var(--lu-serif);
    font-weight: 500;
    font-size: 1.55rem;
    line-height: 1.1;
    color: var(--lu-ink);
}

nav ul {
    display: flex;
    align-items: center;
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Menu control: a viewfinder - four corner marks round a dot in the
   scheme colour; on hover the corners close in, as when you frame a
   shot. The engine emits <span>glyph</span><span>Menu</span>; the glyph
   is hidden with font-size: 0 and the span is redrawn. */
.hamburger-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
    font-family: var(--lu-sans);
    font-weight: 500;
    font-size: 0.95rem;
    color: var(--lu-ink);
    background: transparent;
    border: 1px solid var(--lu-rule);
    border-radius: 2px;
    padding: 0.5rem 1rem 0.5rem 0.85rem;
    cursor: pointer;
}

.hamburger-btn:hover {
    border-color: var(--lu-ink);
}

.hamburger-btn span:first-child {
    position: relative;
    display: block;
    width: 20px;
    height: 15px;
    font-size: 0;
    background:
        linear-gradient(currentColor, currentColor) 0 0 / 7px 2px,
        linear-gradient(currentColor, currentColor) 0 0 / 2px 6px,
        linear-gradient(currentColor, currentColor) 100% 0 / 7px 2px,
        linear-gradient(currentColor, currentColor) 100% 0 / 2px 6px,
        linear-gradient(currentColor, currentColor) 0 100% / 7px 2px,
        linear-gradient(currentColor, currentColor) 0 100% / 2px 6px,
        linear-gradient(currentColor, currentColor) 100% 100% / 7px 2px,
        linear-gradient(currentColor, currentColor) 100% 100% / 2px 6px;
    background-repeat: no-repeat;
    transition: transform 0.2s ease;
}

.hamburger-btn span:first-child::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 5px;
    height: 5px;
    margin: -2.5px 0 0 -2.5px;
    border-radius: 50%;
    background: var(--lu-marker);
}

.hamburger-btn:hover span:first-child {
    transform: scale(0.8);
}

.dropdown-menu {
    display: none;
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 60;
    min-width: 250px;
    max-height: 70vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: pan-y;
    background: var(--lu-paper);
    border: 1px solid var(--lu-rule);
    box-shadow: 0 16px 34px -12px rgba(0, 0, 0, 0.4);
    padding: 0.4rem;
}

.dropdown-menu.active {
    display: block;
}

.dropdown-menu ul {
    display: block;
    list-style: none;
    margin: 0;
    padding: 0;
}

.dropdown-menu li {
    display: block;
}

.dropdown-menu a {
    display: block;
    padding: 0.55rem 0.85rem;
    color: var(--lu-ink);
    text-decoration: none;
}

.dropdown-menu a:hover {
    background: var(--lu-paper-2);
}

/* The current page is ticked in marker. */
.dropdown-menu a.active {
    box-shadow: inset 3px 0 0 var(--lu-marker);
}

/* Subpages (7.6.8 put the home page's subpages under Home). */
.dropdown-menu .dropdown-submenu,
.dropdown-menu .dropdown-subsubmenu {
    padding: 0 0 0 0.9rem;
}

.dropdown-submenu a,
.dropdown-subsubmenu a {
    font-size: 0.92rem;
    padding: 0.4rem 0.85rem;
    color: var(--lu-ink-soft);
}

/* ===================================================================
   BREADCRUMBS
   =================================================================== */

.breadcrumbs {
    padding: 0.8rem 0;
    font-size: 0.86rem;
    color: var(--lu-ink-soft);
}

.breadcrumbs a {
    color: var(--lu-mark);
    text-decoration: none;
}

.breadcrumbs a:hover {
    text-decoration: underline;
}

.breadcrumbs span {
    margin: 0 0.45rem;
}

/* ===================================================================
   HERO - the lit print. A base in a deep tint of the scheme, a cone of
   white light, the print, and two crop corners framing it. The print
   and the title are fixed colours: lamp light is white in any scheme,
   so the title never depends on the palette.
   =================================================================== */

.hero {
    position: relative;
    overflow: hidden;
    padding: clamp(3rem, 7vw, 5.5rem) 20px clamp(3.2rem, 7.5vw, 6rem);
    background:
        radial-gradient(ellipse 70% 95% at 50% 0%, color-mix(in srgb, var(--lu-base) 72%, #6f6e6a) 0%, transparent 70%),
        var(--lu-base);
}

/* The cone of light from the lamp. */
.hero:not(.hero--has-bg)::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    width: min(1180px, 160%);
    height: 100%;
    transform: translateX(-50%);
    clip-path: polygon(45% 0, 55% 0, 97% 100%, 3% 100%);
    background: linear-gradient(to bottom, rgba(255, 251, 238, 0.03), rgba(255, 251, 238, 0.14));
    pointer-events: none;
    z-index: 0;
}

/* The lit print. */
.hero .container {
    position: relative;
    z-index: 1;
    max-width: 860px;
    margin: 0 auto;
    padding: clamp(2.2rem, 5vw, 3.6rem) clamp(1.4rem, 4vw, 3rem);
    text-align: center;
    background: radial-gradient(ellipse 80% 95% at 50% 45%, var(--lu-light) 0%, #f3f1e9 70%, #e5e2d8 100%);
    box-shadow: 0 0 70px rgba(255, 246, 220, 0.16), 0 22px 40px -22px rgba(0, 0, 0, 0.7);
}

.hero h1 {
    margin: 0;
    font-family: var(--lu-serif);
    font-weight: 500;
    font-size: clamp(2.2rem, 5vw, 4rem);
    line-height: 1.08;
    letter-spacing: -0.012em;
    color: #1d1e20;
}

/* A marker stroke under the title - the scheme's mark on the print. */
.hero h1::after {
    content: "";
    display: block;
    width: min(70%, 9em);
    height: 12px;
    margin: 0.35em auto 0;
    background-color: color-mix(in srgb, var(--primary) 78%, #1d1e20);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 14' preserveAspectRatio='none'%3E%3Cpath d='M3 9C40 5 80 11 120 7S200 4 237 8' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 14' preserveAspectRatio='none'%3E%3Cpath d='M3 9C40 5 80 11 120 7S200 4 237 8' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}

/* The two crop corners, top-left and bottom-right - the pair of L-shaped
   cards used to find a crop. Slim, in a light tint of the scheme, lying
   2px onto the print. */
.hero .container::before,
.hero .container::after {
    content: "";
    position: absolute;
    inset: -6px;
    pointer-events: none;
    background-repeat: no-repeat;
    background-image:
        linear-gradient(var(--lu-corner), var(--lu-corner)),
        linear-gradient(var(--lu-corner), var(--lu-corner));
    background-size: min(34%, 190px) 8px, 8px min(62%, 124px);
    filter: drop-shadow(0 3px 3px rgba(0, 0, 0, 0.35));
}

.hero .container::before {
    background-position: 0 0, 0 0;
}

.hero .container::after {
    background-position: 100% 100%, 100% 100%;
}

/* Hero with a photo (homepage, engine owns .hero-bg-media and the tint
   on ::after). The photo IS the print: the paper goes transparent and
   the corners frame it. */
.hero.hero--has-bg {
    padding-top: clamp(5rem, 12vw, 9rem);
    padding-bottom: clamp(5rem, 12vw, 9rem);
}

.hero--has-bg .container {
    background: none;
    box-shadow: none;
}

.hero--has-bg h1 {
    color: #fff;
}

.hero--has-bg h1::after {
    background-color: color-mix(in srgb, var(--primary) 70%, #fff);
}

/* ===================================================================
   THE FRAME CLOSES - first page of a visit only (head.html sets the
   flag), and only with animations on. The corners slide in from outside
   the print, then the lamp comes on: the print and title go from dim to
   lit, the cone of light appears. On the homepage with a photo, the
   photo develops under the lamp instead.
   =================================================================== */

@keyframes lu-corner-a {
    from { transform: translate(calc(var(--lu-travel) * -1), calc(var(--lu-travel) * -1)); opacity: 0; }
    30% { opacity: 1; }
    to { transform: none; opacity: 1; }
}

@keyframes lu-corner-b {
    from { transform: translate(var(--lu-travel), var(--lu-travel)); opacity: 0; }
    30% { opacity: 1; }
    to { transform: none; opacity: 1; }
}

@keyframes lu-lamp {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes lu-expose {
    from { filter: brightness(0.32); }
    to { filter: brightness(1); }
}

html[data-lu-frame="run"] body[data-animations-enabled="true"] .hero .container::before {
    animation: lu-corner-a 1s cubic-bezier(0.2, 0.75, 0.25, 1) 0.1s backwards;
}

html[data-lu-frame="run"] body[data-animations-enabled="true"] .hero .container::after {
    animation: lu-corner-b 1s cubic-bezier(0.2, 0.75, 0.25, 1) 0.1s backwards;
}

html[data-lu-frame="run"] body[data-animations-enabled="true"] .hero:not(.hero--has-bg) .container {
    animation: lu-expose 0.45s ease-out 1s backwards;
}

html[data-lu-frame="run"] body[data-animations-enabled="true"] .hero:not(.hero--has-bg)::before {
    animation: lu-lamp 0.45s ease-out 1s backwards;
}

html[data-lu-frame="run"] body[data-animations-enabled="true"] .hero--has-bg .hero-bg-media img {
    animation: lu-develop calc(var(--lu-dev-time) * 1.4) cubic-bezier(0.35, 0.1, 0.3, 1) 0.9s backwards;
}

/* ===================================================================
   DEVELOPMENT - the main effect. A photo rises out of white paper when
   the engine marks its block as visible (.animated): shadows first,
   highlights last, as in the tray. Contrast collapses everything to
   mid-grey and a strong brightness pushes it to white; as both relax,
   the darkest tones leave white first and the highlights stay clipped
   until the end. The last keyframe is filter: none - the photo settles
   exactly as uploaded.
   =================================================================== */

@keyframes lu-develop {
    0% {
        filter: contrast(calc(1 - var(--lu-dev-s))) brightness(calc(1 + 1.2 * var(--lu-dev-s)));
    }
    40% {
        filter: contrast(calc(1 - 0.55 * var(--lu-dev-s))) brightness(calc(1 + 1.1 * var(--lu-dev-s)));
    }
    75% {
        filter: contrast(calc(1 - 0.15 * var(--lu-dev-s))) brightness(calc(1 + 0.35 * var(--lu-dev-s)));
    }
    100% {
        filter: none;
    }
}

body.js-ready[data-animations-enabled="true"] .gallery-grid.animated .gallery-item img,
body.js-ready[data-animations-enabled="true"] .page-card.animated img.page-card-image {
    animation: lu-develop var(--lu-dev-time) cubic-bezier(0.35, 0.1, 0.3, 1) backwards;
    animation-delay: calc(0.25s + var(--lu-i, 0) * 0.14s);
}

/* One mat after another along the wall. */
.gallery-item:nth-child(2) { --lu-i: 1; }
.gallery-item:nth-child(3) { --lu-i: 2; }
.gallery-item:nth-child(4) { --lu-i: 3; }
.gallery-item:nth-child(5) { --lu-i: 4; }
.gallery-item:nth-child(6) { --lu-i: 5; }
.gallery-item:nth-child(7) { --lu-i: 6; }
.gallery-item:nth-child(8) { --lu-i: 7; }
.gallery-item:nth-child(n+9) { --lu-i: 8; }

.page-card:nth-child(4n+2) { --lu-i: 1; }
.page-card:nth-child(4n+3) { --lu-i: 2; }
.page-card:nth-child(4n+4) { --lu-i: 3; }

/* ===================================================================
   SCROLL REVEAL - the engine's animation contract, all three rules.
   script.js adds .animated as blocks enter and .js-ready to <body>.
   Without the reset rule the offset is applied and never removed
   (Tarasy/Laminat/Preparat 1.0.4). opacity: 0 is safe without JS: the
   engine's <noscript> override uses !important.
   =================================================================== */

.animate-on-scroll {
    opacity: 0;
    transform: translateY(var(--animation-offset, 20px));
    transition: opacity 0.6s ease, transform 0.6s ease;
}

body.js-ready[data-animations-enabled="true"] .animate-on-scroll.animated {
    opacity: 1;
    transform: translateY(0);
}

body:not([data-animations-enabled="true"]) .animate-on-scroll {
    opacity: 1;
    transform: none;
}

/* The wall of mats lands quickly so the development is what you watch. */
.gallery-grid.animate-on-scroll {
    transition-duration: 0.35s;
}

/* ===================================================================
   THE PRINT SHEET - page content
   =================================================================== */

main > article > .container,
main > .container {
    padding-top: clamp(1.4rem, 3.5vw, 2.6rem);
}

.content-section {
    counter-reset: lu-frame;
    background: var(--lu-paper);
    padding: clamp(1.4rem, 4vw, 3rem);
    margin-bottom: clamp(1.6rem, 4vw, 2.8rem);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14), 0 18px 38px -24px rgba(0, 0, 0, 0.45);
}

html[data-theme="dark"] .content-section {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.6), 0 18px 38px -20px rgba(0, 0, 0, 0.9);
}

.content-section h2,
.content-section h3 {
    margin: 1.5em 0 0.55em;
}

.content-section h2 {
    font-size: clamp(1.75rem, 3.2vw, 2.3rem);
}

.content-section h3 {
    font-size: clamp(1.3rem, 2.3vw, 1.6rem);
}

.content-section > div > h2:first-child,
.content-section > div > h3:first-child {
    margin-top: 0.3em;
}

/* The marker stroke under a section heading. */
.content-section h2::after,
.contact-form h2::after,
.testimonials-section h2::after {
    content: "";
    display: block;
    width: min(100%, 5.5em);
    height: 10px;
    margin-top: 0.25em;
    background-color: var(--lu-marker);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 14' preserveAspectRatio='none'%3E%3Cpath d='M3 8C42 11 84 5 124 8S196 10 237 6' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 14' preserveAspectRatio='none'%3E%3Cpath d='M3 8C42 11 84 5 124 8S196 10 237 6' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}

.content-section a:not(.btn):not(.cta-button):not(.price-tag) {
    color: var(--lu-mark);
    text-decoration: underline;
    text-decoration-color: var(--lu-marker);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.2em;
}

/* Safety net: an image a module puts into the text never gets wider
   than the page. */
.content-section img {
    max-width: 100%;
    height: auto;
}

/* The text column: about 115 characters per full line (1.0.2; 1.0.0 had
   about 75, which stood as a narrow pillar on a desktop screen). Without
   it, lines on the 1440px page would run to about 150. The engine wraps
   the page text in the one child of .content-section that has neither a
   class nor an inline text-align (the price and CTA rows carry one), so
   that wrapper becomes a centred column; the galleries above and below
   it keep the whole width of the print. */
.content-section > div:not([class]):not([style*="text-align"]) {
    max-width: 86ch;
    margin-left: auto;
    margin-right: auto;
}

/* ===================================================================
   PASSE-PARTOUT - the gallery. Both .gallery-grid instances (above and
   below the text) are walls of mats. Every mat is the same square with a
   deeper bottom margin, as framers cut them; the window in it is cut to
   the photo's own shape - the image keeps its proportions inside the
   opening instead of being cropped to fit, and the bevel hugs it.
   =================================================================== */

.gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 16px;
    margin: 0 0 2rem;
}

/* A mat is a square, so it must not grow with its track: with 1-3 photos
   auto-fit (the v4.0.2 lesson - no ghost columns) makes the tracks wide,
   and a lone photo got a 1300px square of empty board. The mat stops at
   400px and sits centred in its track; the column count still comes from
   the 200px minimum. */

/* A lone photo - typically "1 above the text" - is the page's main
   picture: it gets one wide landscape mat instead of a small square. */
.gallery-item:only-child {
    max-width: 860px;
    aspect-ratio: 3 / 2;
    padding: 5.5% 7% 8.5%;
}

.gallery-item:only-child::after {
    bottom: 3.2%;
}

.gallery-item {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    max-width: 400px;
    justify-self: center;
    aspect-ratio: 1 / 1;
    padding: 11% 11% 17%;
    cursor: zoom-in;
    counter-increment: lu-frame;
    background: var(--lu-mat);
    box-shadow:
        0 0 0 1px rgba(0, 0, 0, 0.05),
        0 1px 2px rgba(0, 0, 0, 0.1),
        0 10px 22px -14px rgba(0, 0, 0, 0.45);
}

html[data-theme="dark"] .gallery-item {
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.05),
        0 1px 2px rgba(0, 0, 0, 0.6),
        0 10px 22px -12px rgba(0, 0, 0, 0.9);
}

.gallery-item > picture {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

/* The photo in its window. Both sizes stay auto and only the maximums
   are set, so the browser keeps the photo's own ratio and the box of the
   <img> IS the photo - which is why the bevel (box-shadow) can hug it. */
.gallery-grid img,
.gallery-item img {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
    background: var(--lu-window);
    box-shadow:
        0 0 0 1px var(--lu-cut),
        0 0 0 5px var(--lu-core),
        1px 1px 0 5.5px rgba(0, 0, 0, 0.08);
}

/* Catalogue number in the deeper bottom margin. Numbers only, so nothing
   to translate. The counter runs across both walls of a page, matching
   the lightbox order. */
.gallery-item::after {
    content: counter(lu-frame, decimal-leading-zero);
    position: absolute;
    left: 0;
    right: 0;
    bottom: 5.5%;
    text-align: center;
    font-family: var(--lu-sans);
    font-weight: 500;
    font-size: 11px;
    line-height: 1;
    letter-spacing: 0.16em;
    font-variant-numeric: tabular-nums;
    color: var(--lu-ink-soft);
    pointer-events: none;
}

/* Hover: four crop corners in marker close in on the mat - always in the
   mat's margin, never over the photo. */
.gallery-item::before {
    content: "";
    position: absolute;
    inset: 7px;
    z-index: 2;
    pointer-events: none;
    background:
        linear-gradient(var(--lu-marker), var(--lu-marker)) 0 0 / 18px 3px,
        linear-gradient(var(--lu-marker), var(--lu-marker)) 0 0 / 3px 18px,
        linear-gradient(var(--lu-marker), var(--lu-marker)) 100% 0 / 18px 3px,
        linear-gradient(var(--lu-marker), var(--lu-marker)) 100% 0 / 3px 18px,
        linear-gradient(var(--lu-marker), var(--lu-marker)) 0 100% / 18px 3px,
        linear-gradient(var(--lu-marker), var(--lu-marker)) 0 100% / 3px 18px,
        linear-gradient(var(--lu-marker), var(--lu-marker)) 100% 100% / 18px 3px,
        linear-gradient(var(--lu-marker), var(--lu-marker)) 100% 100% / 3px 18px;
    background-repeat: no-repeat;
    opacity: 0;
    transform: scale(1.07);
    transition: opacity 0.2s ease, transform 0.25s ease;
}

.gallery-item:hover::before {
    opacity: 1;
    transform: none;
}

/* The loupe (created by head.html, mouse only). A chrome ring round a
   magnified view of the ~1920px file the lightbox also uses; round the
   photo it shows the mat, as a real loupe would. */
.lu-loupe {
    position: fixed;
    left: 0;
    top: 0;
    z-index: 1500;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.15s ease;
    background-color: var(--lu-mat);
    background-repeat: no-repeat;
    box-shadow:
        inset 0 0 0 1px rgba(0, 0, 0, 0.45),
        inset 0 0 18px rgba(0, 0, 0, 0.25),
        0 0 0 4px #ecebe7,
        0 0 0 5px #8f8d88,
        0 0 0 8px #cfcdc8,
        0 0 0 9px #6f6d68,
        0 16px 34px rgba(0, 0, 0, 0.45);
}

.lu-loupe.is-on {
    opacity: 1;
}

/* ===================================================================
   PRINTS - page cards lie on the table with a white border.
   =================================================================== */

.onepage-sections,
.subpages-sections {
    padding: clamp(1.6rem, 4vw, 3rem) 0;
}

.page-cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: clamp(1.4rem, 3vw, 2.2rem);
}

.page-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--lu-paper);
    padding: 12px 12px 1.3rem;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14), 0 14px 28px -18px rgba(0, 0, 0, 0.5);
    transition: box-shadow 0.25s ease;
}

.page-card:hover {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.16), 0 20px 36px -18px rgba(0, 0, 0, 0.6);
}

html[data-theme="dark"] .page-card {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.6), 0 14px 28px -16px rgba(0, 0, 0, 0.9);
}

.page-card > picture {
    display: block;
}

/* The engine puts .page-card-image straight on the <img> (and on the
   placeholder <div>) - so it is sized here, on the image itself. */
.page-card-image {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    object-position: center;
    margin: 0 0 1rem;
    background: var(--lu-paper-2);
}

.page-card-content {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: 0 0.35rem;
}

.page-card-title {
    font-family: var(--lu-serif);
    font-weight: 500;
    font-size: 1.42rem;
    line-height: 1.15;
    margin: 0 0 0.5rem;
    color: var(--lu-ink);
}

.page-card-excerpt {
    margin: 0 0 1rem;
    font-size: 0.97rem;
    color: var(--lu-ink-soft);
}

.page-card-link {
    align-self: flex-start;
    margin-top: auto;
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--lu-mark);
    text-decoration: underline;
    text-decoration-color: var(--lu-marker);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.25em;
}

.page-card-link:hover {
    text-decoration-thickness: 3px;
}

/* ===================================================================
   PLACEHOLDERS - pages without a photo get studio objects instead of the
   engine's emoji, none of them carrying text. Three compositions on
   3n+1 / 3n+2 / 3n+3, mutually exclusive by construction; the base rule
   sets only what all three share, so nothing leaks between them.
   =================================================================== */

.page-card-placeholder {
    position: relative;
    overflow: hidden;
    font-size: 0;
    line-height: 0;
    background-color: var(--lu-paper-2);
}

.page-card-placeholder span {
    display: none;
}

.page-card-placeholder::before,
.page-card-placeholder::after {
    content: "";
    position: absolute;
    pointer-events: none;
}

/* 1 - the palette card: six tints of the scheme, the pure colour circled
   in marker and a marker stroke beneath. */
.page-card:nth-child(3n+1) .page-card-placeholder {
    background-color: #f7f6f2;
    background-image:
        repeating-linear-gradient(90deg, transparent 0 calc(16.666% - 3px), #f7f6f2 calc(16.666% - 3px) 16.666%),
        linear-gradient(90deg,
            color-mix(in srgb, var(--primary) 14%, #fff) 0 16.666%,
            color-mix(in srgb, var(--primary) 34%, #fff) 16.666% 33.333%,
            color-mix(in srgb, var(--primary) 60%, #fff) 33.333% 50%,
            var(--primary) 50% 66.666%,
            color-mix(in srgb, var(--primary) 70%, #000) 66.666% 83.333%,
            color-mix(in srgb, var(--primary) 42%, #000) 83.333% 100%);
    background-size: calc(88% + 3px) 56%, 88% 56%;
    background-position: 6% 30%, 6% 30%;
    background-repeat: no-repeat;
}

.page-card:nth-child(3n+1) .page-card-placeholder::before {
    left: calc(50% - 8px);
    width: calc(14.667% + 13px);
    top: 7%;
    bottom: 30%;
    border: 3px solid var(--lu-marker);
    border-radius: 50%;
    transform: rotate(-5deg);
}

.page-card:nth-child(3n+1) .page-card-placeholder::after {
    left: 30%;
    right: 30%;
    bottom: 11%;
    height: 10px;
    background-color: var(--lu-marker);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 14' preserveAspectRatio='none'%3E%3Cpath d='M3 8C42 11 84 5 124 8S196 10 237 6' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 14' preserveAspectRatio='none'%3E%3Cpath d='M3 8C42 11 84 5 124 8S196 10 237 6' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}

/* 2 - an empty mat waiting for its photo: photo corners in the window
   and the universal picture sign in marker. */
.page-card:nth-child(3n+2) .page-card-placeholder {
    background-color: var(--lu-mat);
}

.page-card:nth-child(3n+2) .page-card-placeholder::before {
    top: 15%;
    bottom: 23%;
    left: 23%;
    right: 23%;
    background:
        linear-gradient(135deg, #3a3b3f 0 50%, transparent 50%) 0 0 / 16px 16px no-repeat,
        linear-gradient(225deg, #3a3b3f 0 50%, transparent 50%) 100% 0 / 16px 16px no-repeat,
        linear-gradient(45deg, #3a3b3f 0 50%, transparent 50%) 0 100% / 16px 16px no-repeat,
        linear-gradient(315deg, #3a3b3f 0 50%, transparent 50%) 100% 100% / 16px 16px no-repeat,
        var(--lu-window);
    box-shadow: 0 0 0 1px var(--lu-cut), 0 0 0 5px var(--lu-core);
}

.page-card:nth-child(3n+2) .page-card-placeholder::after {
    left: 50%;
    top: 46%;
    width: 30%;
    aspect-ratio: 5 / 3;
    transform: translate(-50%, -50%);
    background-color: var(--lu-marker);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 30'%3E%3Ccircle cx='38' cy='8' r='4.5'/%3E%3Cpath d='M0 30L16 10L24 20L30 13L50 30Z'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 30'%3E%3Ccircle cx='38' cy='8' r='4.5'/%3E%3Cpath d='M0 30L16 10L24 20L30 13L50 30Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* 3 - a layout proof on a trimmed sheet: a headline block in marker,
   grey lines of text, and crop marks at the four corners. */
.page-card:nth-child(3n+3) .page-card-placeholder {
    background-color: var(--lu-paper-2);
}

.page-card:nth-child(3n+3) .page-card-placeholder::before {
    top: 18%;
    bottom: 18%;
    left: 24%;
    right: 24%;
    background:
        linear-gradient(var(--lu-marker), var(--lu-marker)) 14% 20% / 52% 12% no-repeat,
        linear-gradient(#c9c7c0, #c9c7c0) 14% 50% / 72% 5% no-repeat,
        linear-gradient(#c9c7c0, #c9c7c0) 14% 64% / 72% 5% no-repeat,
        linear-gradient(#c9c7c0, #c9c7c0) 14% 78% / 44% 5% no-repeat,
        #fdfdfb;
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.18);
}

.page-card:nth-child(3n+3) .page-card-placeholder::after {
    top: calc(18% - 14px);
    bottom: calc(18% - 14px);
    left: calc(24% - 14px);
    right: calc(24% - 14px);
    background:
        linear-gradient(var(--lu-ink-soft), var(--lu-ink-soft)) left 0 top 13px / 10px 1.5px,
        linear-gradient(var(--lu-ink-soft), var(--lu-ink-soft)) left 13px top 0 / 1.5px 10px,
        linear-gradient(var(--lu-ink-soft), var(--lu-ink-soft)) right 0 top 13px / 10px 1.5px,
        linear-gradient(var(--lu-ink-soft), var(--lu-ink-soft)) right 13px top 0 / 1.5px 10px,
        linear-gradient(var(--lu-ink-soft), var(--lu-ink-soft)) left 0 bottom 13px / 10px 1.5px,
        linear-gradient(var(--lu-ink-soft), var(--lu-ink-soft)) left 13px bottom 0 / 1.5px 10px,
        linear-gradient(var(--lu-ink-soft), var(--lu-ink-soft)) right 0 bottom 13px / 10px 1.5px,
        linear-gradient(var(--lu-ink-soft), var(--lu-ink-soft)) right 13px bottom 0 / 1.5px 10px;
    background-repeat: no-repeat;
}

/* ===================================================================
   BUTTONS, PRICE
   =================================================================== */

.btn,
.cta-button,
button[type="submit"],
input[type="submit"] {
    display: inline-block;
    font-family: var(--lu-sans);
    font-weight: 600;
    font-size: 0.98rem;
    line-height: 1.2;
    padding: 0.85rem 1.6rem;
    border: 0;
    border-radius: 2px;
    color: var(--lu-on-mark);
    background: var(--lu-mark);
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.btn:hover,
.cta-button:hover,
button[type="submit"]:hover,
input[type="submit"]:hover {
    background: var(--lu-ink);
    color: var(--lu-paper);
}

.price-tag {
    display: inline-block;
    font-family: var(--lu-sans);
    font-weight: 600;
    font-size: 1.05rem;
    font-variant-numeric: tabular-nums;
    padding: 0.5rem 1rem;
    color: var(--lu-ink);
    background: var(--lu-paper);
    border: 1.5px solid var(--lu-ink);
    box-shadow: 4px 4px 0 var(--lu-marker);
    text-decoration: none;
}

a.price-tag:hover {
    box-shadow: 2px 2px 0 var(--lu-marker);
}

/* ===================================================================
   TESTIMONIALS - notes on the back of prints
   =================================================================== */

.testimonials-section {
    padding: clamp(2rem, 5vw, 3.5rem) 0;
}

/* The engine writes color: var(--primary) inline on this heading; raw
   scheme colour must never carry text in this theme (pale schemes fall
   far below 3:1), so this is the one justified !important. */
.testimonials-section h2 {
    font-family: var(--lu-serif);
    font-weight: 500;
    font-size: clamp(1.75rem, 3.2vw, 2.3rem);
    color: var(--lu-ink) !important;
}

.testimonials-section h2::after {
    margin-left: auto;
    margin-right: auto;
}

.testimonials-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: clamp(1.2rem, 3vw, 2rem);
    margin-top: 1.5rem;
}

.testimonial-card {
    background: var(--lu-paper);
    color: var(--lu-ink);
    padding: 1.5rem 1.5rem 1.3rem;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14), 0 12px 24px -18px rgba(0, 0, 0, 0.5);
}

.testimonial-rating {
    margin: 0 0 0.5rem;
    letter-spacing: 0.12em;
    color: var(--lu-mark);
}

.testimonial-text {
    margin: 0 0 0.9rem;
    font-family: var(--lu-serif);
    font-style: italic;
    font-size: 1.18rem;
    line-height: 1.45;
}

.testimonial-author {
    margin: 0;
    font-weight: 600;
    font-size: 0.92rem;
    color: var(--lu-ink-soft);
}

/* ===================================================================
   CONTACT FORM - an order slip
   =================================================================== */

.contact-form {
    max-width: 760px;
    margin: clamp(1.6rem, 4vw, 2.8rem) auto;
    padding: clamp(1.4rem, 4vw, 2.6rem);
    background: var(--lu-paper);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14), 0 18px 38px -24px rgba(0, 0, 0, 0.45);
}

.content-section .contact-form {
    box-shadow: none;
    padding-left: 0;
    padding-right: 0;
}

.contact-form h2 {
    margin: 0 0 1.2rem;
    font-size: clamp(1.75rem, 3.2vw, 2.3rem);
}

.form-group {
    margin-bottom: 1.1rem;
}

.contact-form label {
    display: block;
    margin-bottom: 0.3rem;
    font-size: 0.86rem;
    font-weight: 500;
    color: var(--lu-ink-soft);
}

.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form input[type="tel"],
.contact-form input[type="number"],
.contact-form textarea,
.contact-form select {
    width: 100%;
    font: inherit;
    color: var(--lu-ink);
    background: transparent;
    border: 0;
    border-bottom: 1.5px solid var(--lu-rule);
    border-radius: 0;
    padding: 0.55rem 0.1rem;
}

.contact-form textarea {
    min-height: 130px;
    resize: vertical;
    border: 1.5px solid var(--lu-rule);
    padding: 0.6rem 0.7rem;
}

.contact-form input:focus,
.contact-form textarea:focus,
.contact-form select:focus {
    border-color: var(--lu-marker);
}

.success {
    padding: 0.7rem 0.9rem;
    margin-bottom: 1rem;
    font-weight: 500;
    color: #1d5d34;
    background: #e5f1e8;
}

.error {
    padding: 0.7rem 0.9rem;
    margin-bottom: 1rem;
    font-weight: 500;
    color: #8e1f14;
    background: #f7e3df;
}

html[data-theme="dark"] .success {
    color: #bfe7c8;
    background: #17301f;
}

html[data-theme="dark"] .error {
    color: #ffc9bf;
    background: #3b1511;
}

/* ===================================================================
   FOOTER - the bevel of the mat runs along its top edge, and the
   panel's footer colour is taken halfway to black.
   Why (Fotolab): with the footer colour on "auto" the engine uses
   --secondary, and on the pale schemes white text on it measured as low
   as 1.61:1 (ice) - 16 of 48 schemes failed. Mixed 50% toward #121110
   the worst of all 48 is 5.06:1. Footer colours picked in the panel keep
   their hue, one step deeper.
   =================================================================== */

footer {
    position: relative;
    margin-top: clamp(3rem, 6vw, 4.5rem);
    padding: 3rem 0 2rem;
    background: color-mix(in srgb, var(--footer-bg, var(--secondary)) 50%, #121110);
    color: #fff;
}

footer::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -7px;
    height: 7px;
    pointer-events: none;
    background: linear-gradient(to bottom,
        rgba(0, 0, 0, 0.12) 0 1px,
        var(--lu-core) 1px 6px,
        rgba(0, 0, 0, 0.35) 6px 7px);
}

footer h3,
footer h4 {
    color: #fff;
}

footer a {
    color: #fff;
    text-decoration: underline;
    text-underline-offset: 0.18em;
}

.footer-content {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: clamp(1.4rem, 4vw, 3rem);
}

.footer-section h3,
.footer-section h4 {
    margin: 0 0 0.7rem;
    font-size: 1.3rem;
}

.footer-section p,
.footer-section li {
    margin: 0 0 0.45rem;
}

.footer-menu {
    list-style: none;
    margin: 0;
    padding: 0;
}

.footer-menu-text {
    opacity: 0.9;
}

.social-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin: 0.2rem 0 0 -10px;
}

.social-links a {
    color: #fff;
}

.copyright {
    margin-top: 1.8rem;
    padding-top: 1.1rem;
    border-top: 1px solid rgba(255, 255, 255, 0.25);
    font-size: 0.88rem;
    opacity: 0.92;
}

/* ===================================================================
   DARK-MODE CONTROL - fixed bottom right, fleet convention. Drawn as the
   studio lamp: by day its glass is dim, switched on it glows in the
   scheme colour - which is exactly what dark mode is here.
   =================================================================== */

.dark-mode-toggle {
    position: fixed;
    bottom: 20px;
    right: 20px;
    z-index: 1000;
    width: 50px;
    height: 50px;
    padding: 0;
    font-size: 0;
    line-height: 0;
    cursor: pointer;
    border: 1px solid var(--lu-rule);
    border-radius: 50%;
    background: var(--lu-paper);
    box-shadow: 0 8px 18px -8px rgba(0, 0, 0, 0.5);
}

/* lamp shade */
.dark-mode-toggle::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 24px;
    height: 19px;
    transform: translate(-50%, -58%);
    border-radius: 12px 12px 3px 3px;
    background: #3a3b3e;
}

/* glass */
.dark-mode-toggle::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 15px;
    height: 10px;
    transform: translate(-50%, -38%);
    border-radius: 8px 8px 2px 2px;
    background: color-mix(in srgb, var(--primary) 38%, #2c2d30);
    transition: background-color 0.3s ease, box-shadow 0.3s ease;
}

.dark-mode-toggle:hover::after {
    background: color-mix(in srgb, var(--primary) 60%, #2c2d30);
}

html[data-theme="dark"] .dark-mode-toggle {
    background: #1a1b1d;
    border-color: #3d3f44;
}

html[data-theme="dark"] .dark-mode-toggle::after {
    background: color-mix(in srgb, var(--primary) 55%, #fff);
    box-shadow:
        0 0 10px 3px color-mix(in srgb, color-mix(in srgb, var(--primary) 75%, #fff) 75%, transparent),
        0 0 24px 8px color-mix(in srgb, color-mix(in srgb, var(--primary) 75%, #fff) 30%, transparent);
}

/* ===================================================================
   LIGHTBOX - the viewing table: neutral black, no scheme colour near the
   photo. Hidden until .active, fixed above everything (the engine emits
   it at the end of <body> on every page with a gallery).
   =================================================================== */

.lightbox {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    height: 100dvh;
    z-index: 2000;
    background: rgba(10, 10, 10, 0.96);
    flex-direction: column;
    justify-content: center;
    align-items: center;
    cursor: pointer;
}

.lightbox.active {
    display: flex;
}

.lightbox img {
    max-width: 92%;
    max-height: 82vh;
    max-height: 82dvh;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08);
    cursor: default;
}

.lightbox-close {
    position: absolute;
    top: 16px;
    right: 20px;
    font-size: 2.2rem;
    line-height: 1;
    color: #e8e5de;
    background: none;
    border: 0;
    cursor: pointer;
}

.lightbox-counter {
    margin-top: 1rem;
    font-family: var(--lu-sans);
    font-size: 0.9rem;
    letter-spacing: 0.12em;
    font-variant-numeric: tabular-nums;
    color: #bdb7ab;
}

.lightbox-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    font-size: 2.2rem;
    line-height: 1;
    padding: 0.7rem 1rem;
    color: #e8e5de;
    background: rgba(255, 255, 255, 0.08);
    border: 0;
    border-radius: 2px;
    cursor: pointer;
}

.lightbox-nav:hover {
    background: rgba(255, 255, 255, 0.18);
}

.lightbox-prev {
    left: 20px;
}

.lightbox-next {
    right: 20px;
}

/* ===================================================================
   FOCUS - five selectors, fleet convention
   =================================================================== */

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
    outline: 3px solid var(--lu-marker);
    outline-offset: 2px;
}

/* ===================================================================
   NARROW SCREENS
   =================================================================== */

@media (max-width: 720px) {
    .logo-container img {
        height: 56px;
    }

    .site-title {
        font-size: 1.3rem;
    }

    .gallery-grid {
        grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
        gap: 10px;
    }

    .gallery-grid img,
    .gallery-item img {
        box-shadow:
            0 0 0 1px var(--lu-cut),
            0 0 0 4px var(--lu-core),
            1px 1px 0 4.5px rgba(0, 0, 0, 0.08);
    }

    .gallery-item::after {
        font-size: 9.5px;
    }

    .gallery-item::before {
        inset: 5px;
    }

    .hero .container::before,
    .hero .container::after {
        inset: -5px;
        background-size: min(34%, 120px) 6px, 6px min(62%, 90px);
    }

    .lu-loupe {
        display: none;
    }
}

/* ===================================================================
   REDUCED MOTION - no development, no closing frame, no reveal offset.
   =================================================================== */

@media (prefers-reduced-motion: reduce) {
    .animate-on-scroll,
    body.js-ready[data-animations-enabled="true"] .animate-on-scroll.animated {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .gallery-item img,
    .page-card-image,
    .hero .container,
    .hero .container::before,
    .hero .container::after,
    .hero::before,
    .hero-bg-media img {
        animation: none !important;
    }
}

/* ===================================================================
   PRINT - white paper, plain type; photos exactly as they are.
   =================================================================== */

@media print {
    body {
        background: #fff;
        color: #000;
    }

    body::before,
    .dark-mode-toggle,
    .hamburger-menu,
    .lu-loupe,
    .hero::before,
    .hero .container::before,
    .hero .container::after,
    .hero h1::after,
    footer::before,
    .gallery-item::before,
    .page-card-placeholder {
        display: none !important;
    }

    .animate-on-scroll {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }

    img {
        animation: none !important;
        filter: none !important;
    }

    header,
    footer,
    .hero,
    .hero .container,
    .content-section,
    .page-card,
    .testimonial-card,
    .contact-form {
        background: none !important;
        color: #000 !important;
        box-shadow: none !important;
    }

    .hero h1,
    footer a,
    footer h3 {
        color: #000 !important;
    }

    .gallery-grid {
        gap: 8px;
    }

    .gallery-item {
        background: none;
        box-shadow: none;
        border: 1px solid #bbb;
        break-inside: avoid;
    }

    .gallery-item::after {
        color: #555;
    }

    .page-card,
    .content-section {
        break-inside: avoid;
        border: 1px solid #999;
    }
}
