/* =============================================================================
   FONT DECLARATIONS  (self-hosted — do not point these at a CDN)
   ============================================================================= */

@font-face {
    font-display: swap;
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400;
    src: url('../assets/fonts/inter-v19-latin-regular.woff2') format('woff2');
}

@font-face {
    font-display: swap;
    font-family: 'Inter';
    font-style: normal;
    font-weight: 500;
    src: url('../assets/fonts/inter-v19-latin-500.woff2') format('woff2');
}

@font-face {
    font-display: swap;
    font-family: 'Inter';
    font-style: normal;
    font-weight: 600;
    src: url('../assets/fonts/inter-v19-latin-600.woff2') format('woff2');
}

@font-face {
    font-display: swap;
    font-family: 'Inter';
    font-style: normal;
    font-weight: 700;
    src: url('../assets/fonts/inter-v19-latin-700.woff2') format('woff2');
}

@font-face {
    font-display: swap;
    font-family: 'Playfair Display';
    font-style: normal;
    font-weight: 600;
    src: url('../assets/fonts/playfair-display-v39-latin-600.woff2') format('woff2');
}

@font-face {
    font-display: swap;
    font-family: 'Playfair Display';
    font-style: normal;
    font-weight: 700;
    src: url('../assets/fonts/playfair-display-v39-latin-700.woff2') format('woff2');
}

/* Real italic cut — the hero title echoes the logo's script, and a browser's
   synthesised oblique of Playfair looks like a mistake. v40 is simply the
   version Google ships this face at; the roman files above are still v39. */
@font-face {
    font-display: swap;
    font-family: 'Playfair Display';
    font-style: italic;
    font-weight: 700;
    src: url('../assets/fonts/playfair-display-v40-latin-700italic.woff2') format('woff2');
}

/* =============================================================================
   DESIGN TOKENS  —  RE-SKIN KNOB
   Change brand colour / fonts / rhythm here when copying to another project.
   The brand colour is sampled from the logo (public/images/logo.jpg).
   ============================================================================= */

:root {
    /* Brand — the logo's metallic "Mia" script. Sampled straight, its tones
       are shadow #67410d / mid #966b25 / highlight #c89f57, hue 35–38° — but
       a FLAT swatch at that hue reads brown, because the mark only looks
       golden thanks to its highlights. So the palette is pitched warmer and
       lighter than the raw sample: hue 46°. Two levers make something read as
       gold rather than rust — a yellower hue and higher lightness — but on a
       background this light, lightness is nearly spent (see below), so the
       hue is doing most of the work.

       --brand is the display gold, matched by eye to the logo's own script.
       It is DELIBERATELY below the 3:1 WCAG large-text floor (2.5:1 on the
       cream, 2.54:1 on the hero backdrop): a gold bright enough to read as
       gold cannot reach 3:1 against a background this light — that is
       luminance, not a tuning problem. Accepted as a considered trade for
       the display headings only.

       EVERYTHING FUNCTIONAL STAYS COMPLIANT and must keep using --brand-ink
       (4.58:1) — eyebrows, links, footer headings, icons, and any control
       boundary such as the primary button's border. Never put --brand on
       body-size text. --brand-soft is a FILL only (1.7:1 as text). */
    --brand: #b8942c;
    --brand-ink: #7e671a;
    --brand-soft: #ddc47c;
    --brand-press: #5e4c12;
    --brand-tint: rgba(184, 148, 44, 0.10);
    --on-brand: #fdf6ea;
    --ink: #3d2e12;

    /* Section background images. These live here rather than in a style=""
       attribute because the CSP has no 'unsafe-inline' for styles — that is
       also why the hero slideshow uses fixed .hero__slide--N classes instead
       of per-image inline backgrounds. All are laid in under a heavy cream
       wash so they read as paper texture, never as a dark photo band — swap
       for real studio photography once available. */
    --hero-image:   url('/images/hero-bg.jpg');
    --hero-image-2: url('/images/hero-2.jpg');
    --hero-image-3: url('/images/hero-3.jpg');
    --hero-image-4: url('/images/hero-4.jpg');
    --banner-image: url('/images/banner-bg.jpg');

    /* How far the hero photography is allowed to come through. Pushed past
       the original 0.16 so the studio's own work is actually readable behind
       the type; the cream wash in .hero__overlay still keeps the centre
       (where the text sits) light enough to stay legible. */
    --hero-veil: 0.42;

    /* Surfaces — ONE cream for the whole site (the card stock). --surface-2 is
       a barely-there lift used only inside panels; nothing is ever dark. */
    --bg: #f8e9d2;
    --surface: #f8e9d2;
    --surface-2: #fbf0dd;
    --line: rgba(94, 76, 18, 0.22);
    --line-strong: rgba(94, 76, 18, 0.40);

    /* Text — the same 42° gold hue carried down into the browns, so nothing
       on the page reads as a different family. --text-mute is 4.71:1; the
       original #8f7550 was 3.64:1 and quietly failed on the dt labels. */
    --text: #3d2e12;
    --text-dim: #6b5527;
    --text-mute: #79653a;

    /* Type */
    --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
    --step--1: clamp(0.83rem, 0.8rem + 0.15vw, 0.9rem);
    --step-0: clamp(1rem, 0.96rem + 0.2vw, 1.08rem);
    --step-1: clamp(1.2rem, 1.1rem + 0.5vw, 1.5rem);
    --step-2: clamp(1.6rem, 1.4rem + 1vw, 2.25rem);
    --step-3: clamp(2.1rem, 1.7rem + 2vw, 3.25rem);
    --step-4: clamp(2.8rem, 2rem + 4vw, 5.5rem);

    /* Layout */
    --container: 1200px;
    --gutter: clamp(1.25rem, 5vw, 2.5rem);
    --section-pad: clamp(4rem, 10vw, 8rem);
    --radius: 14px;
    --radius-sm: 10px;
    --header-h: 100px;
    --ease: cubic-bezier(0.22, 1, 0.36, 1);

    /* Backwards-compat alias (old rules referenced --primary-red) */
    --primary-red: var(--brand);
}

