/* ==========================================================================
   AD Studio — "Heritage & Stone"
   Architecture Design Studio Építész Iroda
   --------------------------------------------------------------------------
   A hand-written implementation of the Stitch design system.
   Editorial minimalism meets modern classicism: parchment surfaces, 1px
   drafting linework, sharp corners, high-contrast serif/sans pairing.

   Contents
     1.  Design tokens
     2.  Reset & base
     3.  Layout primitives
     4.  Typography
     5.  Buttons
     6.  Navigation
     7.  Hero
     8.  Sections & components
     9.  Project grid & cards
     10. Filters
     11. Archive (references)
     12. Forms
     13. Footer
     14. Utilities
     15. Motion, print & a11y
   ========================================================================== */

/* ==========================================================================
   1. Design tokens
   ========================================================================== */

:root {
    /* --- Palette: stone, parchment, weathered wood, antique metals ------- */
    --surface: #fbf9f4;
    --surface-dim: #dbdad5;
    --surface-bright: #fbf9f4;
    --surface-container-lowest: #ffffff;
    --surface-container-low: #f5f3ee;
    --surface-container: #f0eee9;
    --surface-container-high: #eae8e3;
    --surface-container-highest: #e4e2dd;
    --surface-variant: #e4e2dd;

    --on-surface: #1b1c19;
    --on-surface-variant: #44474a;
    --inverse-surface: #30312e;
    --inverse-on-surface: #f2f1ec;

    --outline: #75777a;
    --outline-variant: #c5c6ca;
    --surface-tint: #5d5e61;

    --primary: #17191b;
    --on-primary: #ffffff;
    --primary-container: #2c2e30;
    --on-primary-container: #949598;

    --secondary: #735a3a;
    /* antique gold */
    --on-secondary: #ffffff;
    --secondary-container: #fddab2;

    --tertiary: #3c0102;
    /* deep burgundy */
    --on-tertiary: #ffffff;

    --background: #fbf9f4;
    --on-background: #1b1c19;

    --error: #ba1a1a;

    /* --- Typography ------------------------------------------------------ */
    --font-display: "EB Garamond", "Iowan Old Style", Georgia, "Times New Roman", serif;
    --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

    /* --- Spacing scale: 8px base unit ------------------------------------ */
    --unit: 8px;
    --container-max: 1280px;
    --gutter: 32px;
    --margin-mobile: 20px;
    --margin-desktop: 64px;
    /* --section-gap is the design's py-section-gap: 128px at desktop, reduced
     to 64px on mobile (see the 768px media query). */
    --section-gap: 64px;

    /* Nav geometry. The logo is the tallest thing in the bar, so the reserved
       heights are DERIVED from its size rather than written out as literals —
       otherwise resizing the logo silently leaves `body`'s reserved padding at
       the old value and every page gains or loses a strip at the top.
       112 at rest = 24 + 64 logo + 24; 48 condensed = the logo alone. */
    --nav-pad: 24px;
    --nav-logo-size: 64px;
    --nav-logo-size-compact: 48px;
    --nav-height: calc(var(--nav-logo-size) + var(--nav-pad) * 2);
    /* The header's height once condensed on scroll (`--nav-logo-size-compact`
       with no padding). 48px is also the height of the CTA button and taller
       than the 44px menu toggle, so the logo governs the bar in both states. */
    --nav-height-compact: var(--nav-logo-size-compact);

    /* Height of a full-screen section. `svh` is the SMALL viewport height: the
       viewport as it is with the mobile browser's toolbars expanded, which is
       the state a page loads in. Crucially it is static — unlike `dvh` it does
       not follow the toolbars as they slide in and out, so a section keeps the
       height it was given on load instead of growing mid-scroll and shunting
       the content below it. See the @supports block after :root. */
    --screen-h: 100vh;

    /* --- Motion ---------------------------------------------------------- */
    --ease: cubic-bezier(0.4, 0, 0.2, 1);
    --dur: 300ms;

    /* --- Elevation: ultra-soft, offset-free lift (per design system) ----- */
    --lift: 0 0 40px rgba(27, 28, 25, 0.05);
}

/* `svh` (Safari 15.4+/Chrome 108+, 2022) is what --screen-h actually wants to
   be, but it has to be swapped in behind @supports rather than as a second
   `--screen-h` declaration. Custom properties are not validated when parsed, so
   an unsupported value would be stored happily and only fail later — when
   `var(--screen-h)` turns out invalid at computed-value time and the entire
   property is dropped. That failure mode would silently collapse every
   full-height section, so the guard is load-bearing, not decoration.

   The fallback in :root is the pre-2022 mobile behaviour, i.e. the LARGE
   viewport: sections overhang the bottom toolbar by its height until the
   toolbar hides. They still hold a fixed size, which is the part that matters.
   The alternative — the `100vh`/`100dvh` pair this replaced — fits the toolbar
   exactly but re-sizes the section on every toolbar slide, which is the jarring
   "sections change height as you scroll" bug. */
@supports (height: 100svh) {
    :root {
        --screen-h: 100svh;
    }
}

/* ==========================================================================
   2. Reset & base
   ========================================================================== */

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

/* The UA rule for [hidden] is only `display: none`, and author styles always
   beat the UA stylesheet. Any component that sets an explicit `display`
   therefore silently defeats `hidden` — which is exactly what stopped the
   project filters from hiding anything: `.project-card { display: flex }` won
   and every card stayed visible while JS reported it as hidden. `!important`
   is intentional here so `hidden` always means hidden. */
[hidden] {
    display: none !important;
}

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* offset in-page anchors so the sticky header never covers a heading */
    scroll-padding-top: calc(var(--nav-height) + 16px);
}

body {
    margin: 0;
    min-height: var(--screen-h);
    display: flex;
    flex-direction: column;
    /* The header is fixed (out of flow) so that shrinking it on scroll cannot
       reflow the page. This reserves its resting height instead. */
    padding-top: var(--nav-height);
    background-color: var(--background);
    color: var(--on-background);
    font-family: var(--font-body);
    font-size: 16px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
}

main {
    flex: 1 0 auto;
}

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

img {
    height: auto;
}

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

button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    cursor: pointer;
}

input,
textarea,
select {
    font: inherit;
    color: inherit;
}

/* Every heading is EB Garamond and carries the design's headline-md size by
   default, so a heading that has no size class can never fall back to the
   browser's own scale. Size classes override these. */
h1,
h2,
h3,
h4,
h5,
h6 {
    margin: 0;
    font-family: var(--font-display);
    font-size: 28px;
    line-height: 36px;
    font-weight: 500;
    color: var(--on-surface);
}

p {
    margin: 0;
}

ul,
ol {
    margin: 0;
    padding: 0;
    list-style: none;
}

hr {
    border: 0;
    border-top: 1px solid var(--outline-variant);
    margin: 0;
}

::selection {
    background-color: var(--secondary-container);
    color: var(--on-surface);
}

/* Visible, on-brand focus ring for keyboard users */
:focus-visible {
    outline: 2px solid var(--secondary);
    outline-offset: 3px;
}

/* ==========================================================================
   3. Layout primitives
   ========================================================================== */

/* Matches the design's `max-w-container-max mx-auto px-margin-mobile
   md:px-margin-desktop`: a 1280px box with the gutter *inside* it, so the
   readable column is 1152px at desktop. */
.container {
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--margin-mobile);
}

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

/* The design's py-24 — statistics band and CTA bands */
.section--tight {
    padding-block: 64px;
}

/* `py-24` on the statistics band — 96px at every size */
.section--stats {
    padding-block: 96px;
}

/* ---------------------------------------------------- Full-screen sections
   Editorial pages treat each major section as its own screen. `min-height`
   rather than `height`, so a section whose content is taller than the viewport
   simply grows — which also keeps flex centring safe, since the container can
   never be shorter than its content.

   The height comes from --screen-h (see :root), which is fixed at load time. */
.section--screen {
    min-height: var(--screen-h);
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.section--flush-bottom {
    padding-bottom: 0;
}

/* Heading block that opens a section, before its content */
.section-head {
    margin-bottom: 32px;
}

@media (min-width: 768px) {
    :root {
        /* The design's generous 128px vertical rhythm, desktop only */
        --section-gap: 128px;
    }

    .container {
        padding-inline: var(--margin-desktop);
    }

    .section--tight {
        padding-block: 96px;
    }

    .section-head {
        margin-bottom: 48px;
    }
}

/* Tonal layering — depth via subtle background shift, never shadows */
.section--low {
    background-color: var(--surface-container-low);
}

.section--container {
    background-color: var(--surface-container);
}

/* `border-t border-outline-variant` on a tonal band */
.section--bordered {
    border-top: 1px solid var(--outline-variant);
}

.rule {
    border-top: 1px solid var(--outline-variant);
}

/* 12-column drafting grid */
.grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: var(--gutter);
}

