/* ==========================================================================
    VFW Theme: GALLERY EDITORIAL
    --------------------------------------------------------------------------
    A reusable "digital art monograph" theme for VFW projects — warm ivory
    ground, near-black text, deep teal as the principal accent, an elegant
    editorial serif for titles and a neutral sans for every interface element.
    Built for artist portfolios and gallery presentations where the imagery must
    outrank the interface (first consumer: Daniel Casique, painter).

    Three parts, mirroring the `classic-poster` and `blender` themes:

    1. FONTS — self-hosted faces (EB Garamond for the editorial titles, Inter
       for navigation, metadata and forms). No CDN; the .woff2 files live in
       ./fonts/ and are covered by the SIL Open Font License.

    2. THEME TOKENS — `.vfw-theme-gallery-editorial` defines a private
       `--gallery-editorial-*` vocabulary (palette, type scale, rhythm) and maps
       it onto the semantic `--vfw-color-*` layer, so every stock VFW widget
       re-skins automatically. The palette is PRESET-SWAPPABLE: decorative rules
       read `--gallery-editorial-accent` / `--gallery-editorial-ink`, never a
       literal hue, so a future preset overrides just those values in a separate
       file — exactly how the blender presets override their own vocabulary.

    3. COMPONENT KIT — `vfw-gallery-*` classes reproducing the monograph
       LANGUAGE: the quiet header, the split hero, the edge-to-edge immersion
       band, the artwork grid, the featured-work panel, the collector aside, the
       exhibition row, the studio-notes band and the teal footer.

    Restraint is the point. There are no shadows, no gradients on content, no
    decorative icons and no motion longer than 300ms. If an element competes
    with a painting for attention, it is wrong.

    Class naming: single-dash kebab, `vfw-gallery-` prefix, modifiers as full
    words (`vfw-gallery-button-solid`, not `--solid`). No `__`, no column
    alignment, no abbreviated identifiers.

    Usage: load core/reset.css, then core/tokens.css, then this file, then add
    `vfw-theme-gallery-editorial` to <html>. core/reset.css is a HARD
    PREREQUISITE, not a convenience: it owns the element-level defaults this
    file deliberately does not restate.

    NO BARE ELEMENT SELECTORS. This file styles classes; the core reset owns
    element defaults. The reason is not tidiness — it is a bug this theme
    already shipped. A `.vfw-theme-gallery-editorial a { color: inherit }` rule
    lived here, a byte-for-byte duplicate of core/reset.css. The reset sits at
    specificity (0,0,1), where any class rule beats it; the copy sat at (0,1,1),
    where it beat every button class instead. Every call-to-action rendered as
    an <a> silently inherited ink on the teal ground — 1.55:1, below even the
    large-text floor — while the same class on a <button> rendered correctly.
    It was deleted, not scoped: scoping repairs one class and leaves the trap
    armed for the next one. Do not re-add it as a "missing" reset.
   ========================================================================== */

/* ==========================================================================
    1. FONTS (self-hosted — see ./fonts/)
   ========================================================================== */