/* =============================================================================
   RESET & BASE
   ============================================================================= */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

body {
    font-family: var(--font-body);
    font-size: var(--step-0);
    line-height: 1.7;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

body.is-inner { padding-top: var(--header-h); }

img, picture, svg { display: block; max-width: 100%; }

h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 700;
    line-height: 1.12;
    letter-spacing: -0.01em;
    color: var(--ink);
}

h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-1); }

p { text-wrap: pretty; }

a { color: inherit; text-decoration: none; }

p a, .legal a, dd a {
    color: var(--text);
    text-decoration: underline;
    text-decoration-color: var(--brand);
    text-underline-offset: 3px;
    transition: color 0.2s var(--ease);
}

p a:hover, .legal a:hover, dd a:hover { color: var(--brand-ink); }

:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 3px;
    border-radius: 4px;
}

::selection { background: var(--brand); color: var(--on-brand); }

::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--brand-soft); border-radius: 6px; }
::-webkit-scrollbar-thumb:hover { background: var(--brand); }

.container {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.section { padding-block: var(--section-pad); }

.skip-link {
    position: fixed;
    top: 0;
    left: 0;
    transform: translateY(-120%);
    background: var(--brand-press);
    color: var(--on-brand);
    padding: 0.75rem 1.25rem;
    font-weight: 600;
    z-index: 2000;
    transition: transform 0.2s var(--ease);
}

.skip-link:focus { transform: translateY(0); }

.eyebrow {
    font-family: var(--font-body);
    font-size: var(--step--1);
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    /* The display gold, matching the hero title — see the accessibility note
       in CLAUDE.md §3. This is the one place --brand is used at body size,
       and at 2.4:1 it is well under the 4.5:1 small-text floor. It is a
       decorative label that always restates or categorises the heading
       directly beneath it, so no information lives here alone. */
    color: var(--brand);
    margin-bottom: 1rem;
}

/* =============================================================================
   BUTTONS
   ============================================================================= */

.btn {
    --btn-bg: var(--brand-ink);
    --btn-fg: var(--on-brand);
    --btn-bd: var(--brand-ink);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    padding: 0.95rem 1.7rem;
    background: var(--btn-bg);
    color: var(--btn-fg);
    border: 1.5px solid var(--btn-bd);
    border-radius: var(--radius-sm);
    font: 600 var(--step--1)/1 var(--font-body);
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: transform 0.2s var(--ease), background-color 0.2s var(--ease), color 0.2s var(--ease);
}

/* Buttons carry no shadow anywhere — hover is the lift and the colour
   change alone. */
.btn:hover {
    transform: translateY(-2px);
}

/* Flat gold — no gradient anywhere on the site. The fill is the bright
   metallic --brand-soft with DARK ink on it (6.9:1), not cream on a dark
   bronze: a cream label caps the fill at roughly --brand-ink lightness, which
   is exactly the bronze look this is meant to avoid.

   Outlined, not filled: a 2px --brand rule on the bare cream with the label
   in --brand-ink. The label is real body-size text, so it must stay on
   --brand-ink (4.57:1); --brand is fine on the 2px border, which is decor
   plus boundary rather than text. This reads more strongly than .btn--ghost
   (1.5px, --line-strong) purely through border weight and saturation, so the
   two remain distinguishable without a fill. Hover inverts to the gold fill
   with dark ink, which is also the only state where the control is solid. */
.btn--primary {
    background: transparent;
    color: var(--brand-ink);
    border-color: var(--brand);
    border-width: 2px;
}

/* Hover fills flat: the 2px border goes transparent rather than away, so the
   button does not resize — the gold background paints under it. */
.btn--primary:hover {
    background: var(--brand-soft);
    color: var(--ink);
    border-color: transparent;
}

.btn--ghost {
    --btn-bg: transparent;
    --btn-fg: var(--brand-ink);
    --btn-bd: var(--line-strong);
}

.btn--ghost:hover {
    background: var(--brand-press);
    color: var(--on-brand);
    border-color: var(--brand-press);
}

.btn--light {
    --btn-bg: #fffaf1;
    --btn-fg: var(--brand-ink);
    --btn-bd: var(--line-strong);
}

.btn--light:hover { background: var(--brand-press); color: var(--on-brand); border-color: var(--brand-press); }

.btn--sm { padding: 0.65rem 1.15rem; }

/* =============================================================================
   GOLD ORNAMENT
   The card's filigree divider: a hairline that fades out both ways around a
   centred diamond (or a Font Awesome heart for .ornament--heart).
   ============================================================================= */

.ornament {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.85rem;
    width: min(320px, 70vw);
    margin: 1.4rem auto 0;
    color: var(--brand);
}

.ornament::before,
.ornament::after {
    content: '';
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, transparent, currentColor);
}