.grid--1 {
    grid-template-columns: minmax(0, 1fr);
}

.grid--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.grid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.grid--4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.col-full {
    grid-column: 1 / -1;
}

/* Full-bleed band that escapes the container */
.bleed {
    width: 100vw;
    margin-inline: calc(50% - 50vw);
}

/* ==========================================================================
   4. Typography
   ========================================================================== */

/* The exact type scale from the design system — fixed sizes, one breakpoint,
   shared by every page so nothing drifts between templates.
   Headings: EB Garamond. Body/UI: Inter. */

.display-lg {
    font-family: var(--font-display);
    font-size: 32px;
    /* headline-lg-mobile */
    line-height: 40px;
    font-weight: 500;
}

.headline-lg {
    font-family: var(--font-display);
    font-size: 32px;
    /* headline-lg-mobile */
    line-height: 40px;
    font-weight: 500;
}

.headline-md {
    font-family: var(--font-display);
    font-size: 28px;
    line-height: 36px;
    font-weight: 500;
}

.body-lg {
    font-size: 18px;
    line-height: 30px;
    color: var(--on-surface-variant);
    text-align: justify;
}

.body-md {
    font-size: 16px;
    line-height: 24px;
    color: var(--on-surface-variant);
    text-align: justify;
}

.caption {
    font-size: 14px;
    line-height: 20px;
    color: var(--on-surface-variant);
}

/* "Label Caps" — nav, categories, eyebrows over imagery */
.label-caps {
    font-family: var(--font-body);
    font-size: 12px;
    line-height: 16px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

/* The single desktop step for the two display sizes */
@media (min-width: 768px) {
    .display-lg {
        font-size: 64px;
        line-height: 72px;
        letter-spacing: -0.02em;
        font-weight: 400;
    }

    .headline-lg {
        font-size: 40px;
        line-height: 48px;
    }
}

.text-secondary {
    color: var(--secondary);
}

.text-primary {
    color: var(--primary);
}

.text-muted {
    color: var(--on-surface-variant);
}

.text-center {
    text-align: center;
}

.text-right {
    text-align: right;
}

@media (max-width: 767px) {
    .text-right {
        text-align: left;
    }
}

.strong {
    font-weight: 600;
    color: var(--on-surface);
}

.tracking-wide {
    letter-spacing: 0.2em;
}

/* --- Publications list -------------------------------------------------- */

/* `mt-12 pt-8 border-t` above a 12-column grid, inset to columns 2-11 */
.pubs-block {
    margin-top: 48px;
    padding-top: 32px;
    border-top: 1px solid var(--outline-variant);
}

@media (min-width: 768px) {
    .pubs-block {
        display: grid;
        grid-template-columns: repeat(12, minmax(0, 1fr));
        gap: var(--gutter);
    }

    .pubs-block>* {
        grid-column: 2 / span 10;
    }
}

.pubs-title {
    margin-bottom: 24px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.pubs li {
    padding-bottom: 8px;
    border-bottom: 1px solid var(--outline-variant);
}

.measure {
    max-width: 62ch;
}

.measure-narrow {
    max-width: 48ch;
}

/* max-w-3xl */
.measure-wide {
    max-width: 768px;
}

.pt-4 {
    padding-top: 16px;
}

/* Eyebrow: small caps label with a leading drafting tick */
.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    color: var(--secondary);
}

.eyebrow::before {
    content: "";
    width: 2rem;
    height: 1px;
    background: currentColor;
    flex: none;
}

/* Decorative divider used to open a section heading block */
.tick {
    width: 4rem;
    height: 1px;
    background: var(--outline);
}

/* ==========================================================================
   5. Buttons — sharp corners, label-caps typography
   ========================================================================== */

/* One button system for the entire site. Every button renders at exactly
   48px tall; variants change colour only.
   The base carries no border, so the solid button is 16+16 padding + 16
   line-height. Bordered variants add a 1px border and subtract it from the
   padding (15/31), which keeps their outer box identical. */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 16px 32px;
    border: 0;
    border-radius: 0;
    font-family: var(--font-body);
    font-size: 12px;
    line-height: 16px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-align: center;
    cursor: pointer;
    transition: background-color var(--dur) var(--ease),
        border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.btn svg {
    flex: none;
    width: 16px;
    height: 16px;
}

.btn-primary {
    background-color: var(--primary);
    color: var(--on-primary);
}

.btn-primary:hover {
    background-color: var(--on-surface-variant);
}

.btn-secondary {
    padding: 15px 31px;
    border: 1px solid var(--primary);
    background-color: transparent;
    color: var(--primary);
}

.btn-secondary:hover {
    background-color: var(--surface-container);
}

/* Colour-only variant for the burgundy CTA band — identical dimensions */
.btn-on-dark {
    padding: 15px 31px;
    border: 1px solid currentColor;
    background-color: transparent;
    color: var(--on-tertiary);
}

.btn-on-dark:hover {
    background-color: rgba(255, 255, 255, 0.12);
}

/* Text link with a sliding forward arrow */
.link-arrow {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--secondary);
    transition: color var(--dur) var(--ease);
}

.link-arrow svg {
    width: 1rem;
    height: 1rem;
    transition: transform var(--dur) var(--ease);
}

.link-arrow:hover {
    color: var(--primary);
    text-decoration: underline;
    text-underline-offset: 4px;
}

.link-arrow:hover svg {
    transform: translateX(4px);
}

/* ==========================================================================
   6. Navigation
   ========================================================================== */

.skip-link {
    position: absolute;
    top: -100%;
    left: var(--margin-mobile);
    z-index: 200;
    padding: 12px 20px;
    background: var(--primary);
    color: var(--on-primary);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.skip-link:focus {
    top: 0;
}

/* Fixed rather than sticky: a sticky header keeps its box in normal flow, so
   collapsing its padding would shift every following element up by 48px and
   make the page jump mid-scroll. Fixed takes it out of flow, so the bar can
   shrink smoothly while the content stays put. `body` reserves the height. */
.site-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    background-color: var(--surface);
    border-bottom: 1px solid var(--outline-variant);
}

.nav-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gutter);
    padding-block: var(--nav-pad);
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--margin-mobile);
    transition: padding-block var(--dur) var(--ease);
}

/* Collapsed state once the page is scrolled: the padding goes to 0 and the
   logo drops to its compact size, so the bar shrinks from 112px to 48px. The
   logo is the only thing that keeps the bar open, so it is the only thing that
   needs to change — everything else in the row already fits inside 48px. */
.site-header.is-compact .nav-inner {
    padding-block: 0;
}

.nav-logo {
    flex: none;
    display: block;
}

/* Larger at rest, per the brief; `height` is transitioned so the shrink is a
   smooth resize rather than a jump. `width: auto` keeps the square viewBox's
   aspect ratio, so only one dimension ever needs stating. */
.nav-logo img {
    height: var(--nav-logo-size);
    width: auto;
    transition: height var(--dur) var(--ease);
}

.site-header.is-compact .nav-logo img {
    height: var(--nav-logo-size-compact);
}

/* `hidden lg:flex ... space-x-8` — links appear at 1024px, 32px apart */
.nav-links {
    display: none;
    align-items: center;
    gap: var(--gutter);
}

.nav-links a {
    position: relative;
    color: var(--on-surface-variant);
    white-space: nowrap;
    padding-bottom: 2px;
    border-bottom: 1px solid transparent;
    transition: color var(--dur) var(--ease),
        border-color var(--dur) var(--ease);
}

.nav-links a:hover {
    color: var(--secondary);
}

/* Current page: gold text + gold underline */
.nav-links a[aria-current="page"] {
    color: var(--secondary);
    border-bottom-color: var(--secondary);
}

.nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-right: -8px;
    color: var(--on-surface);
}

.nav-toggle svg {
    width: 24px;
    height: 24px;
}

.nav-toggle .icon-close {
    display: none;
}

.nav-toggle[aria-expanded="true"] .icon-menu {
    display: none;
}

.nav-toggle[aria-expanded="true"] .icon-close {
    display: block;
}

/* --- Mobile drawer ------------------------------------------------------ */

.nav-drawer {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.5rem;
    padding: calc(var(--nav-height) + 2rem) var(--margin-mobile) 2rem;
    background-color: var(--surface);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    /* `visibility` is transitioned only so the fade-out stays visible to the end.
     Opening flips it with zero delay, which lets the drawer accept focus at
     once — a plain `visibility: visible` transition would leave it hidden for
     the whole duration and silently swallow focus(). */
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
        visibility 0s linear var(--dur);
}