@font-face {
    font-family: 'Gallery Editorial Serif';
    src: url('fonts/ebgaramond-400.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Gallery Editorial Serif';
    src: url('fonts/ebgaramond-600.woff2') format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Gallery Editorial Sans';
    src: url('fonts/inter-400.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Gallery Editorial Sans';
    src: url('fonts/inter-600.woff2') format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

/* ==========================================================================
    2. THEME TOKENS
   ========================================================================== */

.vfw-theme-gallery-editorial {
    /* Palette — warm ivory ground, near-black ink, deep teal principal accent,
       cobalt secondary, restrained ochre detail, ember used very sparingly.

       Three tokens are DERIVED rather than decorative, and each exists because
       its base fails a contrast floor somewhere: `ochre-text` and `ember-text`
       are the legible tones of colours that are safe only as decoration, and
       `focus` is the ring colour, re-bound per ground (see below). */
    --gallery-editorial-ivory: #f4efe6;
    --gallery-editorial-ivory-deep: #ebe4d8;
    --gallery-editorial-paper: #fbf8f3;
    --gallery-editorial-ink: #1c1b19;
    --gallery-editorial-ink-soft: #4a4640;
    /* 4.97:1 on ivory, 4.50:1 on ivory-deep — this carries all card metadata and
       form labels at small sizes, so it must clear AA on BOTH grounds. The former
       #8a837a measured 3.27:1 / 2.96:1 and failed. */
    --gallery-editorial-ink-faint: #6b665f;
    --gallery-editorial-accent: #12414c;
    --gallery-editorial-accent-hover: #0c2f37;
    --gallery-editorial-secondary: #1e3f8f;
    /* The focus ring is a TOKEN, not a fixed colour, because this theme paints
       two grounds. Cobalt reads well on the ivory page (8.48:1) and vanishes on
       the teal bands and the lightbox scrim (1.15:1 and 1.79:1) — where every
       interactive element a keyboard user reaches happens to live. Each dark
       ground re-binds this to paper rather than overriding the outline rule, so
       the indicator follows the ground automatically and a new dark surface
       inherits the fix by setting one property. */
    --gallery-editorial-focus: var(--gallery-editorial-secondary);
    /* Two ochres on purpose: the bright one is decorative only (rules, underlines),
       where contrast minimums do not apply. Anything that carries MEANING as text —
       the availability status above all — uses the darker one, which is 5.27:1 on
       ivory. The bright #b8862f is 2.83:1 and must never be used for text. */
    --gallery-editorial-ochre: #b8862f;
    --gallery-editorial-ochre-text: #7d5e12;
    /* Ember follows the same split as ochre above, and for the same reason. The
       bright #c2432a is 4.44:1 on ivory — it reads as "error" but lands just under
       the 4.5:1 floor, on the one string a reader most needs: why their submission
       was refused. Decorative ember (borders, backgrounds) may use it; ember-text
       is 5.71:1 on ivory and 5.18:1 on ivory-deep, and is what error TEXT uses. */
    --gallery-editorial-ember: #c2432a;
    --gallery-editorial-ember-text: #a63823;
    --gallery-editorial-rule: #d8cfc0;
    --gallery-editorial-rule-strong: #bdb2a0;

    /* Type */
    --gallery-editorial-font-display: 'Gallery Editorial Serif', Georgia, 'Times New Roman', serif;
    --gallery-editorial-font-interface: 'Gallery Editorial Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --gallery-editorial-label-tracking: 0.16em;
    --gallery-editorial-title-tracking: -0.015em;

    /* Rhythm */
    --gallery-editorial-gap: 1.5rem;
    --gallery-editorial-gap-large: 2.5rem;
    --gallery-editorial-section-space: 5.5rem;
    --gallery-editorial-shell-max: 1180px;
    --gallery-editorial-shell-padding: 2rem;

    /* Motion — subtle only, never delaying access to the artwork. */
    --gallery-editorial-transition: 220ms ease;
    /* How long one hero painting takes to dissolve into the next. At the
       theme's 300ms ceiling: long enough to read as intent rather than as a
       failed load, short enough that nothing is ever waited on. */
    --gallery-editorial-hero-fade: 300ms;

    /* Where the hero crop holds when the painting's proportions differ from the
       panel. `center 28%` was tuned to one specific canvas and does not belong
       baked into a reusable theme; a consumer overrides this per hero image. */
    --gallery-editorial-hero-focus: center;
    /* Panel proportions. `auto` lets the image size the panel, which is right
       for a hero that never changes. A consumer that SWAPS the hero image must
       pin this to one ratio: otherwise the panel takes each painting's own
       proportions and the whole page reflows on every swap. */
    --gallery-editorial-hero-ratio: auto;
    /* Portrait treatment. The first consumer immediately had to undo a forced
       grayscale, so it is a token rather than a hardcoded filter. */
    --gallery-editorial-portrait-filter: none;

    /* --- Map onto the semantic VFW layer so stock widgets re-skin --- */
    --vfw-color-background: var(--gallery-editorial-ivory);
    --vfw-color-surface: var(--gallery-editorial-paper);
    --vfw-color-border: var(--gallery-editorial-rule);
    --vfw-color-text: var(--gallery-editorial-ink);
    --vfw-color-text-muted: var(--gallery-editorial-ink-soft);
    --vfw-color-text-on-primary: var(--gallery-editorial-paper);
    --vfw-color-primary: var(--gallery-editorial-accent);
    --vfw-color-primary-hover: var(--gallery-editorial-accent-hover);
    --vfw-color-primary-focus: var(--gallery-editorial-secondary);
    --vfw-color-primary-light: var(--gallery-editorial-ivory-deep);

    --vfw-color-success: var(--gallery-editorial-accent);
    --vfw-color-success-text: var(--gallery-editorial-accent);
    --vfw-color-success-bg: var(--gallery-editorial-ivory-deep);
    --vfw-color-success-border: var(--gallery-editorial-accent);
    --vfw-color-success-contrast: var(--gallery-editorial-paper);

    --vfw-color-warning: var(--gallery-editorial-ochre);
    --vfw-color-warning-text: var(--gallery-editorial-ochre);
    --vfw-color-warning-bg: var(--gallery-editorial-ivory-deep);
    --vfw-color-warning-border: var(--gallery-editorial-ochre);
    --vfw-color-warning-contrast: var(--gallery-editorial-ink);

    --vfw-color-error: var(--gallery-editorial-ember);
    --vfw-color-error-text: var(--gallery-editorial-ember-text);
    --vfw-color-error-bg: var(--gallery-editorial-ivory-deep);
    --vfw-color-error-border: var(--gallery-editorial-ember);
    --vfw-color-error-contrast: var(--gallery-editorial-paper);

    --vfw-color-info: var(--gallery-editorial-secondary);
    --vfw-color-info-text: var(--gallery-editorial-secondary);
    --vfw-color-info-bg: var(--gallery-editorial-ivory-deep);
    --vfw-color-info-border: var(--gallery-editorial-secondary);
    --vfw-color-info-contrast: var(--gallery-editorial-paper);

    --vfw-font-family: var(--gallery-editorial-font-interface);
    --vfw-border-radius: 0;
    --vfw-container-max: var(--gallery-editorial-shell-max);
    --vfw-container-padding: var(--gallery-editorial-shell-padding);
    --vfw-navbar-bg: var(--gallery-editorial-ivory);

    background-color: var(--gallery-editorial-ivory);
    color: var(--gallery-editorial-ink);
    font-family: var(--gallery-editorial-font-interface);
}

/* ==========================================================================
    3. BASE TYPOGRAPHY
   ========================================================================== */

/* Column flex so a short page (an exhibitions list with one entry, a legal
   notice, the 404) still pushes the footer to the bottom of the viewport
   instead of stranding it mid-screen above a band of bare ivory. `main`
   takes the slack — see .vfw-gallery-main. */
.vfw-theme-gallery-editorial body {
    background-color: var(--gallery-editorial-ivory);
    color: var(--gallery-editorial-ink);
    font-family: var(--gallery-editorial-font-interface);
    font-size: 1rem;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.vfw-gallery-main {
    flex: 1;
}

.vfw-theme-gallery-editorial h1,
.vfw-theme-gallery-editorial h2,
.vfw-theme-gallery-editorial h3,
.vfw-theme-gallery-editorial h4 {
    font-family: var(--gallery-editorial-font-display);
    font-weight: 400;
    letter-spacing: var(--gallery-editorial-title-tracking);
    line-height: 1.1;
    color: var(--gallery-editorial-ink);
}

.vfw-theme-gallery-editorial :focus-visible {
    outline: 2px solid var(--gallery-editorial-focus);
    outline-offset: 3px;
}

/* Display title — the artist name, the artwork title, the page heading. */
.vfw-gallery-display {
    font-family: var(--gallery-editorial-font-display);
    font-size: clamp(2.75rem, 7vw, 5.25rem);
    font-weight: 400;
    line-height: 0.98;
    letter-spacing: var(--gallery-editorial-title-tracking);
    margin: 0;
}

.vfw-gallery-title {
    font-family: var(--gallery-editorial-font-display);
    font-size: clamp(1.75rem, 3.4vw, 2.6rem);
    font-weight: 400;
    line-height: 1.12;
    margin: 0;
}

.vfw-gallery-subtitle {
    font-family: var(--gallery-editorial-font-display);
    font-size: clamp(1.15rem, 1.9vw, 1.45rem);
    font-weight: 400;
    line-height: 1.35;
    color: var(--gallery-editorial-ink-soft);
    margin: 0;
}

/* The small tracked-out uppercase label that opens every section. */
.vfw-gallery-label {
    font-family: var(--gallery-editorial-font-interface);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    text-transform: uppercase;
    color: var(--gallery-editorial-accent);
    margin: 0;
}

/* A section label is a real heading for outline purposes, so it is marked up as
   h2 — but it must keep the interface face, not the editorial serif that the
   h1-h4 rule applies. Only the face properties are overridden here: scoping the
   whole .vfw-gallery-label rule would also raise its `margin: 0` above the gap
   utilities and collapse the spacing above every section.
   NOTE its specificity is (0,2,1). Any rule that recolors a label FOR A CONTEXT
   (see the studio-notes band) must therefore be (0,3,0) or higher, or the label
   silently takes the accent colour here — which on the notes band is also the
   background. */
.vfw-theme-gallery-editorial h2.vfw-gallery-label,
.vfw-theme-gallery-editorial h3.vfw-gallery-label {
    font-family: var(--gallery-editorial-font-interface);
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    line-height: 1.65;
    color: var(--gallery-editorial-accent);
}

.vfw-theme-gallery-editorial h2.vfw-gallery-label-muted,
.vfw-theme-gallery-editorial h3.vfw-gallery-label-muted {
    color: var(--gallery-editorial-ink-faint);
}

.vfw-gallery-label-muted {
    color: var(--gallery-editorial-ink-faint);
}

.vfw-gallery-prose {
    font-size: 0.95rem;
    line-height: 1.75;
    color: var(--gallery-editorial-ink-soft);
    max-width: 62ch;
}

/* core/reset.css zeroes every margin, so consecutive paragraphs would otherwise
   run together as one undifferentiated block — which is exactly how the three
   biography paragraphs on /about read before this rule. Spacing is applied
   between siblings only, so a single paragraph keeps its flush top edge. */
.vfw-gallery-prose + .vfw-gallery-prose,
.vfw-gallery-prose-serif + .vfw-gallery-prose-serif {
    margin-top: 1rem;
}

.vfw-gallery-prose-serif {
    font-family: var(--gallery-editorial-font-display);
    font-size: 1.1rem;
    line-height: 1.7;
    color: var(--gallery-editorial-ink);
    max-width: 60ch;
}

.vfw-gallery-quote {
    font-family: var(--gallery-editorial-font-display);
    font-size: clamp(1.4rem, 2.8vw, 2.1rem);
    line-height: 1.4;
    color: var(--gallery-editorial-ink);
    max-width: 26ch;
    margin: 0 auto;
    text-align: center;
}

/* The short ochre rule that sits under a label or above a paragraph. */
.vfw-gallery-rule {
    width: 3rem;
    height: 2px;
    background-color: var(--gallery-editorial-ochre);
    border: 0;
    margin: 1.25rem 0;
}

.vfw-gallery-rule-full {
    width: 100%;
    height: 1px;
    background-color: var(--gallery-editorial-rule);
    border: 0;
    margin: 0;
}

/* ==========================================================================
    4. LAYOUT SHELL
   ========================================================================== */

.vfw-gallery-shell {
    width: 100%;
    max-width: var(--gallery-editorial-shell-max);
    margin: 0 auto;
    padding-left: var(--gallery-editorial-shell-padding);
    padding-right: var(--gallery-editorial-shell-padding);
}

.vfw-gallery-shell-wide {
    max-width: 1440px;
}

.vfw-gallery-section {
    padding-top: var(--gallery-editorial-section-space);
    padding-bottom: var(--gallery-editorial-section-space);
}

.vfw-gallery-section-tight {
    padding-top: 3rem;
    padding-bottom: 3rem;
}

.vfw-gallery-section-divided {
    border-top: 1px solid var(--gallery-editorial-rule);
}

.vfw-gallery-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gallery-editorial-gap);
    margin-bottom: 2rem;
}

/* ==========================================================================
    5. HEADER
   ========================================================================== */

.vfw-gallery-header {
    position: sticky;
    top: 0;
    z-index: 40;
    background-color: color-mix(in srgb, var(--gallery-editorial-ivory) 88%, transparent);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid transparent;
    transition: border-color var(--gallery-editorial-transition), background-color var(--gallery-editorial-transition);
}

.vfw-gallery-header-scrolled {
    background-color: var(--gallery-editorial-ivory);
    border-bottom-color: var(--gallery-editorial-rule);
}

.vfw-gallery-header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gallery-editorial-gap);
    min-height: 4.5rem;
}