.ornament::after { background: linear-gradient(90deg, currentColor, transparent); }

.ornament > span {
    flex: none;
    width: 7px;
    height: 7px;
    background: currentColor;
    transform: rotate(45deg);
}

.ornament > i { flex: none; font-size: 0.85rem; line-height: 1; }

/* Inner-page heroes are left-aligned, so the rule must not centre itself. */
.ornament--start { margin-inline: 0; }

/* =============================================================================
   HEADER / NAVIGATION
   ============================================================================= */

.site-header {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 1000;
    padding-block: 0.9rem;
    background: transparent;
    transition: background-color 0.3s var(--ease), box-shadow 0.3s var(--ease), backdrop-filter 0.3s var(--ease);
}

.site-header--solid,
.site-header.is-scrolled {
    background: rgba(250, 238, 217, 0.90);
    backdrop-filter: blur(14px);
    box-shadow: 0 1px 0 var(--line);
}

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

.brand img {
    height: 72px;
    width: auto;
    transition: transform 0.3s var(--ease);
}

.brand:hover img { transform: scale(1.05); }

.nav-desktop ul {
    display: flex;
    align-items: center;
    gap: 2rem;
    list-style: none;
    padding: 0;
}

.nav-desktop a {
    position: relative;
    font-weight: 600;
    font-size: var(--step--1);
    letter-spacing: 0.04em;
    color: var(--ink);
    padding-block: 0.4rem;
}

.nav-desktop a::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 0;
    height: 2px;
    background: var(--brand);
    transition: width 0.25s var(--ease);
}

.nav-desktop a:hover { color: var(--brand-ink); }
.nav-desktop a:hover::after { width: 100%; }

.nav-toggle {
    display: none;
    background: none;
    border: 0;
    color: var(--ink);
    font-size: 1.6rem;
    line-height: 1;
    padding: 0.4rem;
    cursor: pointer;
    transition: color 0.2s var(--ease);
}

.nav-toggle:hover { color: var(--brand-ink); }

.nav-mobile {
    position: fixed;
    inset: 0;
    z-index: 1600;
    background: var(--bg);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.35s var(--ease), visibility 0.35s var(--ease);
}

.nav-mobile.is-open { opacity: 1; visibility: visible; }

.nav-mobile ul { list-style: none; padding: 0; text-align: center; }

.nav-mobile a {
    display: block;
    padding: 1rem 2rem;
    font-family: var(--font-display);
    font-size: 1.6rem;
    color: var(--ink);
}

.nav-mobile a:hover { color: var(--brand-ink); }

.nav-close {
    position: absolute;
    top: 1.5rem;
    right: 1.5rem;
    background: none;
    border: none;
    color: var(--ink);
    font-size: 1.8rem;
    cursor: pointer;
    padding: 0.5rem;
}

/* =============================================================================
   HERO
   ============================================================================= */

.hero {
    position: relative;
    min-height: 100svh;
    display: flex;
    align-items: center;
    isolation: isolate;
    background: var(--bg);
}