.nav-drawer[data-open="true"] {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
        visibility 0s linear 0s;
}

.nav-drawer[data-open="true"] {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.nav-drawer a:not(.btn) {
    display: flex;
    align-items: baseline;
    gap: 16px;
    padding: 16px 0;
    border-bottom: 1px solid var(--outline-variant);
    font-family: var(--font-display);
    font-size: 28px;
    line-height: 36px;
    color: var(--on-surface);
}

.nav-drawer a:not(.btn)[aria-current="page"] {
    color: var(--secondary);
}

.nav-drawer a:not(.btn) span {
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.1em;
    color: var(--outline);
}

.nav-drawer .btn {
    margin-top: 1.5rem;
}

body.nav-open {
    overflow: hidden;
}

/* ==========================================================================
   7. Hero
   ========================================================================== */

.hero {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    /* The cover fills the screen below the header exactly, so its bottom edge
       lands on the bottom of the viewport with no sliver of the next section
       showing. --screen-h is the load-time height, so this does not change as
       the mobile toolbars slide away mid-scroll. */
    min-height: calc(var(--screen-h) - var(--nav-height));
    overflow: hidden;
    isolation: isolate;
}

.hero-media {
    position: absolute;
    inset: 0;
    z-index: -2;
}

.hero-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The cover is shown as shot: no tint, no blur, no colour grade. Left in place
   as the structural hook for an overlay — if the artwork is ever swapped for a
   busier or darker frame and the headline needs help, the scrim belongs here
   rather than as a filter on `.hero-media img`, which would degrade the photo
   everywhere including under the glass card. */
.hero-scrim {
    position: absolute;
    inset: 0;
    z-index: -1;
}

.hero-inner {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--margin-mobile);
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* `glass-card p-8 md:p-16 max-w-4xl` */
.glass-card {
    width: 100%;
    max-width: 600px;
    margin-inline: auto;
    padding: 32px;
    background: rgba(251, 249, 244, 0.65);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid var(--outline-variant);
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
    /* shadow-2xl */
    text-align: center;
    transition: background-color var(--dur) var(--ease),
        border-color var(--dur) var(--ease),
        box-shadow var(--dur) var(--ease),
        backdrop-filter var(--dur) var(--ease);
}

/* The pane gets out of the way and lets the cover show through untouched.
   blur(0px) rather than `none` so the backdrop-filter interpolates smoothly. */
.glass-card:hover {
    background-color: transparent;
    border-color: transparent;
    box-shadow: none;
    backdrop-filter: blur(0px);
    -webkit-backdrop-filter: blur(0px);
}

@media (min-width: 768px) {
    .hero-inner {
        padding-inline: var(--margin-desktop);
    }

    .glass-card {
        padding: 64px;
    }
}

/* Same scale as .display-lg, uppercase and bold per the mock's hero */
.hero-title {
    font-family: var(--font-display);
    font-size: 32px;
    line-height: 40px;
    font-weight: 700;
    letter-spacing: -0.025em;
    /* tracking-tight */
    text-transform: uppercase;
    color: var(--on-surface);
    margin-bottom: 24px;
}

@media (min-width: 768px) {
    .hero-title {
        font-size: 38px;
        line-height: 72px;
    }
}

.hero-subtitle {
    letter-spacing: 0.1em;
    color: var(--on-surface-variant);
    margin-bottom: 40px;
    text-transform: uppercase;
}

.hero-actions {
    display: flex;
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
}

@media (min-width: 640px) {
    .hero-actions {
        flex-direction: row;
        align-items: center;
        justify-content: center;
    }

    .hero-actions .btn {
        width: auto;
    }
}

/* --- Page banner (interior pages) --------------------------------------- */

/* Interior page shell — the design puts the container on <main> itself:
   `w-full px-margin-mobile md:px-margin-desktop max-w-container-max mx-auto
    pt-16 md:pt-32 pb-section-gap` */
.page-body {
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--margin-mobile);
    padding-top: 64px;
    padding-bottom: var(--section-gap);
}

@media (min-width: 768px) {
    .page-body {
        padding-inline: var(--margin-desktop);
        padding-top: 128px;
    }
}

/* The compact gap the listing pages open with. The design's generous header
   gap (128px) plus the filter block pushed the first project most of a screen
   down, which is poor for a page whose whole purpose is browsing the work.
   Műemlékek uses the `.page-body` shell with the modifier; Referenciák and
   Szolgáltatások opt in on their own page-level element, so all three start
   the same distance below the site header. The legal pages keep the roomier
   rhythm. */
.page-body--compact,
.section.page-top--compact,
.archive-head-band.page-top--compact {
    padding-top: 40px;
}

.page-body--compact .page-head {
    margin-bottom: 28px;
}

.page-body--compact .filters {
    margin-bottom: 32px;
}

@media (min-width: 768px) {

    .page-body--compact,
    .section.page-top--compact,
    .archive-head-band.page-top--compact {
        padding-top: 56px;
    }

    .page-body--compact .page-head {
        margin-bottom: 32px;
    }

    .page-body--compact .filters {
        margin-bottom: 40px;
    }
}

/* `mb-16 md:mb-32` */
.page-head {
    margin-bottom: 64px;
}

.page-head .display-lg,
.page-head .headline-lg {
    margin-bottom: 24px;
}

@media (min-width: 768px) {
    .page-head {
        margin-bottom: 128px;
    }
}

/* ==========================================================================
   8. Sections & components
   ========================================================================== */

/* --- Statistics --------------------------------------------------------- */

.stats {
    position: relative;
    overflow: hidden;
    border-block: 1px solid var(--outline-variant);
    background-color: var(--surface-container);
}

.stats-eyebrow {
    display: block;
    text-align: center;
    letter-spacing: 0.1em;
    margin-bottom: 64px;
    /* mb-16 */
    text-transform: uppercase;
}

/* Faint blueprint grid, mimicking drafting paper */
.stats::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0.1;
    background-image: linear-gradient(var(--outline) 1px, transparent 1px),
        linear-gradient(90deg, var(--outline) 1px, transparent 1px);
    background-size: 64px 64px;
}

.stats-grid {
    position: relative;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 32px;
    /* gap-8 */
}

.stat-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 32px;
    /* p-8 */
    background-color: var(--surface);
    border: 1px solid var(--outline-variant);
    text-align: center;
    transition: border-color var(--dur) var(--ease);
}

.stat-card:hover {
    border-color: var(--secondary);
}

.stat-value {
    display: block;
    font-family: var(--font-display);
    font-size: 40px;
    line-height: 48px;
    font-weight: 400;
    letter-spacing: -0.02em;
    color: var(--primary);
    margin-bottom: 8px;
    /* mb-2 */
}

@media (min-width: 768px) {
    .stat-value {
        font-size: 64px;
        line-height: 72px;
    }
}

.stat-label {
    color: var(--on-surface-variant);
}

/* --- Split feature block (image + copy) --------------------------------- */
/* A 12-column band that collapses to a single column on small screens.
   Children are placed with `.c-N` (span) and optional `.s-N` (start) classes;
   those only take effect from 768px up, so mobile simply stacks. */
.split {
    display: grid;
    gap: var(--gutter);
    align-items: center;
}

.split-media {
    position: relative;
    aspect-ratio: 3 / 4;
    border: 1px solid var(--outline);
    overflow: hidden;
}

.split-media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Editorial treatment: desaturated, high contrast */
    filter: grayscale(1) contrast(1.25);
}

.split-media--square {
    aspect-ratio: 1 / 1;
}

/* Companion media that fills its grid column beside copy */
.side-media {
    position: relative;
    height: 500px;
    /* h-[500px] */
    border: 1px solid var(--outline-variant);
    overflow: hidden;
}

.side-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* --- Services ----------------------------------------------------------- */

.service-grid {
    display: grid;
    gap: var(--gutter);
}

.service-card {
    display: flex;
    flex-direction: column;
    padding: 2rem;
    background-color: var(--surface);
    border: 1px solid var(--outline-variant);
    transition: background-color var(--dur) var(--ease);
}

.service-card:hover {
    background-color: var(--surface-container-highest);
}

/* The design's text-4xl service glyphs */
.service-card .icon {
    width: 36px;
    height: 36px;
    margin-bottom: 24px;
    color: var(--secondary);
}

.service-card h3 {
    margin-bottom: 1rem;
}

.service-card p {
    margin-bottom: 1.5rem;
}

