:root {
  --paper-card: #f4f4f2;
  --ink: #26221e;
  --ink-soft: #8a8175;
  --line: #e8e2d8;
  --brass: #26221e; /* accent neutralized to ink (user: no brown) */
  --wa: #1fa855;
  --font-text: "Golos Text", system-ui, sans-serif;
  --gutter: clamp(1rem, 2.5vw, 2.25rem);
  /* Shared rail grid: label/logo column + content column. Topbar and About
     both use it so the nav's left edge aligns with the About heading. */
  --rail-cols: minmax(0, 1fr) minmax(0, 3.2fr);
  --rail-gap: clamp(1.5rem, 4vw, 4rem);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { background: #fff; color: var(--ink); font-family: var(--font-text); line-height: 1.6; }
img { max-width: 100%; display: block; }
:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; }
/* Reference bar (hyper-effekt): logo in the label rail, nav starts at the
   content column (aligned with the About heading), lang + CTA at the right.
   Nav and the right cluster share the content cell, pinned to its two ends. */
.topbar { display: grid; grid-template-columns: var(--rail-cols); align-items: center;
  gap: var(--rail-gap);
  padding: .55rem var(--gutter); position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  background: rgba(255,255,255,.95); border-bottom: 1px solid var(--line);
  transition: background .25s ease, border-color .25s ease; }
.topbar > .brand { grid-column: 1; grid-row: 1; justify-self: start; }
.topbar > .site-nav { grid-column: 2; grid-row: 1; justify-self: start; }
/* Fixed topbar overlaps content on pages without the hero; push main down */
body.page main { padding-top: 3.5rem; }
/* Over the hero: transparent bar, white text (reference style) */
.topbar--overlay { background: transparent; border-bottom-color: transparent; }
.topbar--overlay .brand, .topbar--overlay .site-nav a { color: #fff; }
.topbar--overlay .site-nav a:hover { color: #fff; opacity: .8; }
.topbar--overlay .nav-toggle { background: transparent; border-color: rgba(255,255,255,.5); }
.topbar--overlay .nav-toggle span { background: #fff; }
.topbar--overlay .lang-picker-current { color: #fff; }
.topbar--overlay .topbar-cta { background: #fff; border-color: #fff; color: var(--ink); }
/* Wordmark: user-supplied PNG used as a CSS mask over currentColor, so it
   recolors like text (ink on white pages, white over the hero overlay). */
.brand { display: inline-flex; align-items: center; color: var(--ink); text-decoration: none; }
.brand-logo { display: block; width: 7.5rem; aspect-ratio: 800 / 168; background: currentColor;
  -webkit-mask: url(../assets/brand/vellara-wordmark.png) no-repeat left center / contain;
  mask: url(../assets/brand/vellara-wordmark.png) no-repeat left center / contain; }
.topbar-right { display: flex; align-items: center; gap: clamp(16px, 2.5vw, 34px);
  grid-column: 2; grid-row: 1; justify-self: end; }
.site-nav { display: flex; gap: clamp(12px, 2vw, 26px); }
.site-nav a { font-size: .68rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-soft); text-decoration: none; }
.site-nav a:hover, .site-nav a[aria-current="page"] { color: var(--ink); }

/* Topbar language picker (reference style: current language opens a menu) */
.lang-picker { position: relative; }
.lang-picker-current { font: 600 .68rem var(--font-text); letter-spacing: .1em; border: none;
  background: none; color: var(--ink-soft); cursor: pointer; padding: 4px 2px; text-transform: uppercase; }
.lang-picker-current::after { content: " \2304"; font-size: .6rem; position: relative; top: -2px; }
.lang-picker-menu { position: absolute; top: calc(100% + 8px); right: 0; min-width: 8.5rem;
  background: #fff; border: 1px solid var(--line); border-radius: 0; z-index: 45; }
.lang-picker-menu button { display: block; width: 100%; text-align: left; border: none;
  background: none; cursor: pointer; font: 400 .8rem var(--font-text); color: var(--ink);
  padding: .6rem .9rem; }
.lang-picker-menu button:hover { background: var(--paper-card); }
.lang-picker-menu button[aria-selected="true"] { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* Topbar CTA (reference "Book a call"): white square button + arrow */
.topbar-cta { display: inline-flex; align-items: center; gap: .45rem;
  font: 600 .68rem var(--font-text); letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink); background: #fff; border: 1px solid var(--line); border-radius: 0;
  padding: .55rem .9rem; text-decoration: none; }
.topbar-cta:hover { border-color: var(--brass); color: var(--brass); }

.nav-toggle { display: none; flex-direction: column; justify-content: center;
  align-items: center; gap: 5px; width: 2.2rem; height: 2.2rem; border: 1px solid var(--line);
  border-radius: 0; background: #fff; appearance: none; cursor: pointer; padding: 0; }
.nav-toggle span { display: block; width: 1.1rem; height: 1.5px; background: var(--ink); }

@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } .dot::before { animation: none !important; } }

/* Mobile nav: burger toggle + slide-down panel */
@media (max-width: 48rem) {
  .nav-toggle { display: flex; }
  .topbar-cta { display: none; }
  .site-nav { display: none; position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; gap: 0; background: #fff; border: 1px solid var(--line);
    border-radius: 0; z-index: 39; }
  /* The desktop rail placement (grid-column:2 + justify-self:start) pins this
     absolutely positioned panel to the nav track and shrinks it to content
     width; resetting both restores the full-width left/right insets. */
  .topbar > .site-nav { grid-column: auto; justify-self: stretch; }
  .site-nav.open { display: flex; }
  .site-nav a { padding: .9rem var(--gutter); border-bottom: 1px solid var(--line); }
  .site-nav a:last-child { border-bottom: none; }
}

/* Room Walk */
.room-walk { background: #fff; }
.walk-stage { position: relative; }
.walk-scrim { position: absolute; left: 0; right: 0; pointer-events: none; z-index: 2; }
.walk-scrim--top { top: 0; height: 110px;
  background: linear-gradient(to bottom, rgba(20,16,12,.45), transparent); }
.walk-scrim--bottom { bottom: 0; height: 42%;
  background: linear-gradient(to top, rgba(20,16,12,.55), rgba(20,16,12,.12) 55%, transparent); }
/* Title + room progress ride together on the hero's bottom edge, so the bar
   always sits directly under the statement whatever the title wraps to. */
.walk-overlay { position: absolute; left: var(--gutter); right: var(--gutter);
  bottom: clamp(1.2rem, 4vh, 2.6rem); z-index: 3; pointer-events: none; }
.walk-title { color: #fff; font: 400 clamp(2.2rem, 5.5vw, 5rem)/1.08 var(--font-text);
  letter-spacing: -0.015em; white-space: pre-line; }

/* One full-bleed room per view — image spans the whole window */
.walk { display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -ms-overflow-style: none; }
.walk::-webkit-scrollbar { display: none; }
.walk-slide { flex: 0 0 100%; width: 100%; scroll-snap-align: start; }


/* The hero fills the window instead of being sized by the photo's own 1.791
   ratio, which left 8-112px of the white About section showing under it on
   nearly every desktop size. Cover then crops, and layoutPins() remaps the dots
   onto the crop. The 1.6 clamp is the safety rail: pins run out to x=92.7%, and
   a box narrower than 16:10 would start cutting the outermost ones off the
   frame entirely. Below that the hero stops growing rather than losing pins. */
.room-image { width: 100%; display: block; height: min(100svh, 100vw / 1.6);
  object-fit: cover; }

/* .walk-slide--room stacks image + pins overlay in the same grid cell, below the
   caption row, so pin percentages map onto the image's own box (not the caption). */
.walk-slide--room { display: grid; grid-template-columns: 1fr; }
.walk-slide--room > .room-image,
.walk-slide--room > .room-pins { grid-column: 1; grid-row: 1; }

/* Room Pins */
.room-pins { position: relative; pointer-events: none; }
/* Centred on its point by negative margins rather than a transform: a
   transformed ancestor becomes the containing block for position:fixed, which
   would trap the phone sheet below inside this 26px box. */
.hotspot { position: absolute; width: 26px; height: 26px; margin: -13px 0 0 -13px;
  pointer-events: auto; }
/* Solid white marker readable on any photo, dark or light (contrast ring, no shadows) */
.dot { position: relative; display: block; width: 28px; height: 28px; border-radius: 50%;
  border: 1px solid rgba(0,0,0,.18); background: rgba(255,255,255,.95); appearance: none;
  padding: 0; cursor: pointer; }
.dot::after { content: ""; position: absolute; top: 50%; left: 50%; width: 9px; height: 9px;
  border-radius: 50%; background: var(--brass); transform: translate(-50%, -50%); pointer-events: none; }
.dot::before { content: ""; position: absolute; inset: -8px; border-radius: 50%;
  border: 1.5px solid rgba(255,255,255,.85); opacity: 0; animation: pin-pulse 2.8s infinite;
  pointer-events: none; }
@keyframes pin-pulse {
  0% { transform: scale(.75); opacity: .55; }
  70% { transform: scale(1.55); opacity: 0; }
  100% { transform: scale(1.55); opacity: 0; }
}

.pin-card { position: absolute; display: none; width: 232px; max-width: 74vw; text-align: left;
  background: #fff; border: 1px solid var(--line); border-radius: 0; padding: 14px; z-index: 5; }
.hotspot.open .pin-card { display: block; }
@media (hover: hover) and (pointer: fine) {
  .hotspot:hover .pin-card { display: block; }
}
.hotspot.hs-up .pin-card { bottom: calc(100% + 10px); left: 50%; transform: translateX(-50%); }
.hotspot.hs-dn .pin-card { top: calc(100% + 10px); left: 50%; transform: translateX(-50%); }
.hotspot.hs-ur .pin-card { bottom: calc(100% + 10px); left: 0; }
.hotspot.hs-ul .pin-card { bottom: calc(100% + 10px); right: 0; }

/* Only the phone sheet needs a close control — on a pointer device the card
   opens on hover and closes when the cursor leaves. */
.pin-close { display: none; }

.pin-card-collection { font: 600 .6rem var(--font-text); letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-soft); margin-bottom: .35rem; }
.pin-card-name { font: 600 .95rem var(--font-text); margin-bottom: .8rem; }
.pin-card-journal { display: block; font-size: .75rem; color: var(--ink); text-decoration: underline;
  margin-bottom: .8rem; }
.pin-card-journal:hover { color: var(--brass); }

/* Room progress: one segment per room, each filling over its own dwell time.
   The fill is a CSS animation rather than a JS timer so pausing the bar and
   pausing the advance are the same state — `animationend` drives the advance. */
.walk-progress { --walk-dwell: 6s; display: flex; gap: 6px; pointer-events: auto;
  margin-top: clamp(1.1rem, 3vh, 1.75rem); }
.walk-seg { flex: 1 1 0; appearance: none; border: 0; background: none; cursor: pointer;
  display: block; padding: 11px 0; }
/* .4 keeps the unrun track legible over the brightest room without competing
   with the statement above it. */
.walk-seg-track { display: block; height: 2px; overflow: hidden;
  background: rgba(255,255,255,.4); }
.walk-seg-fill { display: block; height: 100%; background: #fff;
  transform: scaleX(0); transform-origin: left center; }
.walk-seg.is-done .walk-seg-fill { transform: scaleX(1); }
.walk-seg.is-active .walk-seg-fill { animation: walk-fill var(--walk-dwell) linear forwards; }
.walk-progress.is-paused .walk-seg.is-active .walk-seg-fill { animation-play-state: paused; }
.walk-seg:hover .walk-seg-track { background: rgba(255,255,255,.55); }
.walk-seg:focus-visible { outline: 1px solid #fff; outline-offset: 2px; }
@keyframes walk-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

@media (prefers-reduced-motion: reduce) {
  /* No autoplay without motion — the bar degrades to a plain position indicator. */
  .walk-seg.is-active .walk-seg-fill { animation: none; transform: scaleX(1); }
}

@media (max-width: 48rem) {
  .walk-slide { width: 100%; }
  /* The room keeps its 2752/1536 crop (pins are placed on the image box), so a
     phone hero is only ~218px tall. Title and bar are tuned to that budget —
     together they must not grow up into the topbar. */
  /* The statement comes off the photo on a phone. Overlaid, it ran straight
     through the pins — they sit at 22–79% of an image only ~218px tall, so the
     two were competing for the same band and both lost. Below the image it
     reads as ink on paper, and the room is left whole for its dots. */
  /* Progress leads on a phone: the bar reads as the room counter sitting under
     the photo it belongs to, and the statement then closes the block. */
  .walk-overlay { position: static; padding: 1.2rem var(--gutter) 0;
    display: flex; flex-direction: column; }
  .walk-title { font-size: 1.75rem; color: var(--ink); }
  .walk-progress { order: -1; margin: 0 0 1.4rem; }
  .walk-seg-track { background: var(--line); }
  .walk-seg-fill { background: var(--ink); }
  /* The scrim existed to carry white type over the photo. With the statement
     moved onto paper it has no job, and it would now sit over the paper itself:
     it is anchored to .walk-stage, which the static overlay just made taller. */
  .walk-scrim--bottom { display: none; }

  /* A 232px card cannot open inside a ~218px hero. Whichever way its authored
     hs-* direction points — those are placed against the desktop geometry — it
     either lands on top of the statement or is cut off, because .walk needs
     overflow-x:auto for scroll-snap and CSS then forces overflow-y:auto too.
     On a phone the detail becomes a sheet on the viewport's bottom edge: out of
     the scroller entirely so nothing can clip it, and never competing with the
     statement for the same 200-odd pixels. Square and shadowless, as everywhere.
     The hs-* rules are neutralised at their own specificity or they would win
     and put the offsets back. */
  .hotspot.hs-up .pin-card,
  .hotspot.hs-dn .pin-card,
  .hotspot.hs-ur .pin-card,
  .hotspot.hs-ul .pin-card {
    display: block; position: fixed; inset: auto 0 0 0; width: auto; max-width: none;
    padding: 1.15rem var(--gutter) calc(1.15rem + env(safe-area-inset-bottom, 0px));
    border-left: 0; border-right: 0; border-bottom: 0; z-index: 40;
    transform: translateY(101%); visibility: hidden; pointer-events: none;
    transition: transform .3s cubic-bezier(.22,.61,.36,1), visibility 0s linear .3s;
  }
  .hotspot.open .pin-card {
    transform: translateY(0); visibility: visible; pointer-events: auto;
    transition: transform .3s cubic-bezier(.22,.61,.36,1), visibility 0s;
  }
  /* 44px hit target, drawn rather than typed: the self-hosted Golos subset has
     no guaranteed glyph for a multiplication sign or a ballot X. */
  .pin-close { display: block; position: absolute; top: .45rem; right: .3rem;
    width: 44px; height: 44px; padding: 0; border: 0; background: none;
    cursor: pointer; -webkit-tap-highlight-color: transparent; }
  .pin-close::before, .pin-close::after { content: ""; position: absolute;
    left: 50%; top: 50%; width: 16px; height: 1.5px; background: var(--ink); }
  .pin-close::before { transform: translate(-50%, -50%) rotate(45deg); }
  .pin-close::after { transform: translate(-50%, -50%) rotate(-45deg); }
  .pin-close:focus-visible { outline: 1px solid var(--ink); outline-offset: -6px; }

  /* Keep the name clear of the close button's 44px square. */
  .pin-card-collection, .pin-card-name { padding-right: 44px; }
  .pin-card-name { font-size: 1.05rem; margin-bottom: .9rem; }
  .pin-card-journal { margin-bottom: 1rem; }
  .pin-card .wa { width: 100%; }
}

/* About (reference "Overview" section): side label · big heading · two body
   columns · chat CTA. Label sits in the left rail, content in the wide column. */
.about { display: grid; grid-template-columns: var(--rail-cols); gap: var(--rail-gap);
  padding: clamp(3rem, 8vw, 6.5rem) var(--gutter) clamp(3rem, 8vw, 6rem); }
.about-label { font: 600 .68rem var(--font-text); letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-soft); padding-top: .55em; }
.about-title { font: 400 clamp(1.9rem, 3.6vw, 3.1rem)/1.15 var(--font-text);
  letter-spacing: -0.015em; white-space: pre-line;
  margin-bottom: clamp(1.75rem, 4vw, 3rem); }
.about-cols { display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(1.5rem, 3vw, 3rem); max-width: 56rem; font-size: .9rem;
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }
.about-cta { display: inline-flex; align-items: center; gap: .5rem;
  font: 600 .72rem var(--font-text); letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink); background: #fff; border: 1px solid var(--line); border-radius: 0;
  padding: .8rem 1.2rem; text-decoration: none; }
.about-cta:hover { border-color: var(--ink); }
@media (max-width: 48rem) {
  .about { grid-template-columns: 1fr; gap: 1.25rem; }
  .about-label { padding-top: 0; }
  .about-cols { grid-template-columns: 1fr; }
}

/* Collage: port of 21st.dev @sshahaider/image-gallery — a 3-column masonry
   (each column its own vertical stack, 1.5rem gaps) with lazy fade-in on
   scroll. Complies with the page grid: the label rail (column 1) is skipped,
   so the gallery takes the content area — same left seam as the About
   heading, same capped right edge as the text. Square corners (no radius). */
.collage { display: grid; margin: 0 var(--gutter) clamp(3rem, 8vw, 6rem);
  grid-template-columns:
    calc((100% - var(--rail-gap)) / 4.2)   /* skipped rail column */
    var(--rail-gap)
    minmax(0, min(calc((100% - var(--rail-gap)) * 3.2 / 4.2), 56rem)); }
.gallery { grid-column: 3; display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem; align-items: start; }
.gallery-col { display: grid; gap: 1.5rem; }
.tile { position: relative; display: block; overflow: hidden; aspect-ratio: 3 / 4;
  background: var(--paper-card); border: 1px solid var(--line); border-radius: 0; }
.tile img { width: 100%; height: 100%; object-fit: cover; opacity: 0;
  transition: opacity 1s ease-in-out; }
.tile img.in-view.loaded { opacity: 1; }
@media (max-width: 48rem) {
  .collage { grid-template-columns: 1fr; margin-bottom: 3rem; }
  .gallery { grid-column: 1; grid-template-columns: 1fr; }
}

/* Journal */
#journal { padding: clamp(2rem, 6vw, 5rem) var(--gutter) clamp(3rem, 8vw, 6rem); }
.journal-head { max-width: 640px; margin-bottom: clamp(1.5rem, 4vw, 2.5rem); }
.journal-head h1 { font: 600 clamp(1.8rem, 4vw, 2.6rem) var(--font-text); margin-bottom: .6rem; }
.journal-head p { color: var(--ink-soft); }

.filter-chips { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: clamp(2rem, 5vw, 3.5rem); }
.chip { font: 600 .68rem var(--font-text); letter-spacing: .1em; text-transform: uppercase;
  border: 1px solid var(--line); border-radius: 0; background: #fff; color: var(--ink);
  padding: .55rem 1.1rem; cursor: pointer; appearance: none; }
.chip[aria-pressed="true"] { background: var(--ink); color: #fff; border-color: var(--ink); }

.chapter { padding-top: clamp(2.25rem, 6vw, 3.5rem); }
.chapter-head { display: flex; align-items: baseline; gap: .85rem; margin-bottom: 1.25rem;
  border-top: 1px solid var(--line); padding-top: 1.25rem; }
.chapter-num { font: 600 .7rem var(--font-text); letter-spacing: .14em; color: var(--ink-soft); }
.chapter-title { font: 600 clamp(1.15rem, 3vw, 1.6rem) var(--font-text); }

/* Chapter opener: the approved room scene for this chapter, full grid width,
   no text overlay, sitting above the item grid within the chapter section. */
.chapter-scene { margin-bottom: 1.25rem; }
.chapter-scene img { width: 100%; display: block; aspect-ratio: 2752 / 1536; object-fit: cover; }

/* Hairlines drawn by card borders — incomplete last rows leave no filled blocks.
   Selectors carry two classes so they outrank the cards' own `border: none`. */
.grid { display: grid; grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--line); border-left: 1px solid var(--line); }
.grid > .card, .grid > .pdf-card {
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }
@media (max-width: 64rem) { .grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 48rem) { .grid { grid-template-columns: repeat(2, 1fr); } }

.card { background: #fff; border: none; border-radius: 0; appearance: none; text-align: left;
  font-family: inherit; padding: 1.1rem; display: flex; flex-direction: column; gap: .6rem; cursor: pointer; }
.card .ph { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.card .ph img { mix-blend-mode: multiply; max-height: 100%; width: auto; object-fit: contain; }
.card .item-name { font-size: .85rem; }
.card .item-collection { font: 600 .6rem var(--font-text); letter-spacing: .1em;
  text-transform: uppercase; color: var(--brass); }

/* Lightbox */
.lightbox { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center;
  justify-content: center; padding: var(--gutter); }
.lightbox[hidden] { display: none; }
.lightbox-overlay { position: absolute; inset: 0; background: rgba(255, 255, 255, .96); }
.lightbox-figure { position: relative; z-index: 1; background: #fff; border: 1px solid var(--line);
  border-radius: 0; max-width: 640px; width: 100%; max-height: 90vh; overflow: auto;
  padding: clamp(1.5rem, 4vw, 3rem); display: flex; flex-direction: column; gap: 1rem; }
.lightbox-close { position: absolute; top: .75rem; right: .75rem; width: 2.1rem; height: 2.1rem;
  border: 1px solid var(--line); border-radius: 0; appearance: none; background: #fff;
  font-size: 1.2rem; line-height: 1; cursor: pointer; }
.lightbox-img-wrap { display: flex; align-items: center; justify-content: center; min-height: 260px; }
.lightbox-img { mix-blend-mode: multiply; max-height: 55vh; width: auto; object-fit: contain; }
.lightbox-collection { font: 600 .65rem var(--font-text); letter-spacing: .1em; text-transform: uppercase;
  color: var(--brass); }
.lightbox-name { font: 600 clamp(1.15rem, 3vw, 1.6rem) var(--font-text); }
.wa { display: inline-flex; align-items: center; justify-content: center; width: fit-content;
  border-radius: 999px; background: var(--wa); color: #fff; text-decoration: none;
  font: 600 .78rem var(--font-text); letter-spacing: .04em; padding: .75rem 1.5rem; }

/* Catalogues */
#catalogues { padding: clamp(2rem, 6vw, 5rem) var(--gutter) clamp(3rem, 8vw, 6rem); }
.catalogues-head { max-width: 640px; margin-bottom: clamp(1.5rem, 4vw, 2.5rem); }
.catalogues-head h1 { font: 600 clamp(1.8rem, 4vw, 2.6rem) var(--font-text); margin-bottom: .6rem; }
.catalogues-head p { color: var(--ink-soft); }

#catalogues-grid .pdf-card { background: #fff; border: none; appearance: none; text-align: left;
  font-family: inherit; padding: 1.1rem; display: flex; flex-direction: column; gap: .6rem;
  text-decoration: none; color: var(--ink); cursor: pointer; border-radius: 0;
  transition: background-color 150ms ease; }
#catalogues-grid .pdf-card:hover { background-color: var(--paper-card); }
/* Cover well: square like the product cards' `.ph`, but the sheet inside keeps
   its A4 ratio and is capped short of the edges so it never fills the square. */
#catalogues-grid .pdf-card-cover { aspect-ratio: 1; display: flex;
  align-items: center; justify-content: center; margin-bottom: .3rem; }
#catalogues-grid .pdf-card-cover img { max-height: 80%; max-width: 80%;
  width: auto; height: auto; object-fit: contain; border: 1px solid var(--line); }
#catalogues-grid .pdf-card-kicker { font: 600 .6rem var(--font-text); letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-soft); margin-bottom: .4rem; }
#catalogues-grid .pdf-card-title { font: 600 clamp(1rem, 2vw, 1.2rem) var(--font-text); margin-bottom: .4rem; }
#catalogues-grid .pdf-card-meta { font-size: .75rem; color: var(--ink-soft); margin-bottom: .6rem; }
#catalogues-grid .pdf-card-download { font: 600 .68rem var(--font-text); letter-spacing: .1em;
  text-transform: uppercase; color: var(--brass); }

/* Contact — mirrors the About block: label in the rail, big light heading
   and content on the same seam as the About heading. */
#contact { display: grid; grid-template-columns: var(--rail-cols); gap: var(--rail-gap);
  padding: clamp(2rem, 6vw, 5rem) var(--gutter) clamp(3rem, 8vw, 6rem); }
.contact-label { font: 600 .68rem var(--font-text); letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-soft); padding-top: .55em; }
.contact-content h2 { font: 400 clamp(1.9rem, 3.6vw, 3.1rem)/1.15 var(--font-text);
  letter-spacing: -0.015em; margin-bottom: clamp(1.75rem, 4vw, 3rem); }
.contact-content > p { font-size: .9rem; max-width: 27rem;
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }

.contact-links { display: flex; gap: 1.5rem; align-items: center; flex-wrap: wrap; }
.contact-links a { color: var(--ink); text-decoration: none; font: 600 .85rem var(--font-text); }
.contact-links a:hover { color: var(--brass); }
@media (max-width: 48rem) {
  #contact { grid-template-columns: 1fr; gap: 1.25rem; }
  .contact-label { padding-top: 0; }
}

/* Catalogue cards: hairlines must outrank the ID-scoped `border: none` above */
#catalogues-grid > .pdf-card {
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }

/* Footer: wordmark only */
.site-footer { display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: 1rem; padding: 1.5rem var(--gutter); border-top: 1px solid var(--line); }
.brand--small .brand-logo { width: 6rem; }

.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