/* Hero slideshow — four photos warmed into the cream and held far back, so
   this is paper texture that slowly changes, not a picture show. Everything
   above it stays dark-on-light.

   Pure CSS: no JS at all, which keeps main.js untouched and needs nothing
   from the CSP. Four slides x 8s = a 32s loop. Each slide's visible window is
   0%-25% of the loop — exactly its 1/4 slot — so consecutive slides dissolve
   through the cream rather than overlapping. That matters at load: the
   negative delays put slides 2-4 at 75%/50%/25% of their cycle, all of which
   are opacity 0, so the page always opens cleanly on slide 1.

   Under prefers-reduced-motion nothing animates and slide 1 simply stays up,
   which is exactly the old single-image hero. */
.hero__slides {
    position: absolute;
    inset: 0;
    z-index: -2;
    overflow: hidden;
}

.hero__slide {
    position: absolute;
    inset: 0;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    filter: sepia(0.6) saturate(0.6) contrast(0.88);
    opacity: 0;
}

.hero__slide--1 { background-image: var(--hero-image, none);   opacity: var(--hero-veil); }
.hero__slide--2 { background-image: var(--hero-image-2, none); }
.hero__slide--3 { background-image: var(--hero-image-3, none); }
.hero__slide--4 { background-image: var(--hero-image-4, none); }

@media (prefers-reduced-motion: no-preference) {
    .hero__slide {
        animation: heroSlide 32s linear infinite;
    }
    .hero__slide--1 { animation-delay: 0s; }
    .hero__slide--2 { animation-delay: -24s; }
    .hero__slide--3 { animation-delay: -16s; }
    .hero__slide--4 { animation-delay: -8s; }
}

@keyframes heroSlide {
    0%   { opacity: 0; }
    4%   { opacity: var(--hero-veil); }
    21%  { opacity: var(--hero-veil); }
    25%  { opacity: 0; }
    100% { opacity: 0; }
}

/* Inset double gold rule — the printed border of the card. The header is
   fixed and transparent over the hero, so the top edge starts BELOW it
   (--header-h + a gap > the 6px outline-offset) instead of running through
   the logo and the nav. */
.hero::after {
    content: '';
    position: absolute;
    inset: clamp(14px, 2.6vw, 34px);
    top: calc(var(--header-h) + clamp(14px, 1.8vw, 24px));
    z-index: -1;
    pointer-events: none;
    border: 1px solid rgba(94, 76, 18, 0.32);
    outline: 1px solid rgba(94, 76, 18, 0.24);
    outline-offset: 6px;
}

.hero__overlay {
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(58% 48% at 50% 48%, rgba(252, 245, 232, 0.93) 0%, rgba(252, 245, 232, 0.72) 55%, transparent 100%),
        linear-gradient(180deg, rgba(248, 233, 210, 0.42) 0%, rgba(248, 233, 210, 0.22) 42%, rgba(248, 233, 210, 0.72) 100%);
}

.hero__inner {
    text-align: center;
    padding-block: clamp(7rem, 16vh, 11rem) 4rem;
}

/* Hero entrance — pure CSS so it always finishes even if JS never runs.
   Under reduced motion the rule simply does not apply and content is static. */
@media (prefers-reduced-motion: no-preference) {
    [data-hero] {
        opacity: 0;
        animation: heroIn 0.6s var(--ease) forwards;
    }
    .hero__title    { animation-delay: 0.10s; }
    .hero .ornament { animation-delay: 0.18s; }
    .hero__subtitle { animation-delay: 0.26s; }
    .hero__meta     { animation-delay: 0.34s; }
    .hero__actions  { animation-delay: 0.42s; }
}

@keyframes heroIn {
    from { opacity: 0; transform: translateY(24px); }
    to   { opacity: 1; transform: none; }
}

.hero__toast {
    display: inline-block;
    background: rgba(255, 251, 243, 0.92);
    color: var(--brand);
    border: 1px solid var(--line-strong);
    font-weight: 600;
    font-size: var(--step--1);
    letter-spacing: 0.02em;
    padding: 0.4rem 1rem;
    border-radius: 999px;
    margin-bottom: 1.75rem;
    transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}

.hero__toast.is-hidden {
    opacity: 0;
    transform: translateY(-8px);
    pointer-events: none;
}

/* Italic + the logo's gold: this line is the wordmark restated in type.
   3.25:1 on the cream, which clears the 3:1 large-text floor — it is only
   safe here and on .banner__inner h2 because both are display-sized. */
.hero__title {
    font-size: var(--step-4);
    color: var(--brand);
    font-style: italic;
    letter-spacing: -0.01em;
    text-shadow: 0 1px 0 rgba(94, 76, 18, 0.45);
}