/* The hairline that anchors the bottom of every card */
.service-card::after {
    content: "";
    margin-top: auto;
    height: 1px;
    background-color: var(--outline-variant);
}

/* --- Process timeline (1px rule, diamond nodes) ------------------------- */

.timeline {
    position: relative;
    padding-left: 2rem;
    border-left: 1px solid var(--outline-variant);
}

.timeline-step {
    position: relative;
    padding-bottom: 2.5rem;
}

.timeline-step:last-child {
    padding-bottom: 0;
}

/* Diamond node */
.timeline-step::before {
    content: "";
    position: absolute;
    left: calc(-2rem - 4.5px);
    top: 0.4rem;
    width: 8px;
    height: 8px;
    background-color: var(--secondary);
    transform: rotate(45deg);
}

/* --- Call-to-action band ------------------------------------------------ */

.cta-band {
    border-block: 1px solid var(--outline-variant);
    background-color: var(--tertiary);
    color: var(--on-tertiary);
}

.cta-band h2,
.cta-band p {
    color: inherit;
}

.cta-band p {
    opacity: 0.85;
}

/* ==========================================================================
   9. Project grid & cards
   ========================================================================== */

.project-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--gutter);
}

@media (min-width: 768px) {
    .project-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1024px) {
    .project-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

.project-card {
    display: flex;
    flex-direction: column;
    cursor: pointer;
}

/* Lets the whole card be one link without wrapping the grid children */
.project-link {
    display: contents;
}

/* `display: contents` cannot paint its own focus ring, so surface it on the
   media frame instead — keeps keyboard focus visible. */
.project-card:focus-within .project-media {
    outline: 2px solid var(--secondary);
    outline-offset: 3px;
}

.project-card:hover h3 {
    text-decoration: underline;
    text-underline-offset: 4px;
}

/* A card with no detail page behind it: keep the styling, drop the
   click affordances so it never looks interactive. */
.project-card--static {
    cursor: default;
}

.project-card--static:hover .project-media img {
    transform: none;
}

.project-card--static:hover h3 {
    text-decoration: none;
}

.project-media {
    position: relative;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    background-color: var(--surface-container);
    border: 1px solid var(--outline-variant);
    margin-bottom: 1rem;
}

.project-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 700ms var(--ease);
}

.project-card:hover .project-media img {
    transform: scale(1.05);
}

.project-meta {
    display: flex;
    flex-direction: column;
    gap: 4px;
    /* gap-1 */
}

.project-meta h3 {
    font-family: var(--font-display);
    font-size: 28px;
    line-height: 36px;
    font-weight: 500;
    color: var(--primary);
}

.project-meta .where {
    color: var(--on-surface-variant);
}

.project-meta .kind {
    margin-top: 8px;
    /* mt-2 */
    color: var(--secondary);
}

/* --- Featured archive entry (image + facts) ----------------------------- */

/* `py-8 px-4 md:px-6 -mx-4 md:-mx-6 mt-4 bg-surface-container-low` */
.featured {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
    margin-top: 16px;
    padding: 32px 16px;
    margin-inline: -16px;
    border-bottom: 1px solid rgba(197, 198, 202, 0.5);
    background-color: var(--surface-container-low);
}

/* Layout-transparent wrapper: rows stay direct flow children, as in the design */
.archive-rows {
    display: contents;
}

@media (min-width: 768px) {
    .featured {
        padding-inline: 24px;
        margin-inline: -24px;
    }
}

/* `grid-cols-1 sm:grid-cols-2 gap-4 mb-4` */
.featured-facts {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
    margin-bottom: 16px;
}

@media (min-width: 640px) {
    .featured-facts {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.featured-facts dt {
    display: block;
    color: var(--on-surface-variant);
    margin-bottom: 0.25rem;
}

.featured-facts dd {
    margin: 0;
    color: var(--on-surface);
}

.featured-media {
    position: relative;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background-color: var(--surface-variant);
    border: 1px solid rgba(197, 198, 202, 0.3);
}

.featured-media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 700ms var(--ease);
}

.featured:hover .featured-media img {
    transform: scale(1.05);
}

/* --- Project detail page ------------------------------------------------
   The project pages' own components all live in section 16, which is where the
   four-section template is documented. What used to be here — `.project-hero`'s
   old padding, the sticky `.detail-body` / `.detail-aside` / `.detail-main`
   two-track layout, `.detail-hero-media` and `.detail-facts` — was used only by
   the old single-screen project page and has been removed with it. */

/* `frame` / `stack` / `frame--lead` and the three gallery grids that used them
   (`.gallery-3`, `.gallery-drawings`, `.gallery-result`) were retired when the
   project pages moved to the four-section template with `.photo-row`. They were
   used only by those pages, so nothing else lost a style. The staggered
   `.gallery-3 > :nth-child(2) { margin-top: 3rem }` that lived here is exactly
   the "images jumping up and down" the replacement fixes. */

/* Technical data table */
.spec-list {
    border-top: 1px solid var(--outline-variant);
}

.spec-row {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 1rem 0;
    border-bottom: 1px solid var(--surface-variant);
}

.spec-row dt {
    color: var(--on-surface-variant);
}

.spec-row dd {
    margin: 0;
    color: var(--primary);
}

/* ==========================================================================
   10. Filters
   ========================================================================== */

.filter-group {
    display: flex;
    flex-direction: column;
    gap: 16px;
    /* gap-4 */
}

.filters {
    display: flex;
    flex-direction: column;
    gap: 24px;
    /* gap-6 */
    margin-bottom: 64px;
    /* mb-16 */
}

.filter-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    /* gap-2 */
}

/* The one sanctioned exception to the square-corner rule — the design's
   filter pills use `rounded-full`. */
.chip {
    padding: 8px 16px;
    border: 1px solid var(--outline);
    border-radius: 9999px;
    background-color: transparent;
    color: var(--primary);
    font-size: 12px;
    line-height: 16px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    transition: background-color var(--dur) var(--ease),
        color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.chip:hover {
    background-color: var(--surface-container);
}

.chip[aria-pressed="true"] {
    background-color: var(--primary);
    border-color: var(--primary);
    color: var(--on-primary);
}

.filter-empty {
    padding: 4rem 0;
    text-align: center;
    color: var(--on-surface-variant);
}

/* ==========================================================================
   11. Archive (references)
   ========================================================================== */

/* Header band: `pb-16 border-b border-outline-variant`. The top gap comes from
   `.page-top--compact` — the shared listing-page gap defined with
   `.page-body--compact` — so it matches Műemlékek and Szolgáltatások. */
.archive-head-band {
    padding-bottom: 64px;
    border-bottom: 1px solid var(--outline-variant);
}

/* List wrapper: container + `pb-section-gap` */
.archive {
    padding-bottom: var(--section-gap);
}

/* Table header — desktop only */
.archive-head {
    display: none;
    padding-block: 24px;
    border-bottom: 1px solid var(--outline-variant);
    color: var(--on-surface-variant);
    letter-spacing: 0.1em;
}

/* `mt-16 mb-8` */
.archive-year {
    margin-top: 64px;
    margin-bottom: 32px;
}

/* `border-b pb-4 mb-4` */
.archive-year h2 {
    padding-bottom: 16px;
    margin-bottom: 16px;
    border-bottom: 1px solid var(--outline-variant);
}

.archive-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
    padding: 16px 8px;
    margin-inline: -8px;
    border-bottom: 1px solid rgba(197, 198, 202, 0.5);
}

/* The settlement is the first column now: the table used to carry both a "Név"
   and a "Helyszín" column, and all 33 rows held the identical string in each,
   so the settlement is promoted and the duplicate column dropped. */
.archive-row .place {
    color: var(--on-surface);
}

.archive-row .task {
    color: var(--on-surface-variant);
}

.archive-row .lead {
    color: var(--on-surface);
}

@media (min-width: 1024px) {
    .archive-head {
        display: grid;
        grid-template-columns: repeat(12, minmax(0, 1fr));
        gap: var(--gutter);
        align-items: center;
    }

    .archive-head .c-place,
    .archive-row .place {
        grid-column: 1 / span 5;
    }

    .archive-head .c-task,
    .archive-row .task {
        grid-column: 6 / span 4;
    }

    .archive-head .c-lead,
    .archive-row .lead {
        grid-column: 10 / span 3;
    }

    .archive-row {
        grid-template-columns: repeat(12, minmax(0, 1fr));
        gap: var(--gutter);
        align-items: center;
    }
}

/* ==========================================================================
   12. Forms
   ========================================================================== */

.form-panel {
    padding: 32px;
    background-color: var(--surface-container-low);
    border: 1px solid var(--outline-variant);
}

@media (min-width: 768px) {
    .form-panel {
        padding: 48px;
    }
}