.vfw-gallery-monogram {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.vfw-gallery-monogram-mark {
    font-family: var(--gallery-editorial-font-display);
    font-size: 1.9rem;
    line-height: 1;
    color: var(--gallery-editorial-accent);
}

.vfw-gallery-monogram-name {
    font-family: var(--gallery-editorial-font-display);
    font-size: 0.95rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--gallery-editorial-ink);
}

.vfw-gallery-nav {
    display: flex;
    align-items: center;
    gap: 2.25rem;
}

.vfw-gallery-nav-link {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    text-transform: uppercase;
    color: var(--gallery-editorial-ink-soft);
    padding-bottom: 2px;
    border-bottom: 1px solid transparent;
    transition: color var(--gallery-editorial-transition), border-color var(--gallery-editorial-transition);
}

.vfw-gallery-nav-link:hover,
.vfw-gallery-nav-link-current {
    color: var(--gallery-editorial-accent);
    border-bottom-color: var(--gallery-editorial-ochre);
}

.vfw-gallery-nav-toggle {
    display: none;
    background: none;
    border: 0;
    padding: 0.5rem;
    cursor: pointer;
    color: var(--gallery-editorial-ink);
}

/* ==========================================================================
    6. BUTTONS AND LINK ACTIONS
   ========================================================================== */