.hero__subtitle {
    margin-top: 1.5rem;
    font-size: var(--step-1);
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.22em;
    color: var(--brand);
}

/* The address is marked with the same gold diamond as .ornament rather than
   a Font Awesome pin — the solid pin sat heavy against this type, and the
   diamond ties the line to the rule directly above it. It is decoration
   only: the address reads as an address without it. */
.hero__meta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    margin-top: 1rem;
    color: var(--text-dim);
    font-size: var(--step-0);
}

.hero__meta::before {
    content: '';
    flex: none;
    width: 6px;
    height: 6px;
    background: var(--brand);
    transform: rotate(45deg);
}

.hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    justify-content: center;
    margin-top: 2.5rem;
}

/* =============================================================================
   ABOUT
   ============================================================================= */

.about { background: var(--bg); }

.about__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(2rem, 6vw, 5rem);
    align-items: center;
}

.about__text h2 { margin-bottom: 1.5rem; }
/* :not(.eyebrow) matters — a bare `.about__text p` is (0,1,1) and outranks
   `.eyebrow` (0,1,0), which silently gave this one eyebrow the body colour
   AND the body font-size while every other eyebrow on the site was correct. */
.about__text p:not(.eyebrow) { font-size: var(--step-0); }

.about__media {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(2, 1fr);
    gap: 1rem;
    height: clamp(360px, 46vw, 520px);
}

.about__img {
    overflow: hidden;
    border-radius: var(--radius);
    border: 1px solid var(--line);
}

.about__img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s var(--ease); }
.about__img:hover img { transform: scale(1.06); }

.about__img--1 { grid-row: 1 / 3; }

/* =============================================================================
   SERVICES
   The three headline treatments, each card linking straight to the booking
   page. auto-fit means the grid drops 3 -> 2 -> 1 on its own, so this needs
   no breakpoint of its own.
   ============================================================================= */

.services__head {
    text-align: center;
    margin-bottom: clamp(2rem, 5vw, 3rem);
}

.services__head h2 { font-size: var(--step-2); }

.services__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: clamp(1.25rem, 3vw, 2rem);
}

.service {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: linear-gradient(180deg, var(--surface-2), var(--surface));
    color: inherit;
    transition: transform 0.3s var(--ease), border-color 0.3s var(--ease);
}

.service:hover {
    transform: translateY(-4px);
    border-color: var(--line-strong);
}

.service__media {
    aspect-ratio: 4 / 3;
    overflow: hidden;
    margin: 0;
}

.service__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s var(--ease);
}

.service:hover .service__media img { transform: scale(1.06); }

.service__body {
    display: grid;
    gap: 0.6rem;
    padding: clamp(1.25rem, 3vw, 1.75rem);
}

.service__title { font-size: var(--step-1); }
.service__text { color: var(--text-dim); font-size: var(--step--1); }

.services__note {
    margin-top: clamp(1.75rem, 4vw, 2.5rem);
    text-align: center;
    color: var(--text-dim);
    font-size: var(--step--1);
}

.services__note a {
    color: var(--brand-ink);
    text-decoration: underline;
    text-decoration-color: var(--brand);
    text-underline-offset: 3px;
}

/* =============================================================================
   FUSION BANNER
   ============================================================================= */

.banner {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: clamp(340px, 55vh, 520px);
    text-align: center;
    isolation: isolate;
    border-block: 1px solid var(--line);
    background: var(--bg);
}

.banner::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -2;
    background: var(--banner-image, none) center / cover fixed no-repeat;
    filter: sepia(0.6) saturate(0.6) contrast(0.88);
    opacity: 0.14;
}

.banner__overlay {
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(60% 60% at 50% 50%, rgba(251, 242, 226, 0.88) 0%, rgba(251, 242, 226, 0.50) 65%, transparent 100%),
        linear-gradient(rgba(248, 233, 210, 0.55), rgba(248, 233, 210, 0.62));
}

.banner__inner { max-width: 60ch; }
.banner__inner h2 {
    font-size: var(--step-3);
    color: var(--brand);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-shadow: 0 1px 0 rgba(94, 76, 18, 0.45);
}
.banner__inner p { margin-top: 1rem; font-style: italic; color: var(--text-dim); font-size: var(--step-1); }

/* =============================================================================
   VISIT / CONTACT BLOCK
   A single framed panel: contact details on one side, a photo mosaic that
   bleeds to the panel edge on the other.
   ============================================================================= */

.visit { background: var(--bg); scroll-margin-top: var(--header-h); }