.form {
    display: flex;
    flex-direction: column;
    gap: 32px;
}

.form>.btn {
    align-self: flex-start;
}

/* Bottom-border-only fields, label floats on focus/fill */
.field {
    position: relative;
}

.field input,
.field textarea {
    width: 100%;
    padding: 8px 0;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--outline);
    border-radius: 0;
    font-size: 16px;
    line-height: 24px;
    color: var(--on-surface);
    transition: border-color var(--dur) var(--ease);
}

.field textarea {
    resize: vertical;
    min-height: 112px;
}

.field input:focus,
.field textarea:focus {
    outline: none;
    border-bottom-color: var(--primary);
}

.field label {
    position: absolute;
    left: 0;
    top: -16px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--on-surface-variant);
    pointer-events: none;
    transition: top var(--dur) var(--ease), font-size var(--dur) var(--ease),
        letter-spacing var(--dur) var(--ease);
}

/* Collapse the label down into the field while empty and unfocused */
.field input:placeholder-shown+label,
.field textarea:placeholder-shown+label {
    top: 8px;
    font-size: 16px;
    font-weight: 400;
    letter-spacing: normal;
    text-transform: none;
}

.field input:focus+label,
.field textarea:focus+label {
    top: -16px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.field .hint {
    display: block;
    margin-top: 8px;
    color: var(--error);
    font-size: 12px;
    line-height: 16px;
}

/* Call-back opt-in, and the phone field it reveals. The field starts hidden
   and is shown while the box is ticked: the script toggles [hidden], and this
   rule covers the case where the script never runs. */
.checkbox-row {
    display: flex;
    align-items: center;
    gap: 12px;
}

.checkbox-row input[type="checkbox"] {
    flex: none;
    width: 18px;
    height: 18px;
    margin: 0;
    accent-color: var(--primary);
    cursor: pointer;
}

.checkbox-row label {
    font-size: 16px;
    line-height: 24px;
    color: var(--on-surface);
    cursor: pointer;
}

.field--callback {
    display: none;
}

.form:has(#visszahivas:checked) .field--callback {
    display: block;
}

/* Honeypot bait (see kapcsolat.html). A real field in the DOM, but off-screen
   and out of the accessibility tree, so only a bot ever fills it in. */
.hp-field {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Send status under the submit button. Colour is never the only signal — the
   text always says what happened. */
.form-status[data-status="ok"] {
    color: var(--secondary);
}

.form-status[data-status="error"] {
    color: var(--error);
}

/* --- Contact page ------------------------------------------------------- */

/* `text-center mb-24` with a 64x1px rule 32px below the title */
.page-title {
    text-align: center;
    margin-bottom: 48px;
}

.page-title-rule {
    width: 64px;
    height: 1px;
    margin: 32px auto 0;
    background-color: var(--outline-variant);
}

/* `grid-cols-1 md:grid-cols-2 gap-gutter md:gap-24` */
.contact-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--gutter);
    /* No bottom margin: it used to be var(--section-gap) to separate the form
       from the map, but the section boundary does that now, and the 128px was
       pushing the block past a laptop viewport. */
}

.contact-details {
    display: flex;
    flex-direction: column;
    gap: 32px;
    /* gap-8 */
}

.contact-list {
    display: flex;
    flex-direction: column;
    gap: 24px;
    /* gap-6 */
}

.form-submit {
    margin-top: 16px;
    /* mt-4 */
}

@media (min-width: 768px) {
    .contact-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 96px;
        /* md:gap-24 */
    }
}

/* --- Contact details ---------------------------------------------------- */

.contact-item {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
}

.contact-item .icon {
    flex: none;
    width: 1.5rem;
    height: 1.5rem;
    margin-top: 0.15rem;
    color: var(--outline);
}

.contact-item dt {
    color: var(--on-surface-variant);
    margin-bottom: 0.25rem;
}

.contact-item dd {
    margin: 0;
    color: var(--on-surface);
}

.contact-item dd a:hover {
    color: var(--secondary);
}

/* --- Location map -------------------------------------------------------
   A live map inside `.map-frame` (see section 19). The band is a full-bleed
   tonal strip that holds the map to the content column. */

.map-band {
    position: relative;
    border-block: 1px solid var(--outline-variant);
    overflow: hidden;
    /* The reference site's map band: the tonal strip runs full-bleed, but the
       map inside it is held to the content column (the `.container` in
       kapcsolat.html), so it lines up with the form and heading above it
       instead of meeting the page edge. The bottom gap keeps the frame's own
       border clear of the band's bottom rule. */
    padding-bottom: 48px;
    /* The map's dominant tone, so there is no flash while the embed loads */
    background-color: var(--surface-container);
}

.map-credit {
    padding-block: 12px;
    color: var(--outline);
}

.map-credit a {
    color: var(--secondary);
    text-decoration: underline;
}

/* The contact details + form fill their own screen. Section--screen centres
   vertically; this keeps the padding modest so the whole form clears a laptop
   viewport instead of needing a scroll for one field. */
.contact-screen {
    padding-block: 32px;
}

/* The map keeps its own band, but no longer a full screen of its own: it now
   sits under the form at its natural height. */
.map-screen {
    display: flex;
    flex-direction: column;
}

.map-screen .map-band {
    border-top: 0;
}

.map-screen .map-credit {
    flex: none;
    margin: 0;
}

/* --- Legal pages (adatvédelem, felhasználási feltételek) ---------------- */

/* Comfortable reading column: the design's measure, with section rhythm. */
.legal {
    max-width: 768px;
}

.legal-section {
    padding-top: 32px;
    margin-top: 32px;
    border-top: 1px solid var(--outline-variant);
}

.legal-section h2 {
    margin-bottom: 16px;
}

.legal-section>.body-md+.body-md,
.legal-section>.body-md+.legal-list,
.legal-section>.legal-list+.body-md {
    margin-top: 16px;
}

.legal-list {
    padding-left: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* Restore list markers for prose lists only (the reset removes them) */
.legal-list li {
    position: relative;
    padding-left: 24px;
}

.legal-list li::before {
    content: "";
    position: absolute;
    left: 6px;
    top: 0.65em;
    width: 6px;
    height: 6px;
    background-color: var(--secondary);
    transform: rotate(45deg);
    /* the design's diamond node */
}

.legal-note {
    padding: 16px;
    background-color: var(--surface-container-low);
    border: 1px solid var(--outline-variant);
    color: var(--on-surface-variant);
    font-size: 14px;
    line-height: 20px;
}

.legal-back {
    padding-top: 32px;
    margin-top: 32px;
    border-top: 1px solid var(--outline-variant);
}

/* ==========================================================================
   13. Footer
   ========================================================================== */

.site-footer {
    margin-top: var(--section-gap);
    background-color: var(--surface-container);
    border-top: 1px solid var(--outline-variant);
}

.footer-inner {
    display: flex;
    flex-direction: column;
    gap: var(--gutter);
    padding-block: var(--section-gap);
    /* The design uses px-margin-desktop with no mobile variant */
    padding-inline: var(--margin-desktop);
    max-width: var(--container-max);
    margin-inline: auto;
    width: 100%;
}

@media (min-width: 768px) {
    .footer-inner {
        flex-direction: row;
        justify-content: space-between;
        align-items: flex-start;
    }
}

.footer-brand {
    font-family: var(--font-display);
    font-size: 28px;
    line-height: 36px;
    font-weight: 500;
    color: var(--on-surface);
    margin-bottom: 1rem;
}

.footer-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
    /* gap-6 */
}

.footer-nav a {
    color: var(--on-surface-variant);
    transition: color 200ms var(--ease);
}

.footer-nav a:hover {
    color: var(--on-surface);
}

.footer-nav--center {
    justify-content: center;
}

.footer-legal {
    padding-top: 1.5rem;
    border-top: 1px solid var(--outline-variant);
    color: var(--outline);
}

/* ==========================================================================
   14. Utilities
   ========================================================================== */

address {
    font-style: normal;
}

/* Inline SVG sprite: kept in the document so <use> can resolve the symbols,
   but taken out of layout and the accessibility tree. */