.vfw-gallery-button-solid {
    display: inline-flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.95rem 1.6rem;
    background-color: var(--gallery-editorial-accent);
    color: var(--gallery-editorial-paper);
    border: 0;
    font-family: var(--gallery-editorial-font-interface);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    text-transform: uppercase;
    cursor: pointer;
    transition: background-color var(--gallery-editorial-transition);
}

.vfw-gallery-button-solid:hover {
    background-color: var(--gallery-editorial-accent-hover);
}

.vfw-gallery-button-outline {
    display: inline-flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.95rem 1.6rem;
    background-color: transparent;
    color: var(--gallery-editorial-accent);
    border: 1px solid var(--gallery-editorial-accent);
    font-family: var(--gallery-editorial-font-interface);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    text-transform: uppercase;
    cursor: pointer;
    transition: background-color var(--gallery-editorial-transition), color var(--gallery-editorial-transition);
}

.vfw-gallery-button-outline:hover {
    background-color: var(--gallery-editorial-accent);
    color: var(--gallery-editorial-paper);
}

.vfw-gallery-button-link {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    background: none;
    border: 0;
    padding: 0;
    font-family: var(--gallery-editorial-font-interface);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    text-transform: uppercase;
    color: var(--gallery-editorial-accent);
    cursor: pointer;
    transition: gap var(--gallery-editorial-transition);
}

.vfw-gallery-button-link:hover {
    gap: 1.15rem;
}

.vfw-gallery-button-underline {
    display: inline-block;
    background: none;
    border: 0;
    padding: 0 0 3px 0;
    border-bottom: 1px solid var(--gallery-editorial-ochre);
    font-family: var(--gallery-editorial-font-interface);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    text-transform: uppercase;
    color: var(--gallery-editorial-accent);
    cursor: pointer;
}

.vfw-gallery-arrow {
    display: inline-block;
    width: 1.5rem;
    height: 1px;
    background-color: currentColor;
    position: relative;
    flex: none;
}

.vfw-gallery-arrow::after {
    content: "";
    position: absolute;
    right: 0;
    top: -3px;
    width: 7px;
    height: 7px;
    border-top: 1px solid currentColor;
    border-right: 1px solid currentColor;
    transform: rotate(45deg);
}

/* ==========================================================================
    7. HERO
   ========================================================================== */

.vfw-gallery-hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.75fr);
    align-items: stretch;
    gap: 0;
    min-height: 78vh;
}

.vfw-gallery-hero-text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 4rem var(--gallery-editorial-shell-padding) 4rem 0;
}

.vfw-gallery-hero-image {
    position: relative;
    overflow: hidden;
    aspect-ratio: var(--gallery-editorial-hero-ratio);
    background-color: var(--gallery-editorial-ivory-deep);
}