.visit__panel {
    display: grid;
    grid-template-columns: 1.05fr 0.95fr;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    background:
        radial-gradient(110% 80% at 0% 0%, var(--brand-tint), transparent 55%),
        linear-gradient(180deg, var(--surface-2), var(--surface));
}

.visit__body { padding: clamp(1.9rem, 4.5vw, 3.5rem); }

.visit__body h2 {
    font-size: var(--step-2);
    margin: 0.75rem 0 1.5rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--line);
}

.visit__media {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    gap: 2px;
    background: var(--line-strong);
    min-height: 100%;
}

.visit__media img {
    width: 100%;
    height: 100%;
    min-height: 190px;
    object-fit: cover;
    transition: transform 0.6s var(--ease), filter 0.4s var(--ease);
}

.visit__media:hover img { filter: brightness(0.78) sepia(0.12); }
.visit__media img:hover { transform: scale(1.05); filter: brightness(1); }

/* Shared contact list (also used by kontakt.php) — stacked, no dead space. */
.info__list { display: grid; }
.info__list > div {
    display: grid;
    gap: 0.3rem;
    padding-block: 1.05rem;
    border-bottom: 1px solid var(--line);
}
.info__list > div:first-child { padding-top: 0; }
.info__list > div:last-child { border-bottom: none; padding-bottom: 0; }
.info__list dt {
    font-size: var(--step--1);
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-mute);
}
.info__list dd { color: var(--text); font-size: 1.02rem; line-height: 1.65; }

.info__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin-top: 2rem;
}

/* kontakt.php still uses the standalone .info__card wrapper */
.info__card {
    background:
        radial-gradient(130% 90% at 100% 0%, var(--brand-tint), transparent 58%),
        linear-gradient(180deg, var(--surface-2), var(--surface));
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: clamp(1.75rem, 4vw, 3.25rem);
}
.info__card .eyebrow { margin-bottom: 0.75rem; }
.info__card h2 {
    font-size: var(--step-2);
    margin-bottom: 1.5rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--line);
}

/* =============================================================================
   MAP
   ============================================================================= */

.map { background: var(--bg); border-top: 1px solid var(--line); }

/* The banner carries its own bottom rule, so the map must not add a second. */
.banner + .map { border-top: 0; }

.map__frame {
    display: block;
    width: 100%;
    height: clamp(300px, 44vw, 460px);
    border: 0;
}

/* The Google Maps link floats over the embed instead of sitting in a bar
   below it. Top-LEFT on purpose: OpenStreetMap draws its zoom controls
   top-right and its "© OpenStreetMap contributors" attribution bottom-right
   inside the iframe, and neither may be covered — the embed carries the
   attribution the page no longer prints itself. */
.map__wrap { position: relative; }

.map__action {
    position: absolute;
    top: clamp(0.75rem, 2vw, 1.25rem);
    left: clamp(0.75rem, 2vw, 1.25rem);
    z-index: 1;
}

/* =============================================================================
   GALLERY  (galerie.php)
   CSS columns, not grid: the Unsplash shots are a mix of portrait and
   landscape and masonry lets every one keep its own aspect ratio instead of
   being cropped to a common box.
   ============================================================================= */

.gallery {
    columns: 3;
    column-gap: clamp(0.75rem, 2vw, 1.25rem);
}

/* A <button>, because it opens a dialog — so the UA chrome comes off and the
   focus ring is put back deliberately. */
.gallery__item {
    display: block;
    width: 100%;
    padding: 0;
    background: none;
    font: inherit;
    cursor: zoom-in;
    break-inside: avoid;
    margin: 0 0 clamp(0.75rem, 2vw, 1.25rem);
    overflow: hidden;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    transition: border-color 0.3s var(--ease);
}

.gallery__item:hover { border-color: var(--line-strong); }

.gallery__item img {
    width: 100%;
    height: auto;
    transition: transform 0.5s var(--ease), filter 0.4s var(--ease);
}

.gallery__item:hover img { transform: scale(1.05); }

.gallery__cta {
    margin-top: clamp(2.5rem, 7vw, 4.5rem);
    padding-top: clamp(2rem, 5vw, 3rem);
    border-top: 1px solid var(--line);
    text-align: center;
}

.gallery__cta h2 { font-size: var(--step-2); }
.gallery__cta .info__actions { justify-content: center; margin-top: 1.75rem; }

/* =============================================================================
   LIGHTBOX  (js/lightbox.js builds the markup; nothing here is in the DOM
   until that script runs, so a no-JS visitor just sees the tiles)
   ============================================================================= */

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 3000;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.2s var(--ease);
}