.svg-sprite {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.stack>*+* {
    margin-top: 1.5rem;
}

.stack-sm>*+* {
    margin-top: 0.75rem;
}

.stack-lg>*+* {
    margin-top: 3rem;
}

.mt-2 {
    margin-top: 0.5rem;
}

.mt-3 {
    margin-top: 0.75rem;
}

.mt-4 {
    margin-top: 1rem;
}

.mt-6 {
    margin-top: 1.5rem;
}

.mt-8 {
    margin-top: 2rem;
}

.mt-12 {
    margin-top: 3rem;
}

.mt-16 {
    margin-top: 4rem;
}

.mt-24 {
    margin-top: 6rem;
}

.mx-auto {
    margin-inline: auto;
}

/* Margin scale matching the design's Tailwind steps */
.mb-2 {
    margin-bottom: 8px;
}

.mb-4 {
    margin-bottom: 16px;
}

.mb-6 {
    margin-bottom: 24px;
}

.mb-8 {
    margin-bottom: 32px;
}

.mb-16 {
    margin-bottom: 64px;
}

/* Vertical rhythm between stacked siblings */
.space-y-3>*+* {
    margin-top: 12px;
}

.space-y-6>*+* {
    margin-top: 24px;
}

.space-y-8>*+* {
    margin-top: 32px;
}

.pt-8 {
    padding-top: 2rem;
}

.pb-8 {
    padding-bottom: 2rem;
}

/* ==========================================================================
   15. Motion, print & a11y
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

@media print {

    .site-header,
    .nav-drawer,
    .site-footer,
    .map-band {
        display: none;
    }

    body {
        background: #fff;
        /* The header is hidden when printing, so reclaim its reserved space */
        padding-top: 0;
    }

    /* Full-screen sections make no sense on paper */
    .section--screen {
        min-height: 0;
        display: block;
    }
}

/* ==========================================================================
   Responsive — mobile-first enlargement
   ========================================================================== */

/* ------------------------------------------- >= 640px : large phones / sm */
@media (min-width: 640px) {
    .hero-actions {
        flex-direction: row;
        justify-content: center;
        align-items: center;
    }

    .hero-actions .btn {
        width: auto;
    }

    .project-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .featured-facts {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* ------------------------------------------------- >= 768px : tablets / md */
@media (min-width: 768px) {
    .grid--md-2 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .stats-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 3rem;
    }

    /* Stagger alternate stat cards for a drafting-table rhythm */
    .stat-card:nth-child(even) {
        transform: translateY(2rem);
    }

    /* Spans mirror Tailwind's col-span-N, which emits `span N / span N` — the span
     is applied to BOTH edges so that a later `.s-N` start override replaces only
     the start edge and the width survives. The bare `span N` shorthand sets
     grid-column-end to auto, so adding a start collapsed the item to ONE track
     (a ~4% sliver instead of a 5/12 column).
     Scoped with :not(.split--lg) because that variant is still single-column at
     this width, where a span would create implicit tracks. */
    .split:not(.split--lg) {
        grid-template-columns: repeat(12, minmax(0, 1fr));
    }

    .split:not(.split--lg)>.c-4 {
        grid-column: span 4 / span 4;
    }

    .split:not(.split--lg)>.c-5 {
        grid-column: span 5 / span 5;
    }

    .split:not(.split--lg)>.c-6 {
        grid-column: span 6 / span 6;
    }

    .split:not(.split--lg)>.c-7 {
        grid-column: span 7 / span 7;
    }

    .split:not(.split--lg)>.c-8 {
        grid-column: span 8 / span 8;
    }

    .split:not(.split--lg)>.c-10 {
        grid-column: span 10 / span 10;
    }

    .split:not(.split--lg)>.c-12 {
        grid-column: span 12 / span 12;
    }

    /* Column starts — declared after the spans so they win the start edge only */
    .split:not(.split--lg)>.s-2 {
        grid-column-start: 2;
    }

    .split:not(.split--lg)>.s-7 {
        grid-column-start: 7;
    }

    .split:not(.split--lg)>.s-8 {
        grid-column-start: 8;
    }

    .split:not(.split--lg)>.s-9 {
        grid-column-start: 9;
    }

    .service-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .spec-row {
        flex-direction: row;
        align-items: baseline;
        gap: var(--gutter);
    }

    .spec-row dt {
        flex: 0 0 33.333%;
    }

    .spec-row dd {
        flex: 1;
    }

    .filter-group {
        flex-direction: row;
        align-items: center;
        gap: 1rem;
    }

    .filter-group>.label-caps {
        flex: none;
        min-width: 12rem;
    }

    .contact-item {
        align-items: center;
    }
}

/* The homepage statement block is `lg:col-*` in the design rather than `md:*`,
   so it becomes two columns only from 1024px, and the spans are re-declared here
   because they are scoped to :not(.split--lg) at 768px. */
@media (min-width: 1024px) {
    .split--lg {
        grid-template-columns: repeat(12, minmax(0, 1fr));
    }

    .split--lg>.c-5 {
        grid-column: span 5 / span 5;
    }

    .split--lg>.c-6 {
        grid-column: span 6 / span 6;
    }

    .split--lg>.c-7 {
        grid-column: span 7 / span 7;
    }

    .split--lg>.s-7 {
        grid-column-start: 7;
    }

    .split--lg>.s-9 {
        grid-column-start: 9;
    }

    /* `lg:mt-16` */
    .split--lg>.offset-top {
        margin-top: 64px;
    }
}

/* Links appear at 1024px, as the design's `hidden lg:flex` specifies. The
   design's own spacing (32px link gap, 64px page margin) genuinely does not
   fit at 1024px — six links plus the CTA come to roughly 1027px of content —
   so the gap and margin tighten across 1024-1279px only, and the full design
   rhythm returns from 1280px. Type and button sizes never change. */
@media (min-width: 1024px) and (max-width: 1279.98px) {
    .nav-inner {
        padding-inline: 48px;
        gap: 16px;
    }

    .nav-links {
        gap: 16px;
    }
}

/* -------------------------------------------- >= 1024px : desktop / lg */
@media (min-width: 1024px) {

    /* Links appear here. */
    .nav-links {
        display: flex;
    }

    .nav-toggle {
        display: none;
    }

    .nav-drawer {
        display: none;
    }

    .project-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .service-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    /* Archive column placement now lives with the archive section styles. */

    .featured {
        grid-template-columns: repeat(12, minmax(0, 1fr));
        align-items: center;
    }

    .featured-body {
        grid-column: 1 / span 6;
    }

    .featured-media {
        grid-column: 7 / span 6;
    }
}

/* ------------------------------------------------ >= 1280px : wide screens */
@media (min-width: 1280px) {

    /* Room for the design's full nav rhythm, and the container gutter */
    .nav-inner {
        padding-inline: var(--margin-desktop);
    }

    .nav-links {
        gap: var(--gutter);
    }

    .stat-card:nth-child(even) {
        transform: translateY(2rem);
    }
}

/* ==========================================================================
   16. Project detail view
   --------------------------------------------------------------------------
   Every one of the seven project pages is built from this template, in this
   order, with no page-specific variation. That is the point: the visitor
   learns the structure once, and a building can be read at a glance.

   FOUR SECTIONS, EACH ONE PAGE TALL:

     1. .project-overview   lead plate, title, Történeti háttér, photo gallery
     2. .photo-section      Kiindulási állapot
     3. .photo-section      Megvalósult / tervezett állapot
     4. .spec-section       Műszaki adatok

   Sections 2 and 3 are each ONE straight row of equal tiles. `grid-auto-flow:
   column` places every tile in its own equal-width column and never wraps, so
   tiles cannot end up at different heights — which is what the previous
   staggered grid did, by pushing its middle image 3rem down.

   On heights: sections use `var(--screen-h)` (the frozen small-viewport height)
   rather than `100lvh`. `lvh` is the LARGE viewport — the size with mobile
   toolbars hidden — so a section sized to it is taller than the screen on load
   and its bottom edge sits behind the toolbar. `svh` is the height the page
   actually has when it loads, so "one page tall" is true from the first frame,
   and it is static, so nothing resizes as the toolbars slide away.

   Section 1 subtracts the header because it is the first thing under it; the
   header is fixed, so the remaining three are measured from the viewport itself.
   ========================================================================== */

/* --- 1. Overview: plate, title, history, the whole photo set -------------- */

.project-overview {
    display: flex;
    /* Fills the screen under the header; grows only if the content needs it. */
    min-height: calc(var(--screen-h) - var(--nav-height));
    padding-block: 24px;
}

.project-overview .container {
    /* Must be able to stretch AND shrink. Without `flex: 1 1 auto` the container
       sizes to its content, the section grows past one screen, and the history
       pane never gets a definite height to scroll inside — which is exactly what
       happened first time round (`historyScrolls: false` on every page). */
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-height: 0;
}

/* A DEFINITE height, not `min-height`, from the point where the layout is two
   columns. This is what makes one page-tall true: the history is the only
   flexible child, so it absorbs the leftover space and scrolls if the text is
   longer than the room, while everything else keeps its size.

   Below 1024px the grid stacks, so the section legitimately needs more than a
   phone screen and `min-height` alone lets it grow — clipping the text on a
   phone would be far worse than scrolling the page. */
@media (min-width: 1024px) {
    .project-overview {
        height: calc(var(--screen-h) - var(--nav-height));
    }
}

.project-back {
    flex: none;
    margin: 0;
}

/* One column below 1024px, plate beside the text above it. The plate takes
   `1fr` of the leftover height and crops its image rather than dictating its
   own size — that is what lets the whole block settle onto one screen. */
.project-overview-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
    flex: 1 1 auto;
    min-height: 0;
}