.vfw-gallery-hero-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--gallery-editorial-hero-focus);
    display: block;
}

/* A rotating hero stacks two images in the one panel and dissolves between
   them. The stacking is scoped to this modifier deliberately: taking the images
   out of flow unconditionally would collapse an `auto`-ratio panel to zero
   height, because nothing in flow would be left to give it one. A rotating hero
   always pins --gallery-editorial-hero-ratio, so its panel keeps its height. */
.vfw-gallery-hero-image-rotating img {
    position: absolute;
    inset: 0;
    transition: opacity var(--gallery-editorial-hero-fade) ease;
}

/* The layer waiting its turn. Each swap builds a fresh image into this slot and
   decodes it before touching opacity, so what the visitor sees is a dissolve
   rather than a half-drawn painting; the consumer keeps the next file warm in
   cache so that decode is a cache read and not a fetch. */
.vfw-gallery-hero-image-rotating img.vfw-gallery-hero-idle {
    opacity: 0;
}

/* The regions that follow a rotating hero. They are rebuilt outright rather
   than diffed, so they dissolve in instead of appearing mid-sentence. */
.vfw-gallery-rotate-in {
    animation: vfw-gallery-fade-in var(--gallery-editorial-hero-fade) ease both;
}

@keyframes vfw-gallery-fade-in {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

/* ==========================================================================
    8. IMMERSION BAND
   ========================================================================== */

/* Columns follow the number of figures rather than a fixed three, so a two-image
   band (the spec's detail + installation pair) fills the width instead of leaving
   an empty third track. Works for any count without a modifier class. */
.vfw-gallery-immersion {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 0.5rem;
}

.vfw-gallery-immersion-figure {
    position: relative;
    overflow: hidden;
    aspect-ratio: 4 / 3;
    background-color: var(--gallery-editorial-ivory-deep);
    margin: 0;
}

.vfw-gallery-immersion-figure img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 400ms ease;
}

.vfw-gallery-immersion-figure:hover img {
    transform: scale(1.03);
}

/* ==========================================================================
    9. ARTWORK GRID AND CARD
   ========================================================================== */

.vfw-gallery-work-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: var(--gallery-editorial-gap-large) var(--gallery-editorial-gap);
}

.vfw-gallery-work-grid-wide {
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
}

/* An explicit three-up row, for the homepage's Selected Works band. Deliberately
   NOT auto-fill: an auto-fill track nested in a narrow parent silently collapses
   to a single column, which is what flattened this band into one 410px column and
   made the homepage 5,146px tall. Three works, three columns, at any parent width. */
.vfw-gallery-work-grid-three {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.vfw-gallery-work-card {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

/* A REPRODUCTION IS NEVER CROPPED.
   This frame holds a painting, so the image is contained inside a fixed plate
   rather than cropped to fill it — a gallery does not trim a canvas to fit a
   grid cell, and `object-fit: cover` was cutting the top off El triunfo del
   otium in the archive. The ivory-deep ground reads as a mat around works whose
   proportions differ from the plate.
   Photographs (installation shots, the immersion band) may still crop — those
   use .vfw-gallery-immersion-figure / .vfw-gallery-exhibition-frame. */
.vfw-gallery-work-frame {
    overflow: hidden;
    background-color: var(--gallery-editorial-ivory-deep);
    aspect-ratio: 4 / 5;
}

.vfw-gallery-work-frame img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    transition: transform 400ms ease;
}

.vfw-gallery-work-card:hover .vfw-gallery-work-frame img {
    transform: scale(1.025);
}

.vfw-gallery-work-name {
    font-family: var(--gallery-editorial-font-display);
    font-size: 1.05rem;
    line-height: 1.25;
    color: var(--gallery-editorial-ink);
    margin: 0;
}

.vfw-gallery-work-meta {
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--gallery-editorial-ink-faint);
    margin: 0;
}

.vfw-gallery-work-underline {
    width: 1.75rem;
    height: 2px;
    background-color: var(--gallery-editorial-ochre);
    border: 0;
    margin: 0.15rem 0 0 0;
}

/* ==========================================================================
    10. METADATA TABLE
   ========================================================================== */

.vfw-gallery-facts {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.vfw-gallery-facts th,
.vfw-gallery-facts td {
    padding: 0.65rem 0;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--gallery-editorial-rule);
}

.vfw-gallery-facts th {
    font-weight: 400;
    color: var(--gallery-editorial-ink-faint);
    width: 40%;
}

.vfw-gallery-facts td {
    color: var(--gallery-editorial-ink);
}

.vfw-gallery-status-available {
    color: var(--gallery-editorial-ochre-text);
    font-weight: 600;
}

.vfw-gallery-status-sold {
    color: var(--gallery-editorial-ink-faint);
    font-weight: 600;
}

/* ==========================================================================
    11. COLLECTOR ASIDE
   ========================================================================== */

.vfw-gallery-aside {
    background-color: var(--gallery-editorial-ivory-deep);
    padding: 2.25rem 2rem;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
    align-items: flex-start;
}

/* ==========================================================================
    12. EXHIBITION ROW
   ========================================================================== */

.vfw-gallery-exhibition-row {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: var(--gallery-editorial-gap-large);
    align-items: start;
}