/* MUST stay. `display: flex` above is an author rule and therefore beats the
   UA's `[hidden] { display: none }`, so without this the closed dialog is
   still laid out — a full-viewport, z-index 3000, opacity-0 sheet that
   silently swallows every click on the page, nav included. Any fixed overlay
   toggled with the `hidden` attribute needs the same line. */
.lightbox[hidden] { display: none; }

.lightbox.is-open { opacity: 1; }

/* The one genuinely dark surface on the site: a cream scrim would leave the
   photos with nothing to sit against. */
.lightbox__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(32, 24, 10, 0.88);
}

.lightbox__stage {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.9rem;
    max-width: min(92vw, 1100px);
    max-height: 88vh;
}

.lightbox__img {
    max-width: 100%;
    max-height: 78vh;
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: var(--radius-sm);
    transform: scale(0.98);
    transition: transform 0.2s var(--ease);
}

.lightbox.is-open .lightbox__img { transform: scale(1); }

.lightbox__caption {
    margin: 0;
    color: rgba(253, 246, 234, 0.82);
    font-size: var(--step--1);
    text-align: center;
}

.lightbox__btn {
    position: absolute;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    border: 1px solid rgba(253, 246, 234, 0.28);
    border-radius: 50%;
    background: rgba(32, 24, 10, 0.55);
    color: var(--on-brand);
    font-size: 1.1rem;
    cursor: pointer;
    transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease);
}

.lightbox__btn:hover {
    background: var(--brand-ink);
    border-color: var(--brand);
}

.lightbox__btn:focus-visible { outline: 2px solid var(--brand-soft); outline-offset: 3px; }

.lightbox__btn--close { top: clamp(0.75rem, 3vw, 1.5rem); right: clamp(0.75rem, 3vw, 1.5rem); }
.lightbox__btn--prev  { left: clamp(0.5rem, 2vw, 1.5rem); top: 50%; transform: translateY(-50%); }
.lightbox__btn--next  { right: clamp(0.5rem, 2vw, 1.5rem); top: 50%; transform: translateY(-50%); }

/* Stop the page scrolling behind the dialog. */
body.has-lightbox { overflow: hidden; }

@media (max-width: 620px) {
    .lightbox__btn--prev { left: 0.5rem; }
    .lightbox__btn--next { right: 0.5rem; }
    .lightbox__img { max-height: 68vh; }
}

@media (prefers-reduced-motion: reduce) {
    .lightbox, .lightbox__img { transition: none; }
}

/* =============================================================================
   INNER PAGES  (Kontakt / Impressum / Datenschutz / 404)
   ============================================================================= */

.page-hero {
    background: linear-gradient(180deg, var(--surface-2), var(--bg));
    border-bottom: 1px solid var(--line);
    padding-block: clamp(2.5rem, 8vw, 4.5rem);
}

/* Matches the home hero: the logo's gold, with the diamond rule beneath it
   (.ornament--start, added to each inner page's markup). --step-3 is 34-52px,
   comfortably inside the large-text threshold --brand needs. */
.page-hero h1 {
    font-size: var(--step-3);
    color: var(--brand);
}
.page-hero .ornament { margin-top: 1.1rem; }
.page-hero__lead { margin-top: 1.25rem; color: var(--text-dim); max-width: 60ch; }

.contact__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 3rem);
    align-items: start;
}

.contact__map {
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--line);
    background: var(--surface);
}
.contact__map .map__frame { height: clamp(320px, 52vw, 480px); }
.contact__map figcaption {
    padding: 0.7rem 1rem;
    font-size: var(--step--1);
    color: var(--text-mute);
}
.contact__map figcaption a { text-decoration: underline; }

/* .legal is set on the same element as .container; cap the line length on the
   children so the column still lines up with the page-hero above it. */
.legal > * { max-width: 68ch; }
.legal h2 {
    font-size: var(--step-1);
    margin-top: 2.5rem;
    margin-bottom: 0.75rem;
}
.legal h2:first-child { margin-top: 0; }
.legal p { color: var(--text-dim); margin-bottom: 1rem; }
.legal__meta { margin-top: 2.5rem; font-size: var(--step--1); color: var(--text-mute); }

.error-page { min-height: 60vh; display: flex; align-items: center; }

/* =============================================================================
   FOOTER
   ============================================================================= */

.site-footer {
    background: var(--bg);
    border-top: 1px solid var(--line);
    padding-top: clamp(3rem, 8vw, 5rem);
}

/* One centred column at every width — the footer is read top-to-bottom on a
   phone and there is no reason it should become four columns on a desktop.
   Blocks are separated by the card's hairline rule rather than by whitespace
   alone, so the stack still reads as distinct sections. */