@media (min-width: 1024px) {
    .project-overview-grid {
        grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
        gap: 40px;
    }
}

/* `min-height` is a floor, not a target: on a short phone the plate shrinks to
   it and the section grows past the viewport instead of crushing the image. */
.project-lead {
    position: relative;
    display: block;
    flex: 1 1 auto;
    min-height: 200px;
    padding: 0;
    border: 1px solid var(--outline-variant);
    background-color: var(--surface-container);
    overflow: hidden;
    cursor: zoom-in;
}

.project-lead img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.project-intro {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.project-place {
    flex: none;
    color: var(--secondary);
    margin-bottom: 8px;
}

/* Uses .display-lg's mobile size down to 1024px, where the intro column has
   room for the full 64px step. */
.project-name {
    font-family: var(--font-display);
    font-size: 30px;
    line-height: 38px;
    font-weight: 700;
    letter-spacing: -0.025em;
    text-transform: uppercase;
    color: var(--on-surface);
    margin: 8px 0 12px;
    /* A single settlement name in uppercase display type can be wider than a
       phone column, and one word cannot wrap: "Szabolcsveresmarti" measures
       329px in a 305px column at this size, which pushed the whole document 4px
       wider than the viewport. Hyphenation breaks it the way Hungarian does
       ("Szabolcs-veresmarti"); break-word is the backstop for browsers without
       a Hungarian hyphenation dictionary, where the alternative is a
       horizontally scrolling page. */
    hyphens: auto;
    overflow-wrap: break-word;
}

@media (min-width: 1024px) {
    .project-name {
        font-size: 44px;
        line-height: 52px;
    }
}

/* Sits above the history text, in the same small-caps style the strip uses, so
   the section's own label does not compete with the project title. */
.project-history-title {
    flex: none;
    color: var(--outline);
    margin-bottom: 10px;
}

/* The one region on the page allowed to scroll.

   A page-high section cannot also show 900+ characters of architectural history
   at a readable size on a short laptop screen, and the alternatives are both
   worse: truncating the client's own text, or letting the section grow past one
   screen and break the four-page-height structure. So the history gets a
   bounded pane. On a tall viewport the text fits and no scrollbar appears at
   all — it only shows up when the content genuinely exceeds the room. */
.project-history {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-right: 8px;
}

.project-history p+p {
    margin-top: 10px;
}

/* --- The photograph strip ------------------------------------------------ */

.project-strip {
    flex: none;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.project-strip-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    color: var(--outline);
}

.project-strip-grid {
    display: grid;
    /* Fixed 6 columns rather than auto-fit: every page must break identically,
       and with 5-9 photos per set that gives one or two tidy rows. */
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.project-strip-grid a {
    display: block;
    aspect-ratio: 1 / 1;
    border: 1px solid var(--outline-variant);
    overflow: hidden;
    cursor: zoom-in;
    transition: border-color var(--dur) var(--ease);
}

.project-strip-grid a:hover,
.project-strip-grid a:focus-visible {
    border-color: var(--secondary);
}

.project-strip-grid img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 500ms var(--ease);
}

.project-strip-grid a:hover img {
    transform: scale(1.06);
}

@media (min-width: 768px) {
    .project-strip-grid {
        grid-template-columns: repeat(9, minmax(0, 1fr));
    }
}

/* --- 2 & 3. State sections -----------------------------------------------
   Kiindulási állapot and Megvalósult / tervezett állapot. Identical geometry:
   a heading over one straight row of equal tiles. */

.photo-section {
    display: flex;
    flex-direction: column;
    min-height: var(--screen-h);
    padding-block: 24px;
}

.photo-section .container {
    display: flex;
    flex-direction: column;
    gap: 20px;
    flex: 1 1 auto;
    min-height: 0;
}

.photo-section-title {
    flex: none;
    text-align: center;
}

/* ONE row, never wrapped: `grid-auto-flow: column` gives every tile its own
   equal-width column and `grid-auto-columns` sizes them identically, so the row
   is a flat band whatever the count. `align-content: center` centres it in the
   section rather than leaving it pinned to the heading. */
.photo-row {
    flex: 1 1 auto;
    min-height: 0;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 12px;
    align-content: center;
}

.photo-row figure {
    margin: 0;
    width: 100%;
    /* Portrait tiles, because the sets are mostly portrait photographs and
       scanned drawings. The exact ratio matters less than every tile in the row
       sharing it — that is what keeps the row a straight line. */
    aspect-ratio: 3 / 4;
    /* A short viewport would otherwise make a 2-tile row taller than the screen
       and push the section past one page. Clamping the height widens the tile
       slightly instead, and `object-fit: cover` absorbs the difference. */
    max-height: calc(var(--screen-h) - 120px);
    border: 1px solid var(--outline-variant);
    background-color: var(--surface-container);
    overflow: hidden;
}

.photo-row figure a {
    display: block;
    width: 100%;
    height: 100%;
    cursor: zoom-in;
}

.photo-row img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 500ms var(--ease);
}

.photo-row figure:hover img,
.photo-row figure:focus-within img {
    transform: scale(1.03);
}

/* A lone photograph would be a very tall sliver at 3/4, so it reads as a plate
   instead. `:only-child` avoids needing a count class for this one case. */
.photo-row figure:only-child {
    justify-self: center;
    max-width: 720px;
    aspect-ratio: 16 / 10;
}

/* Below 768px a full row of five tiles would be ~60px wide each, so the row
   wraps to two columns. Each wrapped row is still a straight line. */