/* Featured work beside the collector aside: the work gets the wider track. */
.vfw-gallery-feature-row {
    display: grid;
    grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
    gap: var(--gallery-editorial-gap-large);
    align-items: start;
}

/* Contact: a short list of addresses must not hold a track wider than the form
   it sits beside, or the page reads as a void with a form pushed to one edge. */
.vfw-gallery-contact-row {
    display: grid;
    grid-template-columns: minmax(0, 0.75fr) minmax(0, 1fr);
    gap: var(--gallery-editorial-gap-large);
    align-items: start;
}

.vfw-gallery-exhibition-frame {
    overflow: hidden;
    background-color: var(--gallery-editorial-ivory-deep);
    aspect-ratio: 3 / 2;
}

.vfw-gallery-exhibition-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.vfw-gallery-exhibition-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.vfw-gallery-exhibition-item {
    display: grid;
    grid-template-columns: 5rem minmax(0, 1fr);
    gap: var(--gallery-editorial-gap);
    padding: 1.25rem 0;
    border-bottom: 1px solid var(--gallery-editorial-rule);
}

.vfw-gallery-exhibition-year {
    font-family: var(--gallery-editorial-font-display);
    font-size: 1.1rem;
    color: var(--gallery-editorial-ink-faint);
}

/* ==========================================================================
    13. PORTRAIT ROW
   ========================================================================== */

.vfw-gallery-portrait-row {
    display: grid;
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.3fr);
    gap: var(--gallery-editorial-gap-large);
    align-items: start;
}

.vfw-gallery-portrait-frame {
    overflow: hidden;
    background-color: var(--gallery-editorial-ivory-deep);
    aspect-ratio: 4 / 5;
    filter: var(--gallery-editorial-portrait-filter);
}

.vfw-gallery-portrait-frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* ==========================================================================
    14. STUDIO NOTES BAND
   ========================================================================== */

.vfw-gallery-notes {
    background-color: var(--gallery-editorial-accent);
    color: var(--gallery-editorial-paper);
    /* Re-bound for this dark ground. NOTE this is inheritance, not scoping: a
       LIGHT-backgrounded element nested in here would inherit paper too and get
       an invisible paper-on-paper ring. If you nest one, re-bind this token back
       on its wrapper. */
    --gallery-editorial-focus: var(--gallery-editorial-paper);
    padding: 2.5rem 2.25rem;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--gallery-editorial-gap-large);
    align-items: center;
}

/* (0,3,0) — deliberately above the h2/h3 label override, which is (0,2,1) and
   sets `color: accent`. On this band the accent IS the background, so losing
   this cascade renders the heading teal-on-teal and invisible.
   RULE: any future contextual recolor of .vfw-gallery-label must be written at
   (0,3,0) or higher, i.e. scoped under .vfw-theme-gallery-editorial as well as
   its context. Element-qualified overrides silently outrank a bare two-class
   descendant selector. */
.vfw-theme-gallery-editorial .vfw-gallery-notes .vfw-gallery-label {
    color: var(--gallery-editorial-paper);
}

.vfw-gallery-notes-copy {
    font-size: 0.9rem;
    line-height: 1.6;
    color: color-mix(in srgb, var(--gallery-editorial-paper) 82%, transparent);
    margin: 0.6rem 0 0 0;
    max-width: 40ch;
}

.vfw-gallery-notes-form {
    display: flex;
    gap: 0;
}

.vfw-gallery-notes-form input {
    flex: 1;
    min-width: 0;
    padding: 0.85rem 1rem;
    background-color: transparent;
    border: 1px solid color-mix(in srgb, var(--gallery-editorial-paper) 45%, transparent);
    color: var(--gallery-editorial-paper);
    font-family: var(--gallery-editorial-font-interface);
    font-size: 0.85rem;
}

.vfw-gallery-notes-form input::placeholder {
    color: color-mix(in srgb, var(--gallery-editorial-paper) 60%, transparent);
}

.vfw-gallery-notes-form button {
    padding: 0.85rem 1.4rem;
    background-color: transparent;
    border: 1px solid color-mix(in srgb, var(--gallery-editorial-paper) 45%, transparent);
    border-left: 0;
    color: var(--gallery-editorial-paper);
    font-family: var(--gallery-editorial-font-interface);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    text-transform: uppercase;
    cursor: pointer;
    transition: background-color var(--gallery-editorial-transition), color var(--gallery-editorial-transition);
}

.vfw-gallery-notes-form button:hover {
    background-color: var(--gallery-editorial-paper);
    color: var(--gallery-editorial-accent);
}

/* ==========================================================================
    15. FORMS
   ========================================================================== */

.vfw-gallery-form {
    display: grid;
    gap: 1.25rem;
    max-width: 34rem;
}