.footer-grid {
    display: grid;
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
    gap: clamp(1.75rem, 4vw, 2.25rem);
    width: min(100%, 620px);
    margin-inline: auto;
    padding-bottom: clamp(2.5rem, 6vw, 3.5rem);
}

.footer-grid > * { width: 100%; }

.footer-grid > * + * {
    border-top: 1px solid var(--line);
    padding-top: clamp(1.75rem, 4vw, 2.25rem);
}

.footer-brand img {
    height: 68px;
    width: auto;
    margin: 0 auto 1.25rem;
}

.footer-brand p {
    color: var(--text-mute);
    font-size: var(--step--1);
    max-width: 42ch;
    margin-inline: auto;
}

.footer-col h3 {
    font-family: var(--font-body);
    font-size: var(--step--1);
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--brand-ink);
    margin-bottom: 1.25rem;
}

.footer-col ul { list-style: none; padding: 0; display: grid; gap: 0.65rem; justify-items: center; }
.footer-col a { color: var(--text-dim); font-size: var(--step--1); transition: color 0.2s var(--ease); }
.footer-col a:hover { color: var(--brand-ink); }

/* Same label-over-value pattern as .info__list on the contact card. The
   icons this replaced sat to the LEFT of centred, often two-line values, so
   each row read as visually off-centre and the clock floated against nothing
   — a centred stack has no good place for a leading icon. */
.footer-info { display: grid; gap: 1.15rem; }

.footer-info dt {
    font-size: var(--step--1);
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-mute);
    margin-bottom: 0.25rem;
}

.footer-info dd {
    margin: 0;
    color: var(--text-dim);
    font-size: var(--step--1);
    line-height: 1.6;
}

.footer-social { display: flex; justify-content: center; gap: 0.75rem; }
.footer-social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: 1px solid var(--line-strong);
    border-radius: 50%;
    color: var(--text-dim);
    font-size: 1.1rem;
    transition: all 0.2s var(--ease);
}
.footer-social a:hover { background: var(--brand-press); border-color: var(--brand-press); color: var(--on-brand); transform: translateY(-2px); }

.footer-bottom {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.9rem;
    padding-block: 1.5rem;
    border-top: 1px solid var(--line);
}

.footer-legal { display: flex; align-items: center; justify-content: center; gap: 0.75rem; flex-wrap: wrap; }
.footer-legal a { color: var(--text-dim); font-size: var(--step--1); }
.footer-legal a:hover { color: var(--brand-ink); }
.footer-legal span { color: var(--text-mute); }

.footer-copy { font-size: var(--step--1); color: var(--text-mute); }
.footer-copy a { text-decoration: underline; }

/* =============================================================================
   SCROLL-REVEAL  (progressive enhancement)
   A quick GSAP opacity fade — see main.js. Elements are only hidden once
   main.js has added `.js` to <html>; if the script fails to load nothing is
   ever hidden, and main.js reveals everything when GSAP is unavailable.
   ============================================================================= */

.js [data-animate] { opacity: 0; }
.js [data-animate].is-visible { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    .js [data-animate] { opacity: 1 !important; }
    [data-hero] { opacity: 1 !important; }
    .btn:hover { transform: none; }
    * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

/* =============================================================================
   RESPONSIVE
   ============================================================================= */

@media (max-width: 960px) {
    :root { --header-h: 86px; }

    .nav-desktop { display: none; }
    .nav-toggle { display: inline-flex; }
    .brand img { height: 58px; }

    .about__grid { grid-template-columns: 1fr; text-align: center; }
    .about__text .eyebrow { margin-inline: auto; }
    .about__media { max-width: 460px; margin-inline: auto; }

    .visit__panel { grid-template-columns: 1fr; }
    .visit__media { grid-template-rows: none; grid-auto-rows: 1fr; order: 2; }
    .visit__media img { aspect-ratio: 4 / 3; height: auto; min-height: 0; }

    .contact__grid { grid-template-columns: 1fr; }

    .gallery { columns: 2; }
}

@media (max-width: 620px) {
    .about__img--2, .about__img--3 { display: none; }
    .about__img--1 { grid-row: auto; }
    .about__media {
        max-width: none;
        margin-inline: 0;
        justify-self: stretch;
        grid-template-columns: 1fr;
        grid-template-rows: 1fr;
        height: clamp(320px, 68vw, 420px);
    }

    .hero__actions .btn, .info__actions .btn { width: 100%; max-width: 320px; }
}

/* Closed-day marker from the lieferbuddy opening-hours feed (br_safe normalises
   its inline-styled red <span> to this class; inline style is CSP-blocked). */
.is-closed { color: var(--brand-ink); font-weight: 600; }