@media (max-width: 767.98px) {
    .photo-row {
        grid-auto-flow: row;
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .photo-row figure {
        aspect-ratio: 1 / 1;
        max-height: none;
    }

    .photo-row figure:only-child {
        max-width: none;
        aspect-ratio: 4 / 3;
    }
}

/* --- 4. Műszaki adatok --------------------------------------------------- */

.spec-section {
    display: flex;
    flex-direction: column;
    min-height: var(--screen-h);
    padding-block: 24px;
}

/* Centred as a block, so the table sits in the middle of its own page rather
   than hanging off the top of it. */
.spec-section .container {
    display: flex;
    flex-direction: column;
    justify-content: center;
    flex: 1 1 auto;
    min-height: 0;
}

/* ==========================================================================
   17. Lightbox (Fancybox) — brand overrides
   --------------------------------------------------------------------------
   Loaded on every page. Fancybox is a third-party script but not a
   third-party request: it is vendored under assets/ and served from this
   origin, so no visitor data leaves the site when it runs.
   ========================================================================== */

.fancybox__backdrop {
    background: rgba(23, 25, 27, 0.94);
}

.fancybox__caption {
    font-family: var(--font-body);
    color: var(--inverse-on-surface);
    padding-block: 12px 4px;
}

/* Fancybox's default caption is a flat line; the site sets its titles in the
   display serif elsewhere, so the lightbox follows. */
.fancybox__caption .fancybox-caption-title,
.fancybox__caption h3 {
    font-family: var(--font-display);
    color: var(--inverse-on-surface);
}

.fancybox__thumbs .carousel__slide {
    border: 1px solid transparent;
}

.fancybox__thumbs .carousel__slide.is-nav-selected {
    border-color: var(--secondary);
}

.fancybox__toolbar,
.fancybox__nav {
    --f-button-color: var(--inverse-on-surface);
    --f-button-hover-color: #ffffff;
}

.fancybox__button:focus-visible,
.fancybox__nav button:focus-visible {
    outline: 2px solid var(--secondary-container);
    outline-offset: 2px;
}

/* Fancybox's default theme colour is a cyan; the accent here is the studio's
   antique gold. */
.fancybox__carousel .fancybox__slide.has-image>.fancybox__content {
    background-color: transparent;
}

/* An inline image that opens in the lightbox. The anchor must not disturb the
   box its image was already sitting in: `display: block` removes the inline
   baseline gap that would otherwise add a few pixels of stray height below
   every wrapped photograph. */
.lightbox-link {
    display: block;
    cursor: zoom-in;
}

/* Containers whose image is `position: absolute; inset: 0` (a fixed
   aspect-ratio or height box with `object-fit: cover`). An in-flow anchor
   wrapped around such an image collapses to zero height, because the image is
   out of flow and contributes no size — the anchor would then have no clickable
   area of its own. Matching the image's own geometry makes the anchor cover the
   box exactly, so the whole photograph is the click target, and the absolutely
   positioned image inside it still resolves against a positioned ancestor that
   fills the container. */
.featured-media .lightbox-link,
.split-media .lightbox-link {
    position: absolute;
    inset: 0;
}

.lightbox-link img {
    transition: filter var(--dur) var(--ease);
}

.lightbox-link:hover img,
.lightbox-link:focus-visible img {
    filter: brightness(1.04) saturate(1.05);
}

/* ==========================================================================
   18. Glossary / explanatory boxes
   ========================================================================== */

/* An editorial pull-out: parchment sheet, drafting rule down the left edge,
   term and plain-Hungarian definition. Used on the services page to explain
   the intervention vocabulary, which is otherwise jargon to a first-time
   visitor.
   Used on: egyuttmukodes.html */
.glossary {
    border: 1px solid var(--outline-variant);
    background-color: var(--surface-container-lowest);
    padding: 28px;
}

@media (min-width: 768px) {
    .glossary {
        padding: 40px;
    }
}

.glossary-head {
    border-bottom: 1px solid var(--outline-variant);
    padding-bottom: 16px;
    margin-bottom: 24px;
}

.glossary-title {
    font-family: var(--font-display);
    font-size: 24px;
    line-height: 32px;
    font-weight: 600;
    color: var(--on-surface);
    margin-bottom: 6px;
}

.glossary-list {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
    margin: 0;
}

.glossary-item dt {
    font-family: var(--font-display);
    font-size: 20px;
    line-height: 26px;
    font-weight: 600;
    color: var(--tertiary);
    border-left: 3px solid var(--secondary);
    padding-left: 12px;
    margin-bottom: 8px;
}

.glossary-item dd {
    margin: 0;
    padding-left: 15px;
    color: var(--on-surface-variant);
}

@media (min-width: 768px) {
    .glossary-list {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 28px 40px;
    }
}

@media (min-width: 1280px) {
    .glossary-list {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* ==========================================================================
   19. Location map (Leaflet over OpenFreeMap "Positron")
   --------------------------------------------------------------------------
   Leaflet drives the map; the Positron vector style is drawn by MapLibre
   through leaflet-maplibre-gl. No API key. The brand grade lives in the style
   (assets/js/openfreemap-style.js), not in a CSS filter, so water, roads and
   labels each get their own place on the ramp and the DOM pin and controls keep
   their real colours.

   The banner is held to the content column and keeps a 21:9 proportion; the
   tonal `.map-band` behind it stays full-bleed.
   ========================================================================== */

.map-frame {
    position: relative;
    width: 100%;
    /* 21:9 banner; min-height keeps it usable on phones, where 21:9 would be a
       letterbox strip. */
    aspect-ratio: 21 / 9;
    min-height: 300px;
    border: 1px solid var(--outline-variant);
    background-color: var(--surface-container-high);
    overflow: hidden;
}

@media (min-width: 768px) {
    .map-frame {
        min-height: 380px;
    }
}

.map-canvas {
    width: 100%;
    height: 100%;
    /* Visible while Leaflet loads, and if it never does this tinted plate is
       what the visitor sees rather than a white void. */
    background-color: var(--surface-container-high);
    /* No cursor here: Leaflet sets `grab` on the container and switches it to
       `grabbing` while dragging, which is the honest affordance for a pannable
       map. A `zoom-in` or `pointer` override would fight that. */
}

/* The map container IS the Leaflet container (`L.map` is handed `.map-canvas`),
   so this is the same element rather than a descendant. */
.map-canvas.leaflet-container {
    font-family: var(--font-body);
    background: transparent;
}

/* The MapLibre bridge renders into Leaflet's tile pane. It is non-interactive
   (Leaflet owns every gesture), so it is taken out of hit-testing. */
.map-canvas .leaflet-gl-layer,
.map-canvas .leaflet-gl-layer canvas {
    pointer-events: none;
}

/* Leaflet's chrome is a saturated blue by default; these are the brand's
   charcoal and gold. */
.map-canvas .leaflet-bar {
    border: 1px solid var(--outline-variant);
    box-shadow: 0 2px 8px rgba(27, 28, 25, 0.12);
}

.map-canvas .leaflet-bar a {
    width: 32px;
    height: 32px;
    line-height: 30px;
    background-color: var(--surface);
    color: var(--on-surface);
    border-bottom-color: var(--outline-variant);
}

.map-canvas .leaflet-bar a:hover,
.map-canvas .leaflet-bar a:focus-visible {
    background-color: var(--surface-container-highest);
    color: var(--tertiary);
}

.map-canvas .leaflet-bar a:focus-visible {
    outline: 2px solid var(--secondary);
    outline-offset: 1px;
}

.map-canvas .leaflet-control-attribution {
    background: rgba(251, 249, 244, 0.9);
    color: var(--on-surface-variant);
    font-size: 10px;
    line-height: 1.4;
    padding: 2px 6px;
}

.map-canvas .leaflet-control-attribution a {
    color: var(--secondary);
    text-decoration: underline;
}

/* Leaflet's default markers are PNGs fetched from its own folder, which this
   repository has no copy of — and even if it did, they are a blue teardrop. The
   pin is a divIcon with inline SVG instead, so it needs no asset request and can
   carry the studio's own colours.

   `anchor` is set to the pin's tip in JS, so this element must not try to
   reposition itself. */
.map-pin {
    position: relative;
    display: block;
    width: 30px;
    height: 38px;
    filter: drop-shadow(0 2px 4px rgba(27, 28, 25, 0.4));
}

.map-pin svg {
    display: block;
    width: 100%;
    height: 100%;
}

/* A slow halo on the ground point, so the pin reads as "here" rather than as a
   sticker on the map. Anchored to the pin's tip. */
.map-pin::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -3px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--tertiary);
    opacity: 0.25;
    transform: translate(-50%, 50%);
    animation: pin-pulse 2.6s var(--ease) infinite;
}

@keyframes pin-pulse {

    0%,
    100% {
        transform: translate(-50%, 50%) scale(0.75);
        opacity: 0.25;
    }

    50% {
        transform: translate(-50%, 50%) scale(1.5);
        opacity: 0.05;
    }
}

/* Shown until the map paints, and left visible if it never does - no WebGL, a
   failed script, or JavaScript off. z-index sits below `.map-hint` (500) so the
   "open in Google Maps" chip still wins the bottom-left corner. */
.map-fallback {
    position: absolute;
    inset: 0;
    z-index: 400;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 24px;
    text-align: center;
    background-color: var(--surface-container);
}

.map-fallback-pin {
    width: 30px;
    height: 40px;
    filter: drop-shadow(0 2px 4px rgba(27, 28, 25, 0.25));
}

.map-fallback-address {
    margin: 0;
    color: var(--on-surface-variant);
    line-height: 1.7;
}

.map-hint {
    position: absolute;
    left: 12px;
    bottom: 12px;
    z-index: 500;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    /* Pill-shaped, matching the reference site's chip, with the same soft lift
       so it sits above the map rather than dissolving into it. */
    border-radius: 9999px;
    padding: 8px 14px;
    background: rgba(251, 249, 244, 0.95);
    border: 1px solid var(--outline-variant);
    box-shadow: 0 10px 22px -10px rgba(27, 28, 25, 0.45);
    color: var(--on-surface);
    transition: background-color var(--dur) var(--ease),
        border-color var(--dur) var(--ease);
}

.map-hint:hover,
.map-hint:focus-visible {
    background: var(--surface-container-highest);
    border-color: var(--secondary);
}

.map-hint .icon {
    width: 14px;
    height: 14px;
    color: var(--secondary);
}

/* ==========================================================================
   20. Filter sub-group reveal
   ========================================================================== */

/* The denomination row only means something while a church type is selected.
   Kept in the DOM and marked `hidden` rather than removed, so the filter JS
   reads one consistent set of groups whatever the visitor does.
   Used on: muemlekek.html */
.filter-group[data-filter-dependent][hidden] {
    display: none !important;
}

/* ==========================================================================
   21. Section head spacing
   --------------------------------------------------------------------------
   `.page-head` sets a 32px bottom margin, which was sized for a page that
   opened straight into prose. On muemlekek the filter bar now follows it,
   and the doubled gap pushed the first project row below the fold.
   ========================================================================== */

.page-head--tight {
    margin-bottom: 16px;
}