.vfw-gallery-field {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.vfw-gallery-field label {
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    text-transform: uppercase;
    color: var(--gallery-editorial-ink-faint);
}

.vfw-gallery-field input,
.vfw-gallery-field select,
.vfw-gallery-field textarea {
    padding: 0.8rem 0.9rem;
    background-color: var(--gallery-editorial-paper);
    border: 1px solid var(--gallery-editorial-rule-strong);
    color: var(--gallery-editorial-ink);
    font-family: var(--gallery-editorial-font-interface);
    font-size: 0.9rem;
    border-radius: 0;
}

.vfw-gallery-field textarea {
    min-height: 8rem;
    resize: vertical;
}

/* The accent border is the mouse-focus treatment. It must NOT carry
   `outline: none`, which outranks the theme's own :focus-visible ring by
   specificity and left keyboard focus signalled by a 1px border shift alone.
   :focus-visible keeps the ring; a pointer click still gets the quiet form. */
.vfw-gallery-field input:focus,
.vfw-gallery-field select:focus,
.vfw-gallery-field textarea:focus {
    border-color: var(--gallery-editorial-accent);
}

.vfw-gallery-field input:focus:not(:focus-visible),
.vfw-gallery-field select:focus:not(:focus-visible),
.vfw-gallery-field textarea:focus:not(:focus-visible) {
    outline: none;
}

.vfw-gallery-form-note {
    font-size: 0.82rem;
    line-height: 1.6;
    margin: 0;
}

.vfw-gallery-form-note-success {
    color: var(--gallery-editorial-accent);
}

.vfw-gallery-form-note-error {
    color: var(--gallery-editorial-ember-text);
}

/* ==========================================================================
    16. FOOTER
   ========================================================================== */

.vfw-gallery-footer {
    background-color: var(--gallery-editorial-accent);
    color: var(--gallery-editorial-paper);
    /* Re-bound for this dark ground. NOTE this is inheritance, not scoping: a
       LIGHT-backgrounded element nested in here would inherit paper too and get
       an invisible paper-on-paper ring. If you nest one, re-bind this token back
       on its wrapper. */
    --gallery-editorial-focus: var(--gallery-editorial-paper);
    padding: 2.25rem 0;
}

.vfw-gallery-footer-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gallery-editorial-gap-large);
    flex-wrap: wrap;
}

.vfw-gallery-footer .vfw-gallery-monogram-mark,
.vfw-gallery-footer .vfw-gallery-monogram-name {
    color: var(--gallery-editorial-paper);
}

.vfw-gallery-footer-nav {
    display: flex;
    gap: 1.75rem;
    flex-wrap: wrap;
}

.vfw-gallery-footer-link {
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    text-transform: uppercase;
    color: color-mix(in srgb, var(--gallery-editorial-paper) 82%, transparent);
    transition: color var(--gallery-editorial-transition);
}

.vfw-gallery-footer-link:hover {
    color: var(--gallery-editorial-paper);
}

.vfw-gallery-footer-legal {
    font-size: 0.78rem;
    color: color-mix(in srgb, var(--gallery-editorial-paper) 72%, transparent);
    margin: 0;
}

/* ==========================================================================
    17. SKIP LINK
   ========================================================================== */

/* Off-screen until focused. Every page needs one and its treatment is entirely
   theme-level, so it belongs here rather than in each consumer's app layer. */
.vfw-gallery-skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: 0.75rem 1.25rem;
    background-color: var(--gallery-editorial-accent);
    color: var(--gallery-editorial-paper);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    text-transform: uppercase;
}

.vfw-gallery-skip-link:focus {
    left: 0;
}

/* ==========================================================================
    18. LANGUAGE TOGGLE
   ========================================================================== */

/* A bilingual site is the norm for a gallery, not a Daniel-specific need. */
.vfw-gallery-language-button {
    background: none;
    border: 0;
    padding: 0;
    font-family: inherit;
    font-size: inherit;
    font-weight: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    color: var(--gallery-editorial-ink-faint);
    cursor: pointer;
    transition: color var(--gallery-editorial-transition);
}

.vfw-gallery-language-button:hover,
.vfw-gallery-language-button-current {
    color: var(--gallery-editorial-accent);
}

/* ==========================================================================
    19. VERTICAL RHYTHM UTILITIES
   ========================================================================== */

/* A three-step scale, named by role rather than by value so the spacing can be
   retuned in one place: `small` separates a block from the one above it,
   `action-row` sits above a call to action, `large` opens a new grouping. */
.vfw-gallery-gap-small {
    margin-top: 1.25rem;
}

.vfw-gallery-action-row {
    margin-top: 1.75rem;
}

.vfw-gallery-gap-large {
    margin-top: 2.5rem;
}

/* The attributed line under a pulled quote. */
.vfw-gallery-attribution {
    margin-top: 1.5rem;
    text-align: center;
}

/* ==========================================================================
    20. PLATE FIGURE — the core artwork primitive
   ========================================================================== */

/* A REPRODUCTION IS NEVER CROPPED. Sections 8 and 9 provide cropping frames,
   which are right for photographs; this is the opposite primitive and the one a
   gallery theme most needs: the work shown WHOLE at its own proportions, on the
   ivory-deep ground, with its height driven by the image itself.
   Do not reuse a fixed-ratio frame here — its `height: 100%` image collapses to
   nothing once the ratio is removed, which is how the paintings once vanished
   from the artwork page entirely. */
.vfw-gallery-plate-figure {
    margin: 0 0 0.75rem 0;
    background-color: var(--gallery-editorial-ivory-deep);
}

.vfw-gallery-plate-figure img {
    display: block;
    width: 100%;
    height: auto;
}

/* Every clickable image sits inside a bare button; strip the control chrome so
   only the work is visible. Covers all three frame types. */
.vfw-gallery-plate-figure button,
.vfw-gallery-immersion-figure button,
.vfw-gallery-work-frame button {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: zoom-in;
}

.vfw-gallery-immersion-figure button,
.vfw-gallery-work-frame button {
    height: 100%;
}

/* ==========================================================================
    21. STICKY DETAIL COLUMN
   ========================================================================== */

/* Metadata stays with the reader while a tall image sequence scrolls past. */
.vfw-gallery-sticky-meta {
    position: sticky;
    top: 6rem;
    align-self: start;
}

/* ==========================================================================
    22. PENDING MEDIA PLATE
   ========================================================================== */

/* A labelled placeholder for media that has not been supplied yet — a portrait,
   an installation shot — so a gap reads as deliberate rather than broken. */
.vfw-gallery-media-pending {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--gallery-editorial-ivory-deep);
    border: 1px solid var(--gallery-editorial-rule);
    filter: none;
}

/* ==========================================================================
    23. FILTER ROW
   ========================================================================== */

/* The archive's All / Available / Sold row. Was set with inline JS styles by the
   first consumer and never reached CSS at all. */
.vfw-gallery-filter-row {
    display: flex;
    gap: 1.75rem;
    flex-wrap: wrap;
    margin-bottom: 2.5rem;
}

/* ==========================================================================
    24. LIGHTBOX
   ========================================================================== */

.vfw-gallery-lightbox {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    background-color: color-mix(in srgb, var(--gallery-editorial-ink) 92%, transparent);
    /* Near-black ground: cobalt would be 1.79:1 here. The close button is the only
       focusable child, and it is the sole way out for a keyboard user. Same
       inheritance caveat as the other two re-binds: a light-backgrounded child
       nested here must re-bind this token back on its own wrapper. */
    --gallery-editorial-focus: var(--gallery-editorial-paper);
}

.vfw-gallery-lightbox img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    display: block;
}

.vfw-gallery-lightbox-close {
    position: absolute;
    top: 1.25rem;
    right: 1.5rem;
    background: none;
    border: 0;
    color: var(--gallery-editorial-paper);
    font-family: var(--gallery-editorial-font-interface);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: var(--gallery-editorial-label-tracking);
    text-transform: uppercase;
    cursor: pointer;
}

/* ==========================================================================
    25. RESPONSIVE
   ========================================================================== */

@media (max-width: 900px) {
    .vfw-theme-gallery-editorial {
        --gallery-editorial-section-space: 3.5rem;
        --gallery-editorial-shell-padding: 1.25rem;
    }

    .vfw-gallery-hero {
        grid-template-columns: minmax(0, 1fr);
        min-height: 0;
    }

    .vfw-gallery-hero-text {
        padding: 2.5rem 0 2rem 0;
    }

    /* `order` has to sit on the DIRECT grid children. It was previously set on
       .vfw-gallery-hero-text, which is nested inside the shell and therefore not
       a grid item at all — the rule was inert and the painting stayed below the
       text. On a portfolio the work leads. */
    .vfw-gallery-hero-shell {
        order: 2;
    }

    .vfw-gallery-hero-image {
        order: 1;
        aspect-ratio: 4 / 5;
    }

    /* Stack on a phone: side-by-side detail shots become unreadable slivers. */
    .vfw-gallery-immersion {
        grid-auto-flow: row;
        grid-auto-columns: auto;
        grid-template-columns: minmax(0, 1fr);
    }

    .vfw-gallery-exhibition-row,
    .vfw-gallery-feature-row,
    .vfw-gallery-contact-row,
    .vfw-gallery-portrait-row,
    .vfw-gallery-notes {
        grid-template-columns: minmax(0, 1fr);
    }

    /* Touch targets: the nav links, the works filters and the ES/EN toggle are all
       small tracked-out type, well under the 44px minimum on their own. */
    .vfw-gallery-nav-link {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
    }

    .vfw-gallery-nav {
        display: none;
    }

    .vfw-gallery-nav-open {
        display: flex;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: flex-start;
        gap: 1.25rem;
        padding: 1.5rem var(--gallery-editorial-shell-padding);
        background-color: var(--gallery-editorial-ivory);
        border-bottom: 1px solid var(--gallery-editorial-rule);
    }

    .vfw-gallery-nav-toggle {
        display: block;
    }

    .vfw-gallery-header-inner {
        position: relative;
    }
}

@media (max-width: 560px) {
    /* auto-FIT, not auto-fill: a year group holding a single work collapses the
       empty track and the work fills the row, instead of sitting in a half-empty
       two-up grid. Desktop keeps auto-fill, where a lone full-width card would be
       overbearing rather than generous. */
    .vfw-gallery-work-grid {
        grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    }

    /* Two-up rather than three-up on a phone: at 390px a third of the width is a
       ~110px painting, which is a thumbnail of a thumbnail. */
    .vfw-gallery-work-grid-three {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .vfw-gallery-notes-form {
        flex-direction: column;
    }

    .vfw-gallery-notes-form button {
        border-left: 1px solid color-mix(in srgb, var(--gallery-editorial-paper) 45%, transparent);
        border-top: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .vfw-theme-gallery-editorial *,
    .vfw-theme-gallery-editorial *::before,
    .vfw-theme-gallery-editorial *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
    }
}
/* @audited cfw style=951550e852e0 memsec=951550e852e0 test=951550e852e0 design=06ec70884e90 */
