/* ─────────────────────────────────────────────────────────────────────────────
   Adivia Homes — Shared Stylesheet  (Warm Stone Minimal)
   Pages: Projects, Project Detail, About, Services, Partners, Contacts
───────────────────────────────────────────────────────────────────────────── */

/* ─── Fonts ───────────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'Liquefier';
  src: url('assets/fonts/Liquefier.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Nolluqa';
  src: url('assets/fonts/NolluqapersonaluseRegular-VGMge.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

/* ─── Custom Properties ───────────────────────────────────────────────────── */
:root {
  --cream:       #F5F2EE;
  --cream-dark:  #EDE8E2;
  --white:       #FFFFFF;
  --dark:        #1A1A1A;
  --body-text:   #3A3A3A;
  --muted:       #8A8680;
  --border:      #E0DDD8;
  --teal:        #5B93C4;
  --teal-deep:   #3F76A8;
  --teal-faint:  rgba(91, 147, 196, 0.12);
  --footer-bg:   #3A3632;
  --footer-text: #E8E4DF;

  --font-display: 'Liquefier', Georgia, serif;
  --font-accent:  'Nolluqa', Georgia, serif;
  --font-body:    'Poppins', system-ui, -apple-system, sans-serif;

  --header-h: 70px;
  --max-w:    1200px;
  --radius:   3px;
  --t:        0.28s ease;

  /* ─── Safe-area tokens ──────────────────────────────────────────────────────
     Added 2026-08-13. Client, on an iPhone with a Dynamic Island: "the website
     doesnt render under the dynamic island and the dock", plus "there is a white
     strip under the detail card that just sits there and does nothing".

     BOTH SENTENCES ARE THE SAME BUG. Every page that renders shipped with
     `content="width=device-width, initial-scale=1.0"` and no `viewport-fit=cover`.
     Without it iOS does not give the page the whole screen: it shrinks the LAYOUT
     VIEWPORT to the area between the safe-area insets and paints the leftover bands
     with the page background.

     THE STRIP WAS NEVER IN THE PAGE, and that was established by measurement before
     anything was edited. Emulated at the four sizes that matter, the phone
     inspector's `#lp-deck` ends EXACTLY at the bottom of whatever viewport it is
     given — 852.00 of 852, 759.43 of 759.43, 844.00 of 844, 763.43 of 763.43 — with
     `.lp-card` filling it to the same edge and the last painted element at y = h-1
     being the card. Zero in-page gap at every size. So the strip was the 34px
     home-indicator band BELOW the layout viewport, filled with `body`'s #F5F2EE.
     That is the "white strip"; the island band at the top is the same letterbox
     seen from the other end, and on an iPhone 15 Pro the two together were 93px of
     an 852px screen — 10.9% of the display the client paid for, doing nothing.

     Do not go looking for a short element to stretch. There isn't one.

     So `viewport-fit=cover` now ships on all nine pages — the eight that render,
     plus the partners.html redirect shell so the claim has no exception — and
     these four tokens are how
     the layout gets the insets back. They exist rather than bare `env()` calls for
     two reasons: one place to read the contract, and a testable seam — a harness can
     override `--sat`/`--sab` to simulate a notch, which Chrome cannot otherwise
     produce. The `, 0px` fallback in each `env()` and in every `var()` that consumes
     them is what keeps Android, desktop and every non-notched device byte-identical.

     THE TWO IDIOMS, AND WHEN TO USE WHICH — this is not a style preference:
       - Bottom/side-anchored chrome uses `calc(Npx + var(--sab, 0px))`. Before cover
         the viewport ENDED above the home indicator, so `bottom: N` meant N above it.
         Now the viewport runs to the glass, and only `N + inset` puts the control
         back where it already was. Adding the inset PRESERVES the design.
       - Top-anchored chrome uses `max(Npx, calc(var(--sat, 0px) + margin))`. Here the
         old offset must NOT be preserved: the client's whole complaint is that the
         layout wastes screen, so content should rise into the space cover just handed
         back and stop only where the island would actually clip it. `max()` also
         guarantees the no-inset case is unchanged to the pixel.
     ─────────────────────────────────────────────────────────────────────────── */
  --sat: env(safe-area-inset-top, 0px);
  --sar: env(safe-area-inset-right, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
  --sal: env(safe-area-inset-left, 0px);

  /* The header pill's full occupied height: its own 70px PLUS the island band it now
     has to cover. Anything that used to clear the header with `var(--header-h)` has to
     clear this instead, or it slides up under the pill on a notched phone. */
  --header-total: calc(var(--header-h) + var(--sat, 0px));

  /* Section gutter — ONE number for every full-bleed band on the site.
     Before 2026-08-13 the 40px/24px pair was retyped into .container,
     .banner-inner and .enquire-cta, while .aura-section, .why-section and
     .cta-strip hard-coded 40px and never dropped to 24px on a phone. Measured
     at 320px that left 240px of usable width against .container's 272px, so
     adjacent sections on the same page had visibly different left edges.
     Anything that spans the viewport must use var(--gutter), never a literal.
     The phone value is overridden once, in the max-width:768px block.

     The `max(--sal, --sar)` term is the landscape half of the safe-area work: held
     sideways, a notched phone puts a ~59px inset on ONE side, and `.container`'s
     `padding: 0 var(--gutter)` would otherwise run body copy straight under the
     island. Symmetric on purpose — a centred column insetting on one side only reads
     as broken alignment, and the gutter is the single lever every full-bleed band
     already respects, so backgrounds still reach the glass while text does not.
     `max()` of two 0px values is 0px, so nothing outside a notched landscape moves. */
  --gutter:   calc(40px + max(var(--sal, 0px), var(--sar, 0px)));
}

/* ─── Type scale: rem, not px ─────────────────────────────────────────────────
   Every font-size in this file is declared in rem against the browser's own root
   size. There is exactly one exception and it is documented where it sits
   (.footer-wordmark text, an SVG user-unit value).

   Why, measured. Before 2026-08-13 this file declared 109 font sizes in px
   against 14 in rem/em. A reader who raises Chrome's Settings > Appearance >
   Font size from 16px to 19px got a root of 19px and nothing else moved:
     .filter-btn      9.5px -> 9.5px      .card-location   10.5px -> 10.5px
     .footer-bottom p 11px  -> 11px       .spec-label      10px   -> 10px
   Enlarging text is the one accessibility control that reader has, and this site
   was immune to it. rem fixes that with no visual change at the default setting,
   because every value was divided by 16 exactly: 12px -> 0.75rem,
   12.5px -> 0.78125rem, 13.5px -> 0.84375rem and so on. Verified by comparing
   computed font sizes before and after at a 16px default — identical.

   Two rules for anyone editing type here:
     1. Nothing that carries meaning goes below 0.75rem (12px). That is a floor,
        not a suggestion; a previous pass set it for two selectors inside one
        media query and the rest of the site stayed at 9.5-11px for months.
     2. Do not reintroduce px "just for this one". `max(1rem, 16px)` is the
        pattern when a hard pixel floor is genuinely required — see the contact
        form fields near the end of this file for the only current case.
   Structural px (padding, min-height, borders, touch targets, breakpoints) is
   deliberately left alone: those are physical sizes, not reading sizes. */

/* ─── Reset ───────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--font-body);
  background: var(--cream);
  color: var(--body-text);
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a   { color: inherit; text-decoration: none; }
ul  { list-style: none; }

/* ─── Header ──────────────────────────────────────────────────────────────── */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 200;
  /* Stays glued to top:0 so the glass reaches the physical top of the screen —
     the background is SUPPOSED to run under the island. What must not run under
     it is the nav. `padding-top` is what separates the two: the element grows by
     the inset, the glass fills the whole thing, and `.header-inner` (height:100%,
     i.e. 100% of the CONTENT box under the global border-box) is pushed clear.
     At --sat:0 this is height:70px/padding-top:0 — byte-identical to before.
     The phone pill below resets padding-top to 0 and insets its own `top`; see
     the note there for why the pill uses the other idiom. */
  height: var(--header-total);
  padding-top: var(--sat, 0px);
  transition: box-shadow var(--t), transform 0.35s ease;
}
.site-header.nav-hidden {
  transform: translateY(-100%);
}

/* arch-shaped glass fill — clip-path makes blur follow the dent */
.site-header::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  /* --header-total, not --header-h, in BOTH the height and every clip-path stop.
     This pseudo-element is the arch. Its containing block is the header's PADDING
     box, so `top:0` is still the physical top of the screen (good — that is the
     glass that has to reach under the island), but the arch's dent has to land on
     the header's VISUAL bottom edge, which the padding just moved down by --sat.
     Left at --header-h the notch would have been cut 59px too high on an iPhone
     and the white stroke below (::after, `bottom:-28px`, measured from the same
     padding box) would no longer have traced it. --header-total is
     calc(70px + 0px) with no inset, so this is unchanged everywhere else. */
  height: calc(var(--header-total) + 16px);
  /* permanently glassmorphic — visible glass even before scrolling */
  background: linear-gradient(180deg, rgba(255,255,255,0.16) 0%, rgba(255,255,255,0.08) 100%);
  backdrop-filter: blur(26px) saturate(1.6);
  -webkit-backdrop-filter: blur(26px) saturate(1.6);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.22);
  clip-path: polygon(
    0% 0%, 100% 0%, 100% var(--header-total),
    54.5% var(--header-total),
    53.3% calc(var(--header-total) + 5px),
    52%   calc(var(--header-total) + 9px),
    50.9% calc(var(--header-total) + 12px),
    50%   calc(var(--header-total) + 13px),
    49.1% calc(var(--header-total) + 12px),
    48%   calc(var(--header-total) + 9px),
    46.7% calc(var(--header-total) + 5px),
    45.5% var(--header-total),
    0% var(--header-total)
  );
  pointer-events: none;
  transition: background var(--t), backdrop-filter var(--t);
}
/* arch border line — white stroke, hardcoded so it renders correctly */
.site-header::after {
  content: '';
  position: absolute;
  bottom: -28px; left: 0; right: 0;
  height: 30px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 30' preserveAspectRatio='none'%3E%3Cpath d='M0 1 L455 1 Q500 28 545 1 L1000 1' stroke='white' stroke-opacity='0.55' stroke-width='1.5' fill='none'/%3E%3C/svg%3E") no-repeat;
  background-size: 100% 100%;
  pointer-events: none;
  transition: opacity var(--t);
}

.header-inner {
  position: relative;
  z-index: 1;
  max-width: var(--max-w);
  margin: 0 auto;
  height: 100%;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0 40px;
}

.nav-links {
  display: flex;
  gap: 34px;
  align-items: center;
}
.nav-links.right { justify-content: flex-end; }

.nav-links a {
  font-size: 0.78125rem;
  font-weight: 400;
  letter-spacing: 0.07em;
  color: rgba(255,255,255,0.85);
  transition: color var(--t);
}
.nav-links a:hover,
.nav-links a.active { color: var(--teal); }

.nav-logo {
  padding: 0 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.nav-logo img {
  height: 52px;
  width: auto;
  filter: brightness(0) invert(1);
  transition: filter var(--t);
}

/* scrolled state */
.site-header.scrolled {
  box-shadow: 0 2px 28px rgba(0,0,0,0.07);
}
.site-header.scrolled::before {
  background: rgba(245,242,238,0.55);
  backdrop-filter: blur(26px) saturate(1.7);
  -webkit-backdrop-filter: blur(26px) saturate(1.7);
}
.site-header.scrolled::after {
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 30' preserveAspectRatio='none'%3E%3Cpath d='M0 1 L455 1 Q500 28 545 1 L1000 1' stroke='%23b4aea6' stroke-opacity='0.8' stroke-width='1.5' fill='none'/%3E%3C/svg%3E") no-repeat;
  background-size: 100% 100%;
}
.site-header.scrolled .nav-links a { color: rgba(26,26,26,0.75); }
.site-header.scrolled .nav-links a:hover,
.site-header.scrolled .nav-links a.active { color: var(--teal); }
.site-header.scrolled .nav-logo img { filter: none; }

/* hamburger */
.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  grid-column: 3;
  justify-self: end;
}
.nav-toggle span {
  display: block;
  width: 22px;
  height: 1.5px;
  background: rgba(255,255,255,0.85);
  border-radius: 1px;
  transition: background var(--t);
}
.site-header.scrolled .nav-toggle span { background: var(--dark); }

/* mobile menu */
.nav-mobile {
  display: none;
  position: fixed;
  /* Hangs off the bottom edge of the header, so it tracks --header-total for the
     same reason the arch does. Only reachable above 768px-and-tall (the phone gate
     below re-anchors it to the pill), i.e. desktop and large tablets — where --sat
     is 0 on every desktop browser and 24px on an iPad with cover on. */
  top: var(--header-total); left: 0; right: 0;
  background: var(--cream);
  border-bottom: 1px solid var(--border);
  padding: 24px 40px 32px;
  z-index: 190;
  box-shadow: 0 8px 24px rgba(0,0,0,0.07);
}
.nav-mobile.open { display: block; }
.nav-mobile ul { display: flex; flex-direction: column; gap: 16px; }
.nav-mobile ul a {
  font-size: 0.9375rem;
  color: var(--dark);
  transition: color var(--t);
}
.nav-mobile ul a:hover { color: var(--teal); }

/* ─── Layout Helpers ──────────────────────────────────────────────────────── */
.container {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.section { padding: 96px 0; }

/* ─── Label ───────────────────────────────────────────────────────────────── */
.label {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--teal);
  margin-bottom: 14px;
}
.label::before { content: '── '; letter-spacing: -0.02em; }

/* ─── Buttons ─────────────────────────────────────────────────────────────── */
.btn-teal,
.btn-outline {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 13px 30px;
  border-radius: var(--radius);
  cursor: pointer;
  transition: all var(--t);
  border: none;
}
.btn-teal { background: var(--teal); color: var(--white); }
.btn-teal:hover {
  background: var(--teal-deep);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(91, 147, 196,0.35);
}
.btn-outline {
  background: transparent;
  color: var(--white);
  border: 1px solid rgba(255,255,255,0.3);
}
.btn-outline:hover { border-color: var(--teal); color: var(--teal); transform: translateY(-2px); }

/* ─── Liquid Glass Button ─────────────────────────────────────────────────── */
.btn-chrome {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 15px 32px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,0.7);
  background: rgba(255,255,255,0.35);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  color: var(--dark);
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  box-shadow:
    0 8px 28px rgba(31,41,55,0.14),
    inset 0 1px 1px rgba(255,255,255,0.9),
    inset 0 -6px 12px rgba(255,255,255,0.25);
  transition: transform 0.075s ease, box-shadow 0.3s ease, background 0.3s ease;
}
.btn-chrome__liquid {
  position: absolute;
  inset: -60%;
  z-index: 0;
  opacity: 0.7;
  background:
    radial-gradient(circle at 30% 30%, rgba(255,255,255,0.95) 0%, rgba(255,255,255,0) 40%),
    radial-gradient(circle at 70% 65%, rgba(91, 147, 196,0.55) 0%, rgba(91, 147, 196,0) 45%),
    conic-gradient(from 0deg, rgba(255,255,255,0.5), rgba(91, 147, 196,0.35), rgba(255,255,255,0.6), rgba(255,255,255,0.2), rgba(91, 147, 196,0.4), rgba(255,255,255,0.5));
  filter: blur(14px);
  animation: chromeSwirl 8s linear infinite;
  transition: opacity 0.4s ease;
  mix-blend-mode: soft-light;
}
.btn-chrome:hover {
  background: rgba(255,255,255,0.5);
  box-shadow:
    0 12px 32px rgba(31,41,55,0.18),
    inset 0 1px 1px rgba(255,255,255,1),
    inset 0 -6px 14px rgba(255,255,255,0.35);
}
.btn-chrome:hover .btn-chrome__liquid { opacity: 1; animation-duration: 4s; }
.btn-chrome:active { transform: scale(0.96); }
.btn-chrome__label {
  position: relative;
  z-index: 1;
  color: var(--dark);
}
@keyframes chromeSwirl {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* ─── Page Banner ─────────────────────────────────────────────────────────── */
.page-banner {
  position: relative;
  height: 52vh;
  min-height: 340px;
  display: flex;
  align-items: flex-end;
  padding-bottom: 68px;
  background-size: cover;
  background-position: center 35%;
  overflow: hidden;
}
.page-banner::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(12,9,7,0.22) 0%,
    rgba(12,9,7,0.08) 52%,
    rgba(12,9,7,0.03) 100%
  );
  z-index: 1;
}

/* Page-banner heading — the <h1> of projects / services / contacts.
   Deliberately invisible on screen, and that is the whole point of the rule.

   Every page needs exactly one <h1>; it is the strongest on-page signal a search
   engine has for "what is this page about". These three pages appear to have a
   title already — the banner shows PROJECTS / SERVICES / CONTACTS in large
   display type. It is not text. The words are baked into the pixels of
   banner-projects.jpg, banner-services.jpg and banner-contacts.jpg; the banner
   element's only child is this heading, and its ::before/::after carry no
   content. So a crawler, a screen reader, and a Reader Mode all see three pages
   with a photograph and no title whatsoever.

   The fix is therefore real text, not more visible design: a rendered heading
   would duplicate the word already in the photo and read as a layout bug. The
   text is kept identical to the word shown in the image on purpose. Hidden text
   that says something different from the visible content is what search engines
   penalise as cloaking; hidden text that transcribes visible content is exactly
   the accessible-name case this technique exists for.

   Do not swap this for display:none or visibility:hidden — both remove the
   element from the accessibility tree, which loses the screen-reader benefit
   and leaves only the SEO half. The clip/clip-path pair is intentional
   belt-and-braces: clip is the legacy property, clip-path the modern one.
   If a banner image is ever replaced with one that has no word burnt in, delete
   this rule so the heading becomes visible again, and style it then. */
.page-banner__title {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ─── About Hero (scroll-scrubbed Aura video) ─────────────────────────── */
.aura-hero-scrub {
  position: relative;
  height: 300vh;
}
.aura-hero-scrub__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  background: #0c0907;
}
.aura-hero-scrub__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.aura-hero-scrub__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(12,9,7,0.55) 0%, rgba(12,9,7,0.15) 45%, rgba(12,9,7,0.25) 100%);
  z-index: 1;
}
.aura-hero-scrub__logo {
  position: absolute;
  top: 12%;
  left: 50%;
  transform: translateX(-50%);
  width: 120px;
  z-index: 2;
}
.aura-hero-scrub__logo img { width: 100%; height: auto; display: block; filter: drop-shadow(0 4px 18px rgba(0,0,0,.35)); }
.aura-hero-scrub__content {
  position: absolute;
  bottom: 14%;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  color: var(--white);
  max-width: 640px;
  width: 90%;
  z-index: 2;
}
.about-hero__eyebrow { color: rgba(255,255,255,.75); }
.aura-hero-scrub__content h1 {
  font-family: 'Poppins', sans-serif;
  font-weight: 500;
  font-size: clamp(2.2rem, 5vw, 3.6rem);
  margin: 10px 0 12px;
}
.about-hero__sub { color: rgba(255,255,255,.8); font-size: 1.05rem; }
.aura-hero-scrub__progress {
  position: absolute;
  right: 32px;
  bottom: 40px;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.aura-hero-scrub__progress-label {
  color: rgba(255,255,255,.75);
  font-size: 0.75rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  writing-mode: vertical-rl;
}
.aura-hero-scrub__progress-line .track { stroke: rgba(255,255,255,.25); stroke-width: 1; }
.aura-hero-scrub__progress-line .fill {
  stroke: #fff;
  stroke-width: 1;
  stroke-dasharray: 120;
  stroke-dashoffset: calc(120px - (120px * var(--scrub-progress, 0)));
}

.about-content {
  position: relative;
  z-index: 1;
  background: var(--cream);
  border-radius: 24px 24px 0 0;
  box-shadow: 0 -10px 40px rgba(0,0,0,.12);
}

/* ─── Grain scrollytelling ────────────────────────────────────────────── */
.grain-story {
  position: relative;
  height: 450vh;
  border-radius: 24px 24px 0 0;
}
.grain-story__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 24px 24px 0 0;
}
.grain-blob {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 120px;
  height: 120px;
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(var(--blob-scale, 1));
  will-change: transform, opacity;
  opacity: var(--blob-opacity, 0.9);
  background-color: #d8cdbd;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/><feColorMatrix type='matrix' values='0 0 0 0 0.2  0 0 0 0 0.16  0 0 0 0 0.1  0 0 0 0.9 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 240px 240px;
  mix-blend-mode: multiply;
  filter: blur(0.3px);
  z-index: 0;
}
.grain-stage {
  position: relative;
  z-index: 1;
  max-width: 640px;
  width: 88%;
  text-align: center;
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.5s ease, transform 0.5s ease;
  display: none;
  padding: 0 16px;
}
.grain-stage.active { display: block; opacity: 1; transform: translateY(0); }
.grain-stats { display: flex; flex-wrap: wrap; justify-content: center; gap: 32px; }

.banner-inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.banner-inner .label { color: var(--teal); }
.banner-inner h1 {
  font-family: var(--font-display);
  font-size: clamp(2.375rem, 4.5vw, 3.875rem);
  font-weight: normal;
  color: var(--white);
  line-height: 1.06;
  letter-spacing: 0.015em;
  margin-bottom: 12px;
}
.banner-inner p {
  font-size: 0.875rem;
  color: rgba(255,255,255,0.6);
  max-width: 440px;
}

/* ─── Filter Bar ──────────────────────────────────────────────────────────── */
.filter-bar {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  padding: 6px;
  margin: 52px 0 44px;
  background: rgba(255,255,255,0.55);
  border: 1px solid var(--border);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  border-radius: 999px;
  box-shadow: 0 6px 20px rgba(31,41,55,0.06);
}
.filter-btn {
  position: relative;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 10px 22px;
  border-radius: 999px;
  border: none;
  background: transparent;
  color: var(--muted);
  transition: color 0.25s ease;
  z-index: 1;
  cursor: pointer;
  transition: all var(--t);
}
.filter-btn:hover     { color: var(--dark); }
.filter-btn.active    { color: var(--white); }

.filter-lamp {
  position: absolute;
  top: 6px;
  left: 6px;
  height: calc(100% - 12px);
  border-radius: 999px;
  background: var(--teal);
  box-shadow: 0 4px 14px rgba(91, 147, 196,0.45);
  transition: transform 0.35s cubic-bezier(0.22,1,0.36,1), width 0.35s cubic-bezier(0.22,1,0.36,1);
  z-index: 0;
  pointer-events: none;
}
.filter-lamp::before {
  content: '';
  position: absolute;
  top: -6px;
  left: 50%;
  width: 24px;
  height: 3px;
  background: var(--teal);
  border-radius: 0 0 3px 3px;
  transform: translateX(-50%);
  box-shadow: 0 -4px 10px 2px rgba(91, 147, 196,0.6);
}

/* ─── Projects Grid ───────────────────────────────────────────────────────── */
.projects-section { padding-top: 0; }
.projects-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 26px;
  padding-bottom: 100px;
}

/* ─── Project Card ────────────────────────────────────────────────────────── */
.project-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform var(--t), box-shadow var(--t), border-color var(--t);
}
.project-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 18px 44px rgba(0,0,0,0.09), 0 0 0 2px var(--teal);
  border-color: var(--teal);
}

.card-photo {
  position: relative;
  aspect-ratio: 16 / 11;
  overflow: hidden;
}
.card-photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.55s ease;
}
.project-card:hover .card-photo img { transform: scale(1.04); }

.card-badge {
  position: absolute;
  top: 14px; right: 14px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 5px 11px;
  border-radius: 2px;
}
/* Contrast measured 2026-08-13 on projects.html at 1440x900, declared colour
   composited over the rendered pixels behind each chip (4 of the 7 cards carry
   badge-upcoming, so this is not a corner case):
     badge-completed  var(--dark)              17.4:1   pass, left alone
     badge-ongoing    var(--teal)   #5B93C4     3.28:1  FAIL  -> var(--teal-deep)  4.81:1
     badge-upcoming   rgba(255,255,255,0.14)    1.35:1  FAIL  -> rgba(20,17,14,.72) 8.65:1
                      over the brightest card, worst pixel 1.03:1 — invisible
   badge-upcoming was white text on a 14%-white chip, so its legibility was
   whatever pixel of the photo happened to sit behind it: it read fine over the
   dark grass render and vanished over the pale sky one. That is the "sometimes I
   can see it, sometimes I can't" class of failure, and since the badge is what
   labels the card it is a strong candidate for the reported disappearing cards.
   The 1px rgba(255,255,255,0.42) border does NOT carry legibility on its own —
   measured, it does not move the ratio at all. The blur is kept: with an opaque
   backdrop it still separates the chip from the photograph.
   badge-ongoing uses the existing --teal-deep token rather than a new colour;
   a bespoke #35618C measured better (6.48:1) but introduces a colour the design
   system does not have. Re-measure against the BRIGHTEST photo in the set, not
   an average, if these are ever retuned. */
.badge-completed { background: var(--dark); color: var(--white); }
.badge-ongoing   { background: var(--teal-deep); color: var(--white); }
.badge-upcoming  {
  background: rgba(20,17,14,0.72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--white);
  border: 1px solid rgba(255,255,255,0.42);
}

.card-body {
  padding: 22px 24px 26px;
  display: flex;
  flex-direction: column;
  flex: 1;
}
.card-location {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--teal-deep);
  margin-bottom: 7px;
}
.card-name {
  font-family: var(--font-display);
  font-size: 1.375rem;
  color: var(--dark);
  font-weight: normal;
  line-height: 1.15;
  margin-bottom: 6px;
}
.card-type {
  font-size: 0.75rem;
  color: var(--muted);
  flex: 1;
  padding-bottom: 18px;
}
.card-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dark);
  transition: color var(--t), gap var(--t);
  padding-top: 18px;
  border-top: 1px solid var(--border);
}
.project-card:hover .card-link { color: var(--teal); gap: 13px; }
.card-link span { transition: transform var(--t); }
.project-card:hover .card-link span { transform: translateX(3px); }

/* ─── Project Detail — Hero ───────────────────────────────────────────────── */
.detail-hero {
  position: relative;
  height: 62vh;
  min-height: 420px;
  display: flex;
  align-items: flex-end;
  background-size: cover;
  background-position: center 30%;
  overflow: hidden;
}
.detail-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(12,9,7,0.80) 0%, rgba(12,9,7,0.12) 55%);
  z-index: 1;
}
.detail-hero-inner {
  position: relative;
  z-index: 2;
  padding-bottom: 60px;
  width: 100%;
}
.breadcrumb {
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 0.75rem;
  color: rgba(255,255,255,0.45);
  letter-spacing: 0.07em;
  margin-bottom: 18px;
}
.breadcrumb a { color: rgba(255,255,255,0.45); transition: color var(--t); }
.breadcrumb a:hover { color: var(--teal); }
.breadcrumb span { color: rgba(255,255,255,0.25); }

.detail-hero-inner h1 {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 5vw, 4.375rem);
  color: var(--white);
  font-weight: normal;
  line-height: 1.04;
  letter-spacing: 0.01em;
  margin-bottom: 18px;
}
.detail-meta {
  display: flex;
  gap: 28px;
  flex-wrap: wrap;
}
.detail-meta span {
  font-size: 0.75rem;
  color: rgba(255,255,255,0.55);
  letter-spacing: 0.06em;
}
.detail-meta span strong {
  color: rgba(255,255,255,0.85);
  font-weight: 500;
  margin-right: 6px;
}

/* ─── Project Detail — Body ───────────────────────────────────────────────── */
.detail-body {
  display: grid;
  grid-template-columns: 1fr 340px;
  gap: 70px;
  padding: 80px 0 100px;
}
.detail-main { min-width: 0; }

.detail-heading {
  font-family: var(--font-display);
  font-size: clamp(1.625rem, 3vw, 2.375rem);
  font-weight: normal;
  color: var(--dark);
  line-height: 1.12;
  margin-bottom: 20px;
}
.detail-desc {
  font-size: 0.9375rem;
  line-height: 1.85;
  color: var(--body-text);
  margin-bottom: 18px;
  max-width: 580px;
}

/* Specs grid */
.specs-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin: 44px 0;
}
.spec-cell {
  padding: 20px 22px;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  background: var(--white);
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.spec-cell:nth-child(2n)      { border-right: none; }
.spec-cell:nth-last-child(-n+2) { border-bottom: none; }
.spec-label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.spec-value {
  font-family: var(--font-display);
  font-size: 1.1875rem;
  color: var(--dark);
}

/* Units */
.units-section { margin-top: 60px; padding-top: 60px; border-top: 1px solid var(--border); }
.section-subhead {
  font-family: var(--font-display);
  font-size: 1.5rem;
  color: var(--dark);
  font-weight: normal;
  margin-bottom: 28px;
}
.units-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 14px;
}
.unit-card {
  display: block;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 20px 20px;
  transition: border-color var(--t), box-shadow var(--t);
  color: inherit;
  text-decoration: none;
}
.unit-card:not(.unavailable):hover {
  border-color: var(--teal);
  box-shadow: 0 6px 20px rgba(0,0,0,0.06);
}
.unit-card.unavailable { opacity: 0.42; }

.unit-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 12px;
}
.unit-id {
  font-family: var(--font-display);
  font-size: 1.0625rem;
  color: var(--dark);
}
.unit-status {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 2px;
  flex-shrink: 0;
}
.unit-status.available { background: var(--teal-faint); color: var(--teal-deep); border: 1px solid rgba(91, 147, 196,0.4); }
.unit-status.reserved  { background: rgba(58,54,50,0.07); color: var(--muted); border: 1px solid var(--border); }
.unit-status.sold      { background: rgba(26,26,26,0.05); color: var(--muted); border: 1px solid var(--border); }

.unit-type  { font-size: 0.75rem; color: var(--muted); margin-bottom: 3px; }
.unit-area  { font-size: 0.75rem; color: var(--muted); margin-bottom: 10px; }
.unit-price { font-size: 0.9375rem; font-weight: 600; color: var(--dark); }

/* Gallery Sidebar */
.detail-sidebar { min-width: 0; }
.gallery-sticky {
  position: sticky;
  top: calc(var(--header-h) + 32px);
}
.gallery-main {
  overflow: hidden;
  border-radius: var(--radius);
  margin-bottom: 10px;
  cursor: pointer;
}
.gallery-main img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform 0.45s ease;
}
.gallery-main:hover img { transform: scale(1.03); }
.gallery-thumbs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.gallery-thumb {
  overflow: hidden;
  border-radius: var(--radius);
  cursor: pointer;
  border: 2px solid transparent;
  transition: border-color var(--t);
}
.gallery-thumb img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  opacity: 0.55;
  transition: opacity var(--t);
}
.gallery-thumb:hover img,
.gallery-thumb.active img { opacity: 1; }
.gallery-thumb.active      { border-color: var(--teal); }

/* ─── Enquire CTA ─────────────────────────────────────────────────────────── */
.enquire-cta {
  background: var(--dark);
  padding: 88px var(--gutter);
}
.enquire-inner {
  max-width: var(--max-w);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 60px;
  align-items: center;
}
.enquire-text .label { color: var(--teal); }
.enquire-text h2 {
  font-family: var(--font-display);
  font-size: clamp(1.625rem, 3vw, 2.5rem);
  color: var(--white);
  font-weight: normal;
  margin-bottom: 14px;
}
.enquire-text p {
  font-size: 0.875rem;
  color: rgba(255,255,255,0.48);
  max-width: 440px;
  line-height: 1.7;
}
.enquire-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex-shrink: 0;
}

/* ─── About Page ──────────────────────────────────────────────────────────── */
.about-story { background: var(--cream); }
.story-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  align-items: center;
}
.story-text { min-width: 0; }
.story-text h2 {
  font-family: var(--font-display);
  font-size: clamp(1.625rem, 3vw, 2.5rem);
  color: var(--dark);
  font-weight: normal;
  line-height: 1.12;
  margin-bottom: 24px;
}
.story-text p {
  font-size: 0.9375rem;
  line-height: 1.85;
  color: var(--body-text);
  margin-bottom: 18px;
}
.story-image { position: relative; isolation: isolate; }
.story-image img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: var(--radius);
}
.story-image::after {
  content: '';
  position: absolute;
  top: -14px; right: -14px;
  width: 55%;
  height: 55%;
  border: 2px solid var(--teal);
  border-radius: var(--radius);
  z-index: -1;
}

/* Stats row */
.about-stats {
  background: var(--dark);
  padding: 96px 0;
  border-top: 1.5px solid var(--teal);
}
.stats-row {
  display: flex;
  align-items: center;
  justify-content: center;
}
.stat-item {
  text-align: center;
  flex: 1;
  padding: 0 40px;
  position: relative;
}
.stat-item:not(:last-child)::after {
  content: '';
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 52px;
  width: 1px;
  background: rgba(232,228,223,0.1);
}
.stat-number {
  font-family: var(--font-display);
  font-size: 3.875rem;
  color: var(--white);
  line-height: 1;
  margin-bottom: 12px;
  letter-spacing: -0.01em;
}
.stat-label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(232,228,223,0.38);
}

/* Pillars */
.about-pillars { background: var(--cream); }
.section-head { margin-bottom: 56px; }
.section-head h2 {
  font-family: var(--font-display);
  font-size: clamp(1.625rem, 3vw, 2.375rem);
  color: var(--dark);
  font-weight: normal;
}
.pillars-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  background: transparent;
  border: none;
  overflow: visible;
}
.pillar-card {
  background: var(--dark);
  padding: 48px 38px;
  border-radius: var(--radius);
  transition: transform var(--t), box-shadow var(--t);
}
.pillar-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 24px 52px rgba(0,0,0,0.3);
}
.pillar-icon {
  font-size: 1.25rem;
  color: var(--teal);
  margin-bottom: 22px;
}
.pillar-card h3 {
  font-family: var(--font-display);
  font-size: 1.375rem;
  color: var(--white);
  font-weight: normal;
  margin-bottom: 14px;
}
.pillar-card p {
  font-size: 0.84375rem;
  color: rgba(232,228,223,0.52);
  line-height: 1.75;
}

/* Team CTA strip */
.about-team-cta { background: var(--cream-dark); }
.team-cta-inner {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 60px;
  align-items: center;
}
.team-cta-inner h2 {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.8vw, 2.25rem);
  color: var(--dark);
  font-weight: normal;
  margin-bottom: 14px;
}
.team-cta-inner p {
  font-size: 0.875rem;
  color: var(--muted);
  max-width: 500px;
  line-height: 1.75;
}
/* override btn-outline for light bg */
.about-team-cta .btn-teal { color: var(--white); }

/* ─── Services Page ───────────────────────────────────────────────────────── */
.services-section { padding-top: 40px; }
.service-block {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 48px;
  min-height: 380px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 24px;
  background: var(--white);
  transition: box-shadow 0.4s ease, border-color 0.4s ease;
}
.service-block:hover {
  box-shadow: 0 16px 48px rgba(0,0,0,0.09);
  border-color: transparent;
}
/* left bar — draws top to bottom */
.service-block::before,
.service-block::after {
  content: '';
  position: absolute;
  top: 0;
  width: 3px;
  height: 100%;
  background: var(--teal);
  transform: scaleY(0);
  transition: transform 0.45s ease;
  pointer-events: none;
  z-index: 3;
  border-radius: 1px;
}
.service-block::before {
  left: -1px;
  transform-origin: top center;
}
.service-block::after {
  right: -1px;
  transform-origin: bottom center;
  transition-delay: 0.07s;
}
.service-block:hover::before,
.service-block:hover::after { transform: scaleY(1); }
/* even: push image to right */
.service-block:nth-child(even) .service-image { order: 2; }
.service-block:nth-child(even) .service-text  { order: 1; }

.service-text {
  padding: 48px 52px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: var(--cream);
}
.service-block:nth-child(even) .service-text { background: var(--white); }

.service-text h2 {
  font-family: var(--font-display);
  font-size: clamp(1.375rem, 2.4vw, 1.875rem);
  color: var(--dark);
  font-weight: normal;
  margin: 10px 0 14px;
}
.service-text p {
  font-size: 0.875rem;
  line-height: 1.75;
  color: var(--body-text);
  max-width: 420px;
  margin-bottom: 10px;
}
.service-list {
  list-style: none;
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.service-list li {
  font-size: 0.8125rem;
  color: var(--muted);
  padding-left: 18px;
  position: relative;
}
.service-list li::before {
  content: '–';
  position: absolute;
  left: 0;
  color: var(--teal);
}

.service-image {
  position: relative;
  overflow: hidden;
}
.service-image img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.6s ease;
}
.service-block:hover .service-image img { transform: scale(1.03); }

/* ─── Partners Page ───────────────────────────────────────────────────────── */
.partners-intro { padding-bottom: 0; }
.partners-intro-inner { max-width: 600px; }
.partners-intro-inner h2 {
  font-family: var(--font-display);
  font-size: clamp(1.625rem, 3vw, 2.375rem);
  color: var(--dark);
  font-weight: normal;
  margin-bottom: 20px;
}
.partners-intro-inner p {
  font-size: 0.9375rem;
  color: var(--body-text);
  line-height: 1.8;
}

.partners-grid-section { padding-top: 64px; }
.partners-category { margin-bottom: 72px; }
.partners-category > .label { margin-bottom: 28px; }

.partners-logo-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.partner-logo-cell {
  background: var(--white);
  padding: 44px 32px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  filter: grayscale(1) opacity(0.45);
  transition: filter var(--t);
  min-height: 130px;
}
.partner-logo-cell:hover { filter: grayscale(0) opacity(1); }
.partner-logo-cell img { max-height: 44px; width: auto; max-width: 100%; }
.partner-logo-cell span {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--muted);
  text-align: center;
}

/* Partner CTA card */
.partner-cta-section { padding-top: 0; }
.partner-cta-card {
  background: var(--cream-dark);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 64px 56px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 48px;
  align-items: center;
}
.partner-cta-text h2 {
  font-family: var(--font-display);
  font-size: 1.75rem;
  color: var(--dark);
  font-weight: normal;
  margin-bottom: 10px;
}
.partner-cta-text p {
  font-size: 0.84375rem;
  color: var(--muted);
  max-width: 460px;
  line-height: 1.7;
}
/* btn-teal on light bg */
.partner-cta-card .btn-teal { color: var(--white); flex-shrink: 0; }

/* ─── Contacts Page ───────────────────────────────────────────────────────── */
.contacts-section { padding: 0; }
.contacts-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  padding: 88px 0 100px;
}
/* A grid item's default min-width is `auto`, i.e. min-content — so a 1fr track
   is not actually free to shrink, it has a floor set by the widest unbreakable
   thing inside it. Without this the contact form's textarea (see the width:100%
   note above) and a long address/email string pin the track wider than the
   viewport at 320px. min-width:0 lets the track do what 1fr says it does. */
.contacts-grid > * { min-width: 0; }

.contact-form-wrap h2 {
  font-family: var(--font-display);
  font-size: 1.875rem;
  color: var(--dark);
  font-weight: normal;
  margin-bottom: 32px;
}

.contact-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.form-group {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.form-group label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.form-group input,
.form-group textarea,
.form-group select {
  font-family: var(--font-body);
  font-size: 0.875rem;
  color: var(--dark);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 16px;
  outline: none;
  transition: border-color var(--t), box-shadow var(--t);
  resize: vertical;
  -webkit-appearance: none;
  /* width:100% is not cosmetic. A <textarea> without it is sized from its `cols`
     attribute (default 20) in the CURRENT font, and an <input> from `size`
     (default 20). That intrinsic width is the min-content of the .contacts-grid
     1fr track, so the track cannot shrink below it and the whole column overflows
     the viewport — silently, because html,body carry overflow-x: clip.
     Measured on contacts.html at 320px with the reader's text size at 119%
     (root 19px): the textarea wanted 323px inside a 272px container, taking the
     form, the info column and everything in them 27px off the right edge.
     At the 16px default it wanted 276px against the same 272px, so this was
     already 4px over before the type scale moved to rem — the rem change only
     made an existing bug big enough to see. Pair it with the min-width:0 on the
     grid items below; either alone leaves the track stuck at min-content. */
  width: 100%;
}
.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
  border-color: var(--teal);
  box-shadow: 0 0 0 3px rgba(91, 147, 196,0.15);
}
.form-group textarea { min-height: 140px; }
.form-submit { width: 100%; justify-content: center; margin-top: 4px; }

.contact-info { padding-top: 8px; }
.contact-info h2 {
  font-family: var(--font-display);
  font-size: 1.875rem;
  color: var(--dark);
  font-weight: normal;
  margin-bottom: 36px;
}
.info-block {
  margin-bottom: 36px;
  padding-bottom: 36px;
  border-bottom: 1px solid var(--border);
}
.info-block:last-of-type { border-bottom: none; }
.info-block h4 {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--teal);
  margin-bottom: 10px;
}
.info-block p {
  font-size: 0.875rem;
  color: var(--body-text);
  line-height: 1.7;
}
.info-block a { color: var(--teal-deep); transition: color var(--t); }
.info-block a:hover { color: var(--teal); }
.info-hours { font-size: 0.75rem; color: var(--muted); margin-top: 6px; }

.contact-social {
  display: flex;
  gap: 16px;
  margin-top: 4px;
}
.social-link {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  transition: color var(--t);
}
.social-link:hover { color: var(--teal); }

.map-placeholder {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--cream-dark);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-top: 36px;
}

/* ─── Footer ──────────────────────────────────────────────────────────────── */
.site-footer {
  background: var(--footer-bg);
  color: var(--footer-text);
}
/* padding-block, NOT the padding shorthand — and this is load-bearing.
   The markup is <div class="footer-inner container"> on all nine pages.
   .container (:215) and .footer-inner have IDENTICAL specificity (0,1,0), and
   .footer-inner is declared later, so a `padding: 72px 0 56px` shorthand here
   silently resets padding-left/right to 0 and the footer loses its gutter
   entirely. Measured 2026-08-13 before the fix: at 844px wide the brand block,
   the column headings and the legal line all started at x=0 — flush against the
   glass. --max-w is 1200px, so this was every window from 769px to 1200px, i.e.
   desktop too, on every page. It is the "text is too close to the border of the
   section" the client reported twice.
   padding-block touches only the block axis, so .container's inline padding
   survives and the footer inherits the same 40px/24px gutter as every other
   section. If you ever need to change the vertical rhythm here, edit these two
   values — do NOT reach for the shorthand. Same rule for .footer-bottom below
   and for the phone override in the max-width:768px block. */
.footer-inner {
  padding-block: 72px 56px;
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: 44px;
}

.footer-logo {
  height: 44px;
  width: auto;
  filter: brightness(0) invert(1) opacity(0.75);
  margin-bottom: 18px;
}
/* Alpha raised 0.42 -> 0.68 on 2026-08-13: measured 1.85:1 against the footer as
   it actually rendered (see the glass block below for why it renders light). */
.footer-brand p {
  font-size: 0.78125rem;
  color: rgba(232,228,223,0.68);
  line-height: 1.65;
  max-width: 200px;
}
.footer-social {
  display: flex;
  gap: 14px;
  margin-top: 20px;
}
/* 10px at alpha 0.38. The phone block at the end of this file already raised
   both for touch and legibility; desktop was still 10px/0.38, which is how
   landscape phones (which take the desktop CSS, see the max-height gate) ended
   up with a 14x18px "FB" link. Now 12px/0.70 everywhere. */
.footer-social a {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  color: rgba(232,228,223,0.70);
  transition: color var(--t);
}
.footer-social a:hover { color: var(--teal); }

.footer-col h4 {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--teal);
  margin-bottom: 22px;
}
.footer-col ul { display: flex; flex-direction: column; gap: 11px; }
/* Alpha raised 0.52 -> 0.72 on 2026-08-13: measured 2.02:1. The phone block near
   the end of this file already carried the note that 0.52 is roughly 3:1 and
   under AA, and fixed it at 0.78 for phones only; this is the desktop half of
   the same fix. Keep the two in step. */
.footer-col ul li,
.footer-col ul a {
  font-size: 0.78125rem;
  color: rgba(232,228,223,0.72);
  transition: color var(--t);
}
.footer-col ul a:hover { color: var(--teal); }

/* padding-block for the same reason as .footer-inner above — the markup is
   <div class="footer-bottom container"> and the shorthand would zero the gutter. */
.footer-bottom {
  padding-block: 22px;
  border-top: 1px solid rgba(232,228,223,0.08);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
/* Copyright, "Privacy Policy · Terms of Use", .footer-attrib and .footer-credit.
   Was rgba(232,228,223,0.28) and measured 1.52-1.73:1 on 2026-08-13 — a third of
   the 4.5:1 AA needs at this size.
   READ THIS BEFORE RETUNING THE NUMBER. The alpha alone cannot fix it, and the
   obvious "raise it to 0.62" is measurably wrong: over the footer as it rendered
   before today, 0.62 gives 2.34:1, not the ~4.6:1 it looks like on paper. The
   reason is that this footer is NOT dark. .site-footer paints a translucent dark
   gradient over `backdrop-filter: blur(42px)`, and on projects/services/contacts/
   partners/thank-you the thing being blurred is the cream page body, so the
   rendered slab measured rgb(120,116,111) — a mid grey. Light text on mid grey
   has a hard ceiling: even fully opaque #E8E4DF only reaches 3.67:1 there.
   So the ground was darkened (see the glass block below) AND the ink raised.
   Measure with the ink set to `transparent`, screenshot the box, and composite
   the declared rgba over those pixels; sampling ink pixels directly lies. */
.footer-bottom p {
  font-size: 0.75rem;
  color: rgba(232,228,223,0.72);
  letter-spacing: 0.04em;
}

/* ─── Liquid / Morphic Glass Footer (global) ─────────────────────────────── */
/* THE ALPHAS ON THE LINEAR GRADIENT ARE A CONTRAST FIX, NOT A STYLE PREFERENCE.
   They were 0.55 / 0.68 / 0.60. With `backdrop-filter: blur(42px)` below, a
   translucent dark layer over a CREAM page body composites to a mid grey, and
   that is what every page except index/about actually rendered: measured
   rgb(120,116,111) on projects.html at 1440x900 on 2026-08-13. Every piece of
   footer text is light (var(--footer-text) #E8E4DF at various alphas), and light
   ink on rgb(120,116,111) tops out at 3.67:1 even at alpha 1.0 — the whole
   footer was below AA and no ink change could rescue it. Measured then:
     .footer-bottom p   1.52:1     .footer-col ul a   2.02:1
     .footer-brand p    1.85:1
   Raising the alphas to 0.86/0.93/0.88 pulls the slab back to rgb(64..72), which
   is where --footer-bg (#3A3632) always intended it to be, and every ratio above
   then clears AA once the inks below are also raised. The radial teal/terracotta
   tints, the blur, the sheen and the wordmark are all untouched, so the liquid
   glass look survives — it is simply dark glass again instead of frosted grey.
   Lower these numbers and the whole footer goes back under 2:1. */
.site-footer {
  background:
    radial-gradient(120% 90% at 15% 0%, rgba(121,199,212,0.10) 0%, rgba(121,199,212,0) 45%),
    radial-gradient(110% 100% at 85% 100%, rgba(201,123,90,0.12) 0%, rgba(201,123,90,0) 50%),
    linear-gradient(160deg, rgba(38,33,28,0.86) 0%, rgba(20,17,14,0.93) 55%, rgba(28,23,19,0.88) 100%) !important;
  backdrop-filter: blur(42px) saturate(1.7) !important;
  -webkit-backdrop-filter: blur(42px) saturate(1.7) !important;
  border-top: 1px solid rgba(255,255,255,0.14);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.10),
    inset 0 -40px 80px rgba(0,0,0,0.25) !important;
}
/* moving liquid sheen across the glass */
.site-footer::before {
  content: '';
  position: absolute;
  inset: -60% -20%;
  background: linear-gradient(115deg,
    transparent 30%,
    rgba(255,255,255,0.045) 42%,
    rgba(255,255,255,0.09) 50%,
    rgba(255,255,255,0.045) 58%,
    transparent 70%);
  z-index: 0;
  pointer-events: none;
  animation: footer-sheen 9s ease-in-out infinite alternate;
}
@keyframes footer-sheen {
  from { transform: translateX(-18%) rotate(0.001deg); }
  to   { transform: translateX(18%)  rotate(0.001deg); }
}
@media (prefers-reduced-motion: reduce) {
  .site-footer::before { animation: none; }
}
.footer-bottom {
  border-top: 1px solid rgba(255,255,255,0.08) !important;
}

/* ─── Hero Glass Overlays ─────────────────────────────────────────────────── */
.hero-glass-left {
  position: absolute;
  left: 84px;
  top: 460px;
  width: 421px;
  min-height: 491px;
  background: rgba(217,217,217,0.23);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  border-radius: 20px;
  border: 1px solid rgba(255,255,255,0.15);
  z-index: 22;
  padding: 32px 36px 36px;
  display: flex;
  flex-direction: column;
  pointer-events: auto;
  transition: opacity 0.4s ease;
}
.hero-glass-name {
  font-family: 'Nolluqa', Georgia, serif;
  font-size: 4rem;
  color: #fff;
  text-align: center;
  line-height: 1;
  margin-bottom: 20px;
}
.hero-glass-desc {
  font-family: 'Liquefier', Georgia, serif;
  font-size: 0.875rem;
  color: rgba(255,255,255,0.85);
  line-height: 1.7;
  flex: 1;
}
.hero-glass-desc p + p { margin-top: 10px; }
.hero-glass-more {
  display: inline-block;
  margin-top: 22px;
  align-self: flex-start;
  background: rgba(217,217,217,0.23);
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 6px;
  padding: 4px 16px;
  font-family: 'Liquefier', Georgia, serif;
  font-size: 0.875rem;
  color: #fff;
  cursor: pointer;
  transition: background 0.2s;
  text-decoration: none;
}
.hero-glass-more:hover { background: rgba(255,255,255,0.22); }

.hero-glass-oval {
  position: absolute;
  right: -60px;
  top: 288px;
  width: 414px;
  height: 412px;
  background: rgba(255,255,255,0.15);
  border-radius: 119px;
  z-index: 22;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  overflow: hidden;
  pointer-events: none;
}
.hero-oval-img {
  border-radius: 20px;
  object-fit: cover;
  display: block;
  flex-shrink: 0;
}
.hero-oval-img--top    { width: 152px; height: 78px; }
.hero-oval-img--mid    { width: 209px; height: 106px; }
.hero-oval-img--bottom { width: 152px; height: 78px; }

/* ─── Building Cards ──────────────────────────────────────────────────────── */
.buildings-cards {
  position: relative;
  z-index: 2;
  display: flex;
  gap: 28px;
  align-items: flex-start;
  flex-wrap: wrap;
  justify-content: center;
  margin-bottom: 52px;
}
.b-card {
  width: 296px;
  height: 417px;
  border-radius: 20px;
  overflow: hidden;
  position: relative;
  backdrop-filter: blur(3.4px);
  -webkit-backdrop-filter: blur(3.4px);
  background: rgba(255,255,255,0.18);
  transition: transform 0.4s ease, box-shadow 0.4s ease;
  cursor: pointer;
}
.b-card:hover { transform: translateY(-6px); box-shadow: 0 24px 52px rgba(0,0,0,0.35); }
.b-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 20px;
  transition: transform 0.5s ease;
}
.b-card:hover img { transform: scale(1.04); }
.b-card-hover {
  position: absolute;
  bottom: -90px;
  left: 0;
  right: 0;
  padding: 20px 18px 18px;
  background: linear-gradient(to top, rgba(0,0,0,0.82) 0%, rgba(0,0,0,0.4) 60%, transparent 100%);
  transition: bottom 0.38s cubic-bezier(0.25,1,0.5,1);
}
.b-card:hover .b-card-hover,
.b-card--active .b-card-hover { bottom: 0; }
.b-card-line {
  height: 1px;
  background: rgba(255,255,255,0.5);
  margin-bottom: 10px;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.32s ease 0.08s;
}
.b-card:hover .b-card-line,
.b-card--active .b-card-line { transform: scaleX(1); }
.b-card-name {
  display: block;
  font-family: 'Nolluqa', Georgia, serif;
  font-size: 1.75rem;
  color: #fff;
  line-height: 1.1;
  margin-bottom: 4px;
}
.b-card-price {
  display: block;
  font-family: 'Liquefier', Georgia, serif;
  font-size: 0.75rem;
  color: rgba(255,255,255,0.8);
  letter-spacing: 1.2px;
}

/* Glass pill CTA */
.glass-pill-btn {
  position: relative;
  z-index: 2;
  display: inline-block;
  background: rgba(217,217,217,0.23);
  border: 1px solid rgba(255,255,255,0.25);
  border-radius: 22px;
  padding: 10px 44px;
  font-family: 'Nolluqa', Georgia, serif;
  font-size: 1.375rem;
  color: #fff;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  letter-spacing: 0.03em;
  transition: background 0.25s, border-color 0.25s;
  text-decoration: none;
}
.glass-pill-btn:hover {
  background: rgba(255,255,255,0.22);
  border-color: rgba(255,255,255,0.45);
}

/* ─── Parallax Stack (Aura slides over Buildings) ─────────────────────────── */
.parallax-stack-outer {
  position: relative;
  z-index: 3;
}

/* ─── Aura Feature Section ────────────────────────────────────────────────── */
.aura-section {
  position: relative;
  height: 100vh;
  min-height: 600px;
  background: url('assets/images/apartments/aura-hero.jpg') center/cover no-repeat;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 100px var(--gutter);
}
.aura-section::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.15) 40%, rgba(0,0,0,0.45) 100%);
}
.aura-title-wrap {
  position: relative;
  z-index: 2;
  text-align: center;
  margin-bottom: 12px;
}
.aura-name {
  display: block;
  font-family: 'Nolluqa', Georgia, serif;
  font-size: clamp(4.5rem, 10vw, 8rem);
  color: #fff;
  text-align: center;
  text-shadow: 0 4px 4px rgba(0,0,0,0.25);
  line-height: 0.95;
}
.aura-name.blur-copy {
  position: absolute;
  top: 0; left: 0; right: 0;
  filter: blur(4.4px);
  pointer-events: none;
}
.aura-subtitle-wrap {
  position: relative;
  z-index: 2;
  text-align: center;
  margin-bottom: 48px;
}
.aura-subtitle {
  display: block;
  font-family: 'Liquefier', Georgia, serif;
  font-size: clamp(1.375rem, 3.2vw, 3.0625rem);
  color: #fff;
  text-align: center;
  text-shadow: 0 4px 4px rgba(0,0,0,0.25);
  max-width: 800px;
  line-height: 1.3;
}
.aura-subtitle.blur-copy {
  position: absolute;
  top: 0; left: 0; right: 0;
  filter: blur(3.8px);
  pointer-events: none;
  color: #fff;
}
.aura-side-card {
  position: absolute;
  width: min(588px, 38vw);
  height: min(301px, 20vw);
  overflow: hidden;
  z-index: 2;
  border-radius: 4px;
}
.aura-side-card img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center bottom;
  display: block;
}
.aura-side-left  { left: min(123px, 6vw); top: 296px; }
.aura-side-right { right: min(123px, 6vw); top: 580px; }

/* ─── Why Adivia Section ──────────────────────────────────────────────────── */
.why-section {
  position: relative;
  background: #f7f5f2;
  padding: 100px var(--gutter);
  overflow: hidden;
}
.why-section::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(to right, transparent, rgba(0,0,0,0.12), transparent);
}
.why-inner {
  max-width: 1200px;
  margin: 0 auto;
}
.why-heading-wrap {
  text-align: center;
  margin-bottom: 64px;
}
.why-label {
  display: block;
  font-family: 'Liquefier', Georgia, serif;
  font-size: 0.75rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: rgba(100,90,80,0.7);
  margin-bottom: 16px;
}
.why-title {
  font-family: 'Nolluqa', Georgia, serif;
  font-size: clamp(2.25rem, 4vw, 3.625rem);
  color: #1a1612;
  font-weight: normal;
}
.why-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  background: rgba(0,0,0,0.06);
  border-radius: 16px;
  overflow: hidden;
}
/* min-width:0 + overflow-wrap for the same grid reason as .contacts-grid above.
   .why-card-title is set in Liquefier at 1.375rem with 0.06em tracking, and the
   Bulgarian copy contains single words like "ПРОСТРАНСТВА" that are longer than
   a narrow phone's content box. A grid item's automatic minimum is min-content —
   the longest unbreakable word — so the card was pinned WIDER than its own
   track and the right-hand side was destroyed by html,body{overflow-x:clip}.
   Measured on index.html at 320px, before this rule: card 288.2px inside a 272px
   track at the 16px default, and 328.7px (32.7px past the viewport) with the
   reader's text size at 119%. This predates the rem conversion — the 40px
   gutters this section used to hard-code made it worse still, at 240px of track.
   break-word only engages when a word genuinely cannot fit, so nothing changes
   at ordinary sizes; it is the difference between a hyphen-less line break and a
   card with its right edge cut off. */
.why-card {
  background: #fff;
  padding: 48px 36px;
  transition: background 0.3s;
  min-width: 0;
  overflow-wrap: break-word;
}
.why-card:hover { background: #f0ede8; }
.why-card-icon {
  font-family: 'Nolluqa', Georgia, serif;
  font-size: 2.5rem;
  color: rgba(160,130,100,0.55);
  margin-bottom: 20px;
  line-height: 1;
}
.why-card-title {
  font-family: 'Liquefier', Georgia, serif;
  font-size: 1.375rem;
  color: #1a1612;
  letter-spacing: 0.06em;
  margin-bottom: 14px;
}
.why-card-text {
  font-family: var(--font-body);
  font-size: 0.84375rem;
  color: rgba(30,24,18,0.55);
  line-height: 1.75;
}

/* ─── Contact Strip Section ───────────────────────────────────────────────── */
.cta-strip {
  position: relative;
  background: #f7f5f2;
  padding: 100px var(--gutter);
  text-align: center;
  overflow: hidden;
}
.cta-strip::before { display: none; }
.cta-strip-inner {
  position: relative;
  z-index: 2;
  max-width: 680px;
  margin: 0 auto;
}
.cta-strip-title {
  font-family: 'Nolluqa', Georgia, serif;
  font-size: clamp(2.25rem, 4.5vw, 4rem);
  color: #1a1612;
  margin-bottom: 20px;
}
.cta-strip-sub {
  font-family: 'Liquefier', Georgia, serif;
  font-size: clamp(0.9375rem, 1.8vw, 1.375rem);
  color: rgba(30,22,14,0.6);
  line-height: 1.65;
  margin-bottom: 44px;
}
.cta-strip-btns {
  display: flex;
  gap: 16px;
  justify-content: center;
  flex-wrap: wrap;
}
.cta-strip .glass-pill-btn {
  background: rgba(30,22,14,0.08);
  border-color: rgba(30,22,14,0.2);
  color: #1a1612;
  backdrop-filter: none;
}
.cta-strip .glass-pill-btn:hover {
  background: rgba(30,22,14,0.14);
  border-color: rgba(30,22,14,0.35);
}
.cta-strip .btn-outline {
  color: #1a1612;
  border-color: rgba(30,22,14,0.3);
}
.cta-strip .btn-outline:hover {
  border-color: #1a1612;
  color: #1a1612;
}

/* ─── Scroll Reveal ───────────────────────────────────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.65s ease, transform 0.65s ease;
}
.reveal.delay-1 { transition-delay: 0.1s; }
.reveal.delay-2 { transition-delay: 0.2s; }
.reveal.delay-3 { transition-delay: 0.3s; }
.reveal.visible { opacity: 1; transform: translateY(0); }

/* ─── Responsive ──────────────────────────────────────────────────────────── */
@media (max-width: 1024px) {
  .projects-grid { grid-template-columns: repeat(2, 1fr); }
  .detail-body   { grid-template-columns: 1fr; gap: 48px; }
  .detail-sidebar { order: -1; }
  .gallery-sticky { position: static; }
  .story-grid    { grid-template-columns: 1fr; gap: 48px; }
  .story-image   { max-width: 540px; }
  .stats-row     { flex-wrap: wrap; }
  .stat-item     { flex: 0 0 50%; padding: 32px 0; }
  .stat-item:not(:last-child)::after { display: none; }
  .service-block { grid-template-columns: 1fr; min-height: auto; gap: 0; }
  .service-block:nth-child(even) .service-image,
  .service-block:nth-child(even) .service-text { order: 0; }
  .service-image { aspect-ratio: 16 / 8; }
  .service-image img { position: relative; height: 100%; }
  .enquire-inner { grid-template-columns: 1fr; }
  .enquire-actions { flex-direction: row; }
  .partners-logo-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-inner { grid-template-columns: 1fr 1fr; gap: 40px 44px; }
  .contacts-grid { grid-template-columns: 1fr; gap: 60px; }
}

/* This tablet band still fires on a landscape phone (844x390 is <=1024 and
   >=769). That is harmless: all three of its declarations are re-declared in the
   phone block below at the same specificity and later in the file, so the phone
   values win. Do not "tidy" this by adding the height clause here without
   re-checking those three selectors. */
@media (max-width: 1024px) and (min-width: 769px) {
  .why-grid { grid-template-columns: repeat(2, 1fr); }
  .aura-side-card { display: none; }
  .hero-glass-oval { display: none; }
}

/* ═══ THE PHONE GATE ═══════════════════════════════════════════════════════
   `(max-width: 768px), (max-height: 500px)` — this exact pair, byte for byte,
   in three places: every phone-layout block in this file, the gates in
   index.html's inline <style>, and MOBILE_INSPECT in hero3d/hero-light.js.
   They must agree or a device gets half a layout.

   Why the height clause exists. index.html picks the hero tier with
   `Math.min(screen.width, screen.height) < 820`, i.e. a SHORT-SIDE test — on the
   SCREEN since 2026-08-20, on the window before that, so that resizing a desktop
   browser can no longer downgrade the hero. Either way a phone in
   landscape is 844x390 with a 390 short side, so it loads the phone hero and the
   argument that follows is untouched by that move. Every layout
   gate used to be a WIDTH test at 768px, and 844 is not under 768, so the same
   device got the DESKTOP stylesheet. Measured at 844x390 on 2026-08-13, before
   the fix:
     footer padding-left/right      0px, text flush at x=0
     .footer-social a ("FB")        14.3 x 17.5 px   (44x44 minimum)
     .footer-col ul a               35.2 x 17.7 px
     .footer-col h4                 9.5px
     .as-info card                  546px tall inside a 390px viewport, top at
                                    y = -78, cut off at both ends
   That is the whole "landscape falls apart" report, and it is one predicate
   disagreeing with another. 500px is the ceiling because 390 (the short side of
   the common phones) must match while a genuinely small desktop window at, say,
   600px tall must not.
   Consequence to be aware of, and it is deliberate: a 1440x480 desktop window
   now takes the phone layout. That is the agreed trade — a short viewport is
   treated as a phone regardless of width. ═══════════════════════════════════ */
@media (max-width: 768px), (max-height: 500px) {
  .hero-glass-left { left: 20px; right: 20px; width: auto; top: auto; bottom: 140px; min-height: auto; padding: 20px 22px 24px; }
  .hero-glass-name { font-size: 2.5rem; }
  .hero-glass-oval { display: none; }
  .scroll-body-text { left: 50%; top: auto; bottom: 10%; transform: translateX(-50%); max-width: 90%; text-align: center; }
  .scroll-body-text.sv-visible { transform: translateX(-50%); }
  .buildings-section { padding: 60px 20px 80px; }
  .buildings-cards { gap: 16px; }
  .b-card { width: 260px; height: 370px; }
  .aura-side-card { display: none; }
  .why-grid { grid-template-columns: 1fr; }
  .cta-strip-btns { flex-direction: column; align-items: center; }

  /* One place, one number. .container, .banner-inner, .enquire-cta,
     .aura-section, .why-section and .cta-strip all read this, so a phone gets
     the same left edge in every band on the page. Before this token
     .why-section / .cta-strip / .aura-section stayed at 40px on a 320px screen
     while .container was at 24px, and the step between adjacent sections was
     visible. .header-inner keeps its own 20px on purpose — on phones the header
     is a 400px floating pill, not a full-bleed band, so it is not a gutter. */
  :root { --gutter: 24px; }
  .header-inner { padding: 0 20px; grid-template-columns: 40px 1fr 40px; }
  .site-header::before, .site-header::after { display: none; }

  /* Floating centered glass pill — not full width */
  .site-header,
  .site-header.scrolled {
    /* THE OTHER SAFE-AREA IDIOM, and the pill is the reason the two exist.
       The desktop header is a full-bleed band whose glass must reach the top of
       the screen, so it pads. The pill is a detached, rounded, 400px-wide object
       floating BELOW the top edge — nothing about it wants to be under the island,
       and padding it would just make a 56px pill 115px tall with a bald crown.
       So it moves instead: `max(12px, --sat + 8px)`.

       Measured on an iPhone 15 Pro (--sat:59): 12px -> 67px. That reads like the
       pill fell down the screen, and it is the opposite. Before viewport-fit=cover
       the layout viewport STARTED at y=59 on the glass, so `top:12px` put the pill
       at y=71 in real screen coordinates. It now sits at y=67 — 4px HIGHER than the
       client sees today, with the same 8px of air under the island that 12px gave it
       under the old status bar. Nothing moved down; the page got taller underneath it.

       padding-top:0 undoes the base rule's `padding-top: var(--sat)`. Without it the
       pill would inherit a 59px pad inside a 56px box and `.header-inner`'s height:100%
       would resolve against a clamped-to-zero content box — the logo and burger vanish.
       This is the whole reason the reset is here and not left implicit.

       max() and not calc(): at --sat:0 max(12px, 8px) is 12px exactly, so Android,
       desktop and every non-notched phone keep the pill they have to the pixel. */
    top: max(12px, calc(var(--sat, 0px) + 8px));
    padding-top: 0;
    left: 50%;
    right: auto;
    width: min(92vw, 400px);
    height: 56px;
    transform: translateX(-50%);
    border-radius: 999px;
    background: rgba(30, 28, 26, 0.45);
    backdrop-filter: blur(24px) saturate(1.6);
    -webkit-backdrop-filter: blur(24px) saturate(1.6);
    border: 1px solid rgba(255,255,255,0.18);
    box-shadow: 0 10px 34px rgba(0,0,0,0.25);
    overflow: visible;
  }
  /* CAUGHT BY MEASUREMENT, NOT BY READING — and it is the trap in insetting any
     top-anchored element that also has a "parked off-screen" state.
     -100% is 56px and the 16px is clearance, so this parks the pill 72px above
     where it sits. That was enough while it sat at top:12px (12 - 72 = -60, i.e.
     bottom edge at -4, fully gone). The moment `top` became max(12, --sat+8) the
     travel stopped covering the distance: at --sat:59 the pill starts at 67 and
     72px of lift leaves it at -5..51 — a hidden header sitting in plain sight
     behind the Dynamic Island. Measured at 393x852 as .nav-logo occupying y 1..45.
     The lift has to grow by exactly the same inset the offset grew by. At --sat:0
     this is calc(-100% - 16px) unchanged, so nothing without a notch moves. */
  .site-header.nav-hidden { transform: translate(-50%, calc(-100% - 16px - var(--sat, 0px))); }
  .site-header .nav-logo { padding: 0; grid-column: 2; justify-self: center; }
  .site-header .nav-logo img,
  .site-header.scrolled .nav-logo img { height: 34px; filter: brightness(0) invert(1); }
  .site-header .nav-toggle span,
  .site-header.scrolled .nav-toggle span { background: rgba(255,255,255,0.9); }

  .nav-links { display: none; }
  .nav-toggle { display: flex; }

  /* Mobile dropdown matches the pill: centered floating glass card */
  .nav-mobile {
    /* 80 = the pill's 12 top + 56 height + 12 of air. That 12px gap is the thing
       being preserved, so this tracks the pill's own max() with the same 68px of
       pill baked in: max(12,--sat+8) + 56 + 12. At --sat:0 both sides are 80px. */
    top: max(80px, calc(var(--sat, 0px) + 76px));
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    width: min(92vw, 400px);
    border-radius: 22px;
    border: 1px solid rgba(255,255,255,0.16);
    background: rgba(30, 28, 26, 0.72);
    backdrop-filter: blur(28px) saturate(1.6);
    -webkit-backdrop-filter: blur(28px) saturate(1.6);
    padding: 22px 26px 26px;
    box-shadow: 0 18px 50px rgba(0,0,0,0.35);
  }
  .nav-mobile ul a { color: rgba(255,255,255,0.9); }
  .nav-mobile .lang-current { color: rgba(255,255,255,0.85); }

  .page-banner { height: 44vh; min-height: 280px; padding-bottom: 48px; }
  .section { padding: 64px 0; }

  .projects-grid { grid-template-columns: 1fr; }
  .filter-bar { padding: 36px 0 28px; }

  .pillars-grid { grid-template-columns: 1fr; }
  .team-cta-inner { grid-template-columns: 1fr; }

  .service-text { padding: 48px 32px; }

  .partner-cta-card { grid-template-columns: 1fr; }
  .partners-logo-grid { grid-template-columns: repeat(2, 1fr); }

  /* padding-block, not the shorthand — see the note on .footer-inner (:1426).
     The shorthand here would re-introduce the zero-gutter bug on phones. */
  .footer-inner { grid-template-columns: 1fr; gap: 36px; padding-block: 56px 40px; }
  .footer-bottom { flex-direction: column; gap: 8px; text-align: center; }

  .form-row { grid-template-columns: 1fr; }
  .detail-meta { flex-direction: column; gap: 10px; }
  .gallery-thumbs { grid-template-columns: repeat(3, 1fr); }
  .enquire-actions { flex-direction: column; }
  .enquire-cta { padding: 56px var(--gutter); }

  .about-stats { padding: 52px 0; }
  .stats-row { flex-wrap: wrap; }
  .stat-item { flex: 0 0 50%; padding: 24px 0; }

  /* ── General phone polish ── */
  html { -webkit-text-size-adjust: 100%; }
  body { overflow-x: hidden; }

  /* Ready-projects rows: smaller type, tighter spacing */
  .pl-row { padding: 26px 6vw; gap: 14px; }
  .pl-name { font-size: clamp(1.5rem, 7.5vw, 2.5rem); }
  .pl-meta { display: none; }

  /* Filter bar: one horizontal line that SCROLLS instead of clipping.
     The previous version was `flex-wrap: nowrap; justify-content: space-between`
     with `.filter-btn { flex: 1; font-size: 9.5px }`, and in Russian it lost a
     filter completely. Measured 2026-08-13 on projects.html, lang=ru:
       320px viewport -> bar clientWidth 270, scrollWidth 333,
                         4th button's right edge at x=358  (38px off-screen)
       344px viewport -> clientWidth 294, scrollWidth 333, same right edge
     and because html,body carry `overflow-x: clip` (end of this file) the
     overflow is not scrollable either — "ПРЕДСТОЯЩИ" was simply gone. That is a
     real instance of the reported "some cards disappear".

     Three things have to be true together or it still hides:
       1. overflow-x: auto            — turn the clip into a scroll
       2. justify-content: flex-start — `space-between` pins the first item and
                                        pushes the overflow off the RIGHT, where
                                        a scroll container cannot reach it
       3. .filter-btn { flex: 0 0 auto } — `flex: 1` forces the buttons to share
                                        the box, which is what made them overflow
                                        their own text in the first place
     Do NOT "fix" a future language by shrinking the type again: 9.5px was itself
     a finding (nothing meaningful on this site may sit under 12px). Scrolling
     costs nothing and works for any string length. */
  .filter-bar {
    display: flex;
    flex-wrap: nowrap;
    gap: 4px;
    justify-content: flex-start;
    width: 100%;
    padding: 5px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .filter-bar::-webkit-scrollbar { display: none; }
  .filter-lamp { display: none; }
  .filter-btn {
    padding: 10px 14px;
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    flex: 0 0 auto;
    scroll-snap-align: start;
    white-space: nowrap;
  }
  .filter-btn.active { background: var(--dark); color: #fff; border-radius: 999px; }

  /* Aura scene info panel + buttons stack nicely in static mobile mode */
  .as-info-link { padding: 11px 20px; font-size: 0.75rem; }
  .aura-scene.as-static .as-info-link { margin: 6px 4px 12px; }

  /* Footer wordmark scales down instead of overflowing */
  .footer-wordmark svg { height: 60%; }
  /* The two `.site-footer .footer-inner/.footer-bottom { padding-left/right: 24px }`
     patches that used to live here were removed on 2026-08-13. They existed only
     to paper over the padding-shorthand bug described at :1426, which is why the
     footer looked right on phones and was flush to the edge on every wider
     screen. Both elements carry .container, so once .footer-inner/.footer-bottom
     stopped resetting the inline axis they inherit --gutter (24px here) for free.
     Verified by measurement with these two rules deleted: padding-left/right
     computed 24px on all nine pages at 320/344/360/390. Do not re-add them —
     if the gutter is ever wrong again the bug is a shorthand, not a missing patch. */

  /* Page banners: top 35% of the screen, edge to edge */
  .page-banner {
    height: 35vh;
    height: 35svh;
    min-height: 220px;
    padding-bottom: 28px;
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center;
  }

  /* Language switcher in the mobile menu: proper dropdown, accordion-style —
     expands in place below the button (absolute positioning misplaced it and
     made it look stuck open), closed by default, tap toggles */
  .nav-mobile .lang-dropdown-item { flex-direction: column; align-items: center; }
  .nav-mobile .lang-current { display: flex; color: rgba(255,255,255,0.85); }
  .nav-mobile .lang-menu {
    display: none;
    position: static;
    transform: none;
    margin-top: 10px;
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.14);
    border-radius: 12px;
    box-shadow: none;
    min-width: 170px;
  }
  .nav-mobile .lang-dropdown-item.open .lang-menu { display: block; }
  .nav-mobile .lang-option { color: rgba(255,255,255,0.75); text-align: center; }
  .nav-mobile .lang-option:hover { color: #fff; background: rgba(255,255,255,0.08); }
  .nav-mobile .lang-option.active { color: #fff; }
}

/* ─── Banner slide-over effect ────────────────────────────────────────────── */
.page-banner {
  position: relative;
  z-index: 0;
}
.page-banner + .section {
  position: relative;
  z-index: 1;
  margin-top: -36px;
  border-radius: 22px 22px 0 0;
  background: var(--cream);
  box-shadow: 0 -6px 32px rgba(0,0,0,0.07);
}

/* ─── Language Loader Overlay ─────────────────────────────────────────────── */
#lang-loader {
  position: fixed;
  inset: 0;
  z-index: 9998;
  background: #0D0C0B;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 40px;
  pointer-events: all;
}
#lang-loader[hidden] { display: none; }
#lang-loader.fade-out {
  opacity: 0;
  transition: opacity 0.5s ease;
}
#lang-loader img {
  width: 140px;
  opacity: 0.92;
  filter: brightness(0) invert(1);
}
.lang-progress-track {
  width: min(340px, 70vw);
  height: 2px;
  background: rgba(255,255,255,0.12);
  border-radius: 2px;
  overflow: hidden;
}
.lang-progress-bar {
  height: 100%;
  width: 0%;
  background: var(--teal);
  border-radius: 2px;
}

/* ─── Language Dropdown ───────────────────────────────────────────────────── */
.lang-dropdown-item {
  position: relative;
  list-style: none;
  display: flex;
  align-items: center;
  transform: translateY(1.5px);
}

.lang-current {
  display: flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-body);
  font-size: 0.78125rem;
  font-weight: 400;
  letter-spacing: 0.07em;
  color: rgba(255,255,255,0.85);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  line-height: inherit;
  transition: color var(--t);
  white-space: nowrap;
}
.lang-current:hover,
.lang-dropdown-item.open .lang-current { color: var(--teal); }
.site-header.scrolled .lang-current { color: rgba(26,26,26,0.75); }
.site-header.scrolled .lang-current:hover,
.site-header.scrolled .lang-dropdown-item.open .lang-current { color: var(--teal); }

.lang-current svg { opacity: 0.5; transition: transform 0.2s ease; flex-shrink: 0; }
.lang-dropdown-item.open .lang-current svg { transform: rotate(180deg); }

.lang-menu {
  display: none;
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  background: rgba(245,242,238,0.97);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--border);
  border-radius: 4px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.10);
  min-width: 150px;
  z-index: 1000;
  padding: 6px 0;
  list-style: none;
}
.lang-dropdown-item.open .lang-menu { display: block; }

.lang-menu li { display: block; }
.lang-option {
  display: block;
  width: 100%;
  text-align: left;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--muted);
  background: none;
  border: none;
  cursor: pointer;
  padding: 9px 18px;
  transition: color var(--t), background var(--t);
}
.lang-option:hover { color: var(--dark); background: var(--cream-dark); }
.lang-option.active { color: var(--teal-deep); }

/* Mobile lang dropdown — inline row in mobile menu */
.nav-mobile .lang-dropdown-item {
  list-style: none;
  border-top: 1px solid var(--border);
  padding-top: 18px;
  margin-top: 10px;
  display: flex;
  justify-content: center;
}
.nav-mobile .lang-current { font-size: 0.75rem; }
.nav-mobile .lang-menu {
  top: calc(100% + 8px);
  right: auto;
  left: 50%;
  transform: translateX(-50%);
}

/* ─── How it works (contacts page) ──────────────────────────────────────── */
.how-it-works {
  background: var(--cream-dark);
  padding: 72px 0;
}
.how-it-works .section-intro {
  text-align: center;
  margin-bottom: 52px;
}
.how-it-works .section-intro h2 {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2.125rem);
  font-weight: normal;
  color: var(--dark);
  margin-bottom: 8px;
}
.how-it-works .section-intro p {
  font-size: 0.875rem;
  color: var(--muted);
}
.steps-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
}
.step {
  padding: 32px 28px;
  border-left: 1px solid var(--border);
  position: relative;
}
.step:first-child { border-left: none; }
.step-num {
  font-family: var(--font-display);
  font-size: 3.25rem;
  font-weight: normal;
  color: var(--teal);
  opacity: 0.55;
  line-height: 1;
  margin-bottom: 16px;
}
.step-title {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--dark);
  margin-bottom: 8px;
  letter-spacing: 0.02em;
}
.step-text {
  font-size: 0.8125rem;
  color: var(--muted);
  line-height: 1.7;
}
@media (max-width: 768px), (max-height: 500px) {
  .steps-grid {
    grid-template-columns: 1fr 1fr;
  }
  .step:nth-child(odd) { border-left: none; }
  .step:nth-child(n+3) { border-top: 1px solid var(--border); }
}
/* contacts.html at 320px: the two columns come out 171px each and .step's own
   32px/28px padding pushes steps 2 and 4 exactly 18px past the right edge.
   html,body { overflow-x: clip } (end of this file) means that overflow is
   destroyed rather than revealed — the text is truncated mid-word with no
   scrollbar to hint at it. Measured 2026-08-13: a config diff of 390px vs 320px
   on contacts.html reported exactly two elements CUT-OFF-RIGHT by 18px, both
   .step blocks. Fine from 344px up, hence the 360px ceiling rather than 768px. */
@media (max-width: 360px) {
  .steps-grid { grid-template-columns: 1fr; }
  .step { border-left: none; }
  .step:nth-child(n+2) { border-top: 1px solid var(--border); }
}

/* ─── Form field errors ──────────────────────────────────────────────────── */
.field-error {
  display: block;
  font-size: 0.75rem;
  color: #b94040;
  margin-top: 5px;
  letter-spacing: 0.01em;
}
.form-group input.has-error,
.form-group textarea.has-error {
  border-color: #b94040 !important;
  outline-color: #b94040;
}
.form-note {
  font-size: 0.75rem;
  color: var(--muted);
  margin-top: 10px;
  letter-spacing: 0.02em;
}

/* ─── Map link block (contacts page) ────────────────────────────────────── */
.map-link-block {
  margin-top: 24px;
  padding: 20px;
  background: var(--cream-dark);
  border-radius: var(--radius);
  border: 1px solid var(--border);
}
.map-link-block p {
  font-size: 0.8125rem;
  color: var(--body-text);
  line-height: 1.6;
  margin-bottom: 10px;
}
.map-link-block a {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--teal-deep);
  transition: color var(--t);
}
.map-link-block a:hover { color: var(--dark); }

/* ─── Pillar rows (about page) ───────────────────────────────────────────── */
.pillars-list { margin-top: 8px; }
.pillar-rule {
  border: none;
  border-top: 1px solid var(--border);
  margin: 0;
}
.pillar-row {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 32px;
  padding: 36px 0;
  align-items: start;
}
.pillar-row h3 {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2.2vw, 1.625rem);
  font-weight: normal;
  color: var(--dark);
  line-height: 1.25;
}
.pillar-row p {
  font-size: 0.875rem;
  color: var(--body-text);
  line-height: 1.75;
  max-width: 560px;
}
@media (max-width: 640px) {
  .pillar-row {
    grid-template-columns: 1fr;
    gap: 10px;
    padding: 28px 0;
  }
}

/* ═══ About — Loft-style scroll storytelling ═══════════════════════════════ */

/* Preloader */
.story-preloader {
  position: fixed; inset: 0; z-index: 9999;
  background: #000; color: #fff;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px; transition: opacity 0.9s ease, visibility 0.9s;
}
.story-preloader.done { opacity: 0; visibility: hidden; pointer-events: none; }
.story-preloader__logo { width: 54px; opacity: 0.9; }
.story-preloader__name {
  font-family: 'Noto Serif Display', Georgia, serif;
  font-weight: 300; font-size: 2rem; letter-spacing: 0.42em; text-indent: 0.42em;
}
.story-preloader__count {
  font-family: 'Noto Serif Display', Georgia, serif;
  font-weight: 300; font-size: 2.6rem; margin-top: 10px;
}
.story-preloader__track {
  width: 120px; height: 1px; background: rgba(255,255,255,0.22); overflow: hidden;
}
.story-preloader__track span {
  display: block; height: 100%; width: 0%;
  background: #fff; transition: width 0.25s ease;
}

/* Story container — long scroll runway */
.story { height: 1300vh; position: relative; background: #000; }
.story__sticky {
  position: sticky; top: 0; height: 100vh; overflow: hidden;
}
.story__video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
}
.story__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(0,0,0,0.42) 0%, rgba(0,0,0,0.12) 35%, rgba(0,0,0,0.12) 65%, rgba(0,0,0,0.5) 100%);
}

/* Stages */
.story-stage {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: center;
  padding: 0 clamp(24px, 7vw, 110px);
  opacity: 0; visibility: hidden;
  transform: translateY(46px);
  transition: opacity 0.9s cubic-bezier(0.22,1,0.36,1), transform 0.9s cubic-bezier(0.22,1,0.36,1), visibility 0.9s;
  will-change: opacity, transform;
  color: #fff;
  pointer-events: none;
}
.story-stage.active { opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto; }
.story-stage.passed { opacity: 0; visibility: hidden; transform: translateY(-46px); }
.story-stage--center { align-items: center; text-align: center; }
.story-stage--left { align-items: flex-start; text-align: left; max-width: none; }
.story-stage--left .story-p { max-width: 520px; }
.story-stage .label {
  color: rgba(255,255,255,0.75); letter-spacing: 0.3em; text-transform: uppercase;
  font-size: 0.75rem; margin-bottom: 18px;
}

.story-stage__mark { width: 64px; margin-bottom: 26px; opacity: 0.95; }

/* Typography */
.story-h {
  font-family: 'Noto Serif Display', Georgia, serif;
  font-weight: 300; line-height: 1.06; margin: 0 0 22px;
  text-shadow: 0 2px 30px rgba(0,0,0,0.35);
}
.story-h--xl { font-size: clamp(2.4rem, 6.4vw, 5.4rem); }
/* The About story headline is the one place on the site where a single word is
   wider than a 320px phone. .story-stage gives 272px of content there, and the
   longest Bulgarian word in the copy measured 300.6px at the clamp's 2.4rem
   minimum — 28.6px past the right edge at the DEFAULT text size, and 356.9px
   (60.9px over) with the reader's text size at 119%. It is destroyed rather
   than revealed, because html,body carry overflow-x: clip.
   overflow-wrap does NOT help here: the word-by-word reveal wraps each word in
   `.story-h .w` as an inline-block with overflow:hidden, so there is nothing for
   the line breaker to break. Lowering the clamp minimum is the fix that works
   with the animation instead of against it. 1.7rem/8.5vw resolves to 27.2px at
   320px (word 212.9px, fits) and 32.3px at 320px with 119% text (252.8px, fits)
   while staying fluid. Scoped to <=360px so the headline is unchanged on every
   phone that was already fine. */
@media (max-width: 360px) {
  .story-h--xl { font-size: clamp(1.7rem, 8.5vw, 5.4rem); }
}
.story-script {
  font-family: 'Nolluqa', 'Noto Serif Display', Georgia, serif;
  font-style: normal; font-weight: 400;
  font-size: 1.18em; letter-spacing: 0.01em;
}
.story-sub, .story-p {
  color: rgba(255,255,255,0.85);
  font-weight: 300; font-size: clamp(0.95rem, 1.35vw, 1.12rem);
  line-height: 1.75; max-width: 560px; margin: 0 0 26px;
  text-shadow: 0 1px 18px rgba(0,0,0,0.45);
}

/* Word-by-word reveal */
.story-h .w {
  display: inline-block; overflow: hidden; vertical-align: bottom;
}
.story-h .w > span {
  display: inline-block; transform: translateY(115%);
  transition: transform 0.85s cubic-bezier(0.22,1,0.36,1);
  transition-delay: calc(var(--i) * 90ms);
}
.story-stage.active .story-h .w > span { transform: translateY(0); }

/* Start-here button */
.story-start {
  border: 1px solid rgba(255,255,255,0.55); background: rgba(0,0,0,0.25);
  color: #fff; padding: 13px 34px; cursor: pointer;
  font-family: inherit; font-size: 0.78rem; letter-spacing: 0.28em; text-transform: uppercase;
  backdrop-filter: blur(4px); transition: background 0.35s, border-color 0.35s;
}
.story-start:hover { background: rgba(255,255,255,0.14); border-color: #fff; }

/* Stats */
.story-stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(20px, 5vw, 72px);
}
.story-stats .stat-number {
  display: block; font-family: 'Noto Serif Display', Georgia, serif;
  font-weight: 300; font-size: clamp(2.4rem, 5vw, 4.4rem); color: #fff;
}
.story-stats .stat-label {
  display: block; margin-top: 8px; color: rgba(255,255,255,0.72);
  font-size: 0.78rem; letter-spacing: 0.18em; text-transform: uppercase;
}

/* Progress line (bottom, grows with scroll) */
.story__progress {
  position: absolute; left: clamp(24px, 7vw, 110px); right: clamp(24px, 7vw, 110px); bottom: 34px;
  height: 1px; background: rgba(255,255,255,0.22);
}
.story__progress-fill {
  display: block; height: 100%; width: 0%;
  background: #fff; transition: width 0.2s linear;
}
.story__progress::after {
  content: ''; position: absolute; right: -1px; top: -3px;
  width: 7px; height: 7px; background: #fff;
  transform: rotate(45deg); opacity: 0.85;
}

@media (max-width: 720px) {
  .story { height: 1000vh; }
  .story-stats { grid-template-columns: repeat(2, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  .story-stage, .story-h .w > span { transition: none; }
}

/* ── Permanent liquid-glass header (about page) ── */
.site-header.header-liquid.scrolled::before {
  background: rgba(255,255,255,0.08);
  backdrop-filter: blur(16px) saturate(1.5);
  -webkit-backdrop-filter: blur(16px) saturate(1.5);
}
.site-header.header-liquid.scrolled::after {
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 30' preserveAspectRatio='none'%3E%3Cpath d='M0 1 L455 1 Q500 28 545 1 L1000 1' stroke='white' stroke-opacity='0.55' stroke-width='1.5' fill='none'/%3E%3C/svg%3E") no-repeat;
  background-size: 100% 100%;
}
.site-header.header-liquid.scrolled { box-shadow: 0 2px 28px rgba(0,0,0,0.25); }
.site-header.header-liquid.scrolled .nav-links a { color: rgba(255,255,255,0.85); }
.site-header.header-liquid.scrolled .nav-links a:hover,
.site-header.header-liquid.scrolled .nav-links a.active { color: #fff; }
.site-header.header-liquid.scrolled .nav-logo img { filter: brightness(0) invert(1); }
.site-header.header-liquid.scrolled .nav-toggle span { background: #fff; }
.site-header.header-liquid.scrolled .lang-current { color: rgba(255,255,255,0.85); }
.site-header.header-liquid.scrolled .lang-current:hover,
.site-header.header-liquid.scrolled .lang-dropdown-item.open .lang-current { color: #fff; }

/* ═══ After-story: clip-path zoom reveal + parallax service cards ══════════ */
.zoomrise {
  position: relative;
  background: #000;
  color: #fff;
  /* tall runway so the center image has room to un-clip while cards drift */
  min-height: 280vh;
}
.zoomrise__center {
  position: sticky; top: 0;
  height: 100vh; width: 100%;
  background-position: center;
  background-repeat: no-repeat;
  background-size: 170%;
  /* JS drives --zr-clip (25→0) and --zr-bgsize / opacity */
  clip-path: polygon(
    calc(var(--zr-clip, 25) * 1%) calc(var(--zr-clip, 25) * 1%),
    calc(100% - var(--zr-clip, 25) * 1%) calc(var(--zr-clip, 25) * 1%),
    calc(100% - var(--zr-clip, 25) * 1%) calc(100% - var(--zr-clip, 25) * 1%),
    calc(var(--zr-clip, 25) * 1%) calc(100% - var(--zr-clip, 25) * 1%)
  );
}
.zoomrise__cards {
  position: absolute; inset: 0;
  max-width: 1060px; margin: 0 auto;
  padding: 26vh 24px 0;
  display: flex; flex-direction: column;
}
.zoomrise__label { color: rgba(255,255,255,0.7); letter-spacing: 0.3em; text-transform: uppercase; font-size: 0.75rem; }
.zoomrise__head {
  font-size: clamp(1.9rem, 4vw, 3.4rem);
  margin: 10px 0 60px; max-width: 640px;
  text-shadow: 0 2px 30px rgba(0,0,0,0.55);
}

.zoomrise-card {
  position: relative; display: block;
  overflow: hidden; text-decoration: none; color: #fff;
  will-change: transform;
  box-shadow: 0 24px 60px rgba(0,0,0,0.45);
  transition: box-shadow 0.35s ease;
}
.zoomrise-card img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  transition: transform 0.6s cubic-bezier(0.22,1,0.36,1);
}
.zoomrise-card:hover img { transform: scale(1.045); }
.zoomrise-card__meta {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px;
  background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.72) 100%);
  font-size: 0.92rem; letter-spacing: 0.06em;
}
.zoomrise-card__title { font-weight: 500; }
.zoomrise-card__arrow {
  transition: transform 0.35s ease;
  font-size: 1.1rem;
}
.zoomrise-card:hover .zoomrise-card__arrow { transform: translateX(6px); }

.zoomrise-card--left  { width: 36%; aspect-ratio: 4/3; }
.zoomrise-card--wide  { width: 62%; aspect-ratio: 16/9; margin: 90px auto 0; }
.zoomrise-card--right { width: 38%; aspect-ratio: 4/3; margin: 90px 0 0 auto; }

.zoomrise__fade {
  position: absolute; left: 0; right: 0; bottom: 0; height: 300px;
  background: linear-gradient(180deg, rgba(0,0,0,0) 0%, #0d0d0d 100%);
  pointer-events: none;
}

@media (max-width: 720px) {
  .zoomrise { min-height: 220vh; }
  .zoomrise-card--left, .zoomrise-card--wide, .zoomrise-card--right { width: 86%; margin: 46px auto 0; }
}

/* ── Zoomrise v2: cards rise over the story video's last frame ── */
.zoomrise {
  margin-top: -100vh;          /* overlap the story's final pinned viewport */
  position: relative; z-index: 5;
  background: linear-gradient(180deg,
    rgba(0,0,0,0)   0,
    rgba(0,0,0,0)   60vh,
    rgba(0,0,0,0.9) 130vh,
    #0d0d0d         100%);
  min-height: 340vh;
}
.zoomrise__center { display: none; }
.zoomrise__cards { padding-top: 40vh; }

/* cards flow normally so the section grows with its content */
.zoomrise__cards { position: relative; inset: auto; padding-bottom: 26vh; }
.zoomrise { min-height: 0; }

/* ── Zoomrise v3: fixed last-frame background + growing final card ── */
.zoomrise {
  background:
    linear-gradient(180deg, rgba(0,0,0,0) 0, rgba(0,0,0,0) 50vh, rgba(0,0,0,0.55) 120vh, rgba(0,0,0,0.55) 100%),
    url('assets/images/about-story-last.jpg') center / cover no-repeat fixed;
}
.zoomrise__fade { display: none; }

.zoomrise-final { height: 220vh; }
.zoomrise-final__sticky {
  position: sticky; top: 0; height: 100vh;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.zoomrise-final__card {
  /* --grow: 0 → card, 1 → full screen; driven by JS */
  width: calc(52vw + (100vw - 52vw) * var(--grow, 0));
  height: calc(56vh + (100vh - 56vh) * var(--grow, 0));
  position: relative;
}
.zoomrise-final__card img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.zoomrise-final__card .zoomrise-card__meta {
  opacity: calc(1 - var(--grow, 0) * 1.6);
}

/* ── Floating flip-cards arc (ported from Framer component) ── */
.floatarc {
  height: 380vh;
  position: relative;
  background: #0d0d0d;
  color: #fff;
}
.floatarc__sticky {
  position: sticky; top: 0; height: 100vh;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.floatarc__intro, .floatarc__content {
  position: absolute; z-index: 2;
  text-align: center; pointer-events: none;
  padding: 0 24px;
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.floatarc__intro { top: 50%; transform: translateY(-50%); }
.floatarc__intro h2 { font-size: clamp(1.8rem, 3.6vw, 3rem); margin: 0 0 14px; }
.floatarc__hint {
  font-size: 0.75rem; letter-spacing: 0.3em; text-transform: uppercase;
  color: rgba(255,255,255,0.55); margin: 0;
}
.floatarc__content { top: 12%; opacity: 0; transform: translateY(20px); }
.floatarc__content.visible { opacity: 1; transform: translateY(0); }
.floatarc__content h2 { font-size: clamp(1.9rem, 4vw, 3.2rem); margin: 0 0 14px; }
.floatarc__content p { color: rgba(255,255,255,0.72); max-width: 520px; margin: 0 auto; line-height: 1.7; font-size: 0.95rem; }
.floatarc__intro.hidden { opacity: 0; transform: translateY(-50%) scale(0.97); }

.floatarc__stage { position: absolute; inset: 0; z-index: 1; }

.flipcard {
  position: absolute; left: 50%; top: 50%;
  width: 76px; height: 106px;
  margin: -53px 0 0 -38px;
  perspective: 1000px;
  will-change: transform, opacity;
  pointer-events: auto;
}
.flipcard__inner {
  position: relative; width: 100%; height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.6s cubic-bezier(0.22,1,0.36,1);
}
.flipcard:hover .flipcard__inner { transform: rotateY(180deg); }
.flipcard__face {
  position: absolute; inset: 0;
  border-radius: 10px; overflow: hidden;
  backface-visibility: hidden;
  box-shadow: 0 10px 26px rgba(0,0,0,0.45);
}
.flipcard__face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.flipcard__face--back {
  transform: rotateY(180deg);
  background: #14181d;
  border: 1px solid rgba(255,255,255,0.14);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px;
}
.flipcard__face--back .t1 {
  font-size: 0.75rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: #79c7d4; font-weight: 700;
}
.flipcard__face--back .t2 { font-size: 0.75rem; color: #fff; }

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

/* ── Zoomrise v4: seamless fixed end-frame, no overlap seam ── */
.zoomrise {
  /* No negative margin: the fixed background is pixel-identical to the video's
     last frame, so the hand-off is invisible without overlapping the story. */
  margin-top: 0;
  background:
    linear-gradient(180deg, rgba(0,0,0,0.25) 0, rgba(0,0,0,0.45) 100%),
    url('assets/images/about-story-last.jpg') center / cover no-repeat fixed;
}
.zoomrise__cards { padding-top: 18vh; }

.zoomrise-final__card video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}

/* ── Floatarc overlaps the grown full-screen card ── */
.floatarc {
  margin-top: -100vh;
  background: linear-gradient(180deg,
    rgba(13,13,13,0) 0,
    rgba(13,13,13,0.55) 70vh,
    #0d0d0d 130vh,
    #0d0d0d 100%);
  z-index: 6;
}

/* ── Compact textured footer that rises over the spinning cards ── */
.site-footer.footer-compact {
  position: relative; z-index: 10;
  margin-top: -60vh;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.05 0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E"),
    #14100c;
  box-shadow: 0 -18px 60px rgba(0,0,0,0.5);
}
.site-footer.footer-compact .footer-inner {
  padding-top: 44px; padding-bottom: 26px;
  gap: 28px;
}
.site-footer.footer-compact .footer-inner p,
.site-footer.footer-compact .footer-col li { font-size: 0.82rem; }
.site-footer.footer-compact .footer-logo { max-width: 110px; }
.site-footer.footer-compact .footer-bottom { padding-top: 12px; padding-bottom: 16px; }

/* ── Zoomrise v5: transparent — the pinned story video IS the background ── */
.zoomrise {
  background: none;
  min-height: 0;
}
.zoomrise__cards { padding-top: 24vh; }

/* ── Zoomrise v6: cards begin only AFTER the video story runway ── */
.story { height: auto; }               /* height now comes from content */
.zoomrise { margin-top: 1200vh; }      /* 1300vh runway − 100vh sticky = text/video portion */
@media (max-width: 720px) {
  .zoomrise { margin-top: 900vh; }
}

/* ── Footer: placed at the very end, textured, with space above ── */
.site-footer.footer-compact {
  margin-top: 0;                       /* footer sits flush against the last section */
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 0.95 0 0 0 0 0.85 0 0 0 0.13 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E"),
    linear-gradient(180deg, #1a140e 0%, #120d09 100%);
  box-shadow: none;
}

/* ── Floatarc finale: center card zooms into the CTA background ── */
.floatarc { height: 480vh; }

.floatarc__zoomcard {
  /* --zc: 0 = small card in the middle, 1 = full-screen background */
  position: absolute; left: 50%; top: 50%; z-index: 2;
  transform: translate(-50%, -50%);
  width: calc(140px + (100vw - 140px) * var(--zc, 0));
  height: calc(190px + (100vh - 190px) * var(--zc, 0));
  border-radius: calc(10px * (1 - var(--zc, 0)));
  overflow: hidden;
  opacity: 0;
  box-shadow: 0 20px 60px rgba(0,0,0,0.55);
  pointer-events: none;
}
.floatarc__zoomcard video { width: 100%; height: 100%; object-fit: cover; display: block; }

.floatarc__cta {
  position: absolute; inset: 0; z-index: 3;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 0 24px;
  opacity: 0; visibility: hidden; transform: translateY(30px);
  transition: opacity 0.8s ease, transform 0.8s ease, visibility 0.8s;
}
.floatarc__cta.visible { opacity: 1; visibility: visible; transform: translateY(0); }
.floatarc__cta h2 {
  font-size: clamp(2.2rem, 5vw, 4.2rem); margin: 0 0 16px;
  text-shadow: 0 2px 30px rgba(0,0,0,0.5);
}
.floatarc__cta p {
  color: rgba(255,255,255,0.85); max-width: 460px; margin: 0 0 30px;
  line-height: 1.7; text-shadow: 0 1px 16px rgba(0,0,0,0.55);
}

/* ── Finale v2: Investment video card pins, zooms, and stays as background ── */
.zoomrise-final {
  /* 1.2 viewports of zooming + the entire arc/CTA ride on top of the pinned card */
  height: 600vh;
}
.floatarc {
  margin-top: -480vh;          /* rides entirely over the pinned full-screen video */
  height: 480vh;
  background: none;
}
.floatarc__sticky::before {   /* readability scrim over the video */
  content: '';
  position: absolute; inset: 0;
  background: rgba(0,0,0,0.35);
  pointer-events: none;
}
.floatarc__zoomcard { display: none; }

/* scrim fades in with the arc, not with the section edge (no black sheet during zoom) */
.floatarc__sticky::before {
  opacity: var(--fa-scrim, 0);
}

/* ─── Home scrollytelling (v2) ────────────────────────────────────────────── */
/* Shared easing tokens */
:root {
  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);
}

/* S1 — Manifesto */
.manifesto { position: relative; height: 220vh; background: var(--cream); }
.manifesto-sticky {
  position: sticky; top: 0; height: 100vh;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  overflow: hidden; text-align: center; padding: 0 6vw;
}
.manifesto-bgtext {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%) translateX(var(--kx, 0px));
  font-family: var(--font-display);
  font-size: clamp(10rem, 26vw, 24rem);
  line-height: 1; white-space: nowrap;
  color: transparent;
  -webkit-text-stroke: 1.5px rgba(91, 147, 196, 0.16);
  pointer-events: none; user-select: none;
  will-change: transform;
}
.manifesto-title {
  font-family: var(--font-display);
  font-size: clamp(3rem, 9vw, 8.5rem);
  line-height: 1.02; letter-spacing: 0.02em;
  color: var(--dark); margin: 0;
}
.manifesto-title .mw {
  display: inline-block;
  opacity: calc(0.12 + 0.88 * var(--wp, 0));
  transform: translateY(calc((1 - var(--wp, 0)) * 14px));
  will-change: transform, opacity;
}
.manifesto-title .mw-accent { font-family: var(--font-accent); color: var(--teal); }
.manifesto-body {
  max-width: 560px; margin: 36px auto 0;
  font-family: var(--font-body); font-size: clamp(0.9375rem, 1.4vw, 1.125rem);
  line-height: 1.8; color: var(--body-text);
  opacity: var(--bp, 0);
  transform: translateY(calc((1 - var(--bp, 0)) * 20px));
}

/* S2 — Projects showcase */
.showcase { position: relative; height: 300vh; background: var(--dark); }
.showcase-sticky {
  position: sticky; top: 0; height: 100vh;
  display: grid; grid-template-columns: 55% 45%; overflow: hidden;
}
.showcase-stage { position: relative; overflow: hidden; }
.showcase-img {
  position: absolute; inset: 0; margin: 0;
  clip-path: inset(0 0 100% 0);
  will-change: clip-path;
}
.showcase-img.is-active { clip-path: inset(0 0 0 0); }
.showcase-img img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transform: scale(var(--imgs, 1));
  will-change: transform;
}
.showcase-meta {
  position: relative; display: flex; flex-direction: column;
  justify-content: center; gap: 32px; padding: 0 5vw;
}
.showcase-eyebrow {
  font-family: var(--font-body); font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--teal);
}
.showcase-texts { position: relative; min-height: 240px; }
.showcase-text {
  position: absolute; inset: 0;
  opacity: 0; transform: translateY(24px);
  transition: opacity 360ms var(--ease-out-strong), transform 360ms var(--ease-out-strong);
  pointer-events: none;
}
.showcase-text.is-active { opacity: 1; transform: translateY(0); pointer-events: auto; }
.showcase-index {
  font-family: var(--font-display); font-size: clamp(3rem, 5vw, 5rem);
  color: var(--footer-text); line-height: 1;
}
.showcase-index em { font-style: normal; font-size: 0.4em; color: var(--muted); }
.showcase-name {
  font-family: var(--font-accent); font-size: clamp(2.4rem, 4vw, 4rem);
  color: #fff; margin: 10px 0 4px; line-height: 1.05;
}
.showcase-price { font-family: var(--font-body); font-size: 0.9375rem; color: var(--muted); margin: 0 0 18px; }
.showcase-link {
  display: inline-block; font-family: var(--font-body); font-size: 0.8125rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--teal); text-decoration: none;
  transition: transform 200ms var(--ease-out-strong);
}
@media (hover: hover) and (pointer: fine) {
  .showcase-link:hover { transform: translateX(6px); }
}
.showcase-rail { display: flex; gap: 14px; }
.showcase-rail .b-card { width: 132px; height: 186px; border-radius: 12px; opacity: 0.45; transition: opacity 280ms var(--ease-out-strong), transform 280ms var(--ease-out-strong); }
.showcase-rail .b-card.is-active { opacity: 1; transform: translateY(-6px); }
@media (hover: hover) and (pointer: fine) {
  .showcase-rail .b-card:hover { opacity: 1; }
}
.showcase-rail .b-card-name { font-size: 0.9375rem; }
.showcase-rail .b-card-price { font-size: 0.75rem; }

/* S3 — Living gallery */
.hgallery { position: relative; height: 300vh; background: var(--cream); }
.hgallery-sticky {
  position: sticky; top: 0; height: 100vh;
  display: flex; flex-direction: column; justify-content: center;
  overflow: hidden; gap: 44px;
}
.hgallery-head { padding: 0 6vw; display: flex; flex-direction: column; gap: 16px; }
.hgallery-title {
  font-family: var(--font-display); font-size: clamp(2.4rem, 5vw, 4.6rem);
  color: var(--dark); margin: 0; line-height: 1;
}
.hgallery-accent { font-family: var(--font-accent); color: var(--teal); }
.hgallery-progress { width: min(320px, 40vw); height: 2px; background: var(--border); }
.hgallery-progress span {
  display: block; height: 100%; background: var(--teal);
  transform: scaleX(var(--gp, 0)); transform-origin: left;
  will-change: transform;
}
.hgallery-track {
  display: flex; gap: 28px; padding: 0 6vw;
  transform: translateX(calc(var(--tx, 0) * 1px));
  will-change: transform;
}
.hg-card {
  position: relative; margin: 0; flex: 0 0 auto;
  width: clamp(280px, 30vw, 420px); height: clamp(380px, 58vh, 560px);
  border-radius: 14px; overflow: hidden;
}
.hg-card img {
  width: 112%; height: 100%; object-fit: cover; display: block;
  transform: translateX(var(--px, 0%));
  will-change: transform;
}
.hg-card figcaption {
  position: absolute; left: 18px; bottom: 16px;
  font-family: var(--font-body); font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: #fff; background: rgba(26,26,26,0.55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  padding: 8px 14px; border-radius: 999px;
  opacity: 0; transform: translateY(8px);
  transition: opacity 320ms var(--ease-out-strong), transform 320ms var(--ease-out-strong);
}
.hg-card.in-view figcaption { opacity: 1; transform: translateY(0); }

/* S5 — Stats row */
.stats-row {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px;
  margin: 0 0 56px;
}
.stat { text-align: center; padding: 28px 12px; }
.stat-num {
  display: block; font-family: var(--font-display);
  font-size: clamp(2.6rem, 4.5vw, 5rem); line-height: 1; color: var(--teal);
}
.stat-label {
  display: block; margin-top: 10px;
  font-family: var(--font-body); font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--muted);
}
.why-card { position: relative; }
.why-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: var(--teal); transform: scaleX(0); transform-origin: left;
  transition: transform 400ms cubic-bezier(0.22, 1, 0.36, 1) 120ms;
}
.why-card.visible::before { transform: scaleX(1); }

/* Marquee divider */
.marquee { overflow: hidden; background: var(--cream-dark); padding: 22px 0; white-space: nowrap; }
.marquee-track { display: inline-block; animation: marquee-slide 28s linear infinite; }
.marquee-track span {
  font-family: var(--font-display); font-size: clamp(1.4rem, 2.4vw, 2.2rem);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
}
@keyframes marquee-slide {
  from { transform: translateX(0); }
  to   { transform: translateX(-25%); }
}

/* Footer — giant hover-reveal wordmark */
.footer-wordmark { position: relative; display: block; width: 100%; margin-top: 8px; }
.footer-wordmark svg { display: block; width: 100%; height: auto; cursor: default; }
.fw-base   { fill: transparent; stroke: rgba(232, 228, 223, 0.16); stroke-width: 0.6; }
.fw-hover  { fill: transparent; stroke: rgba(232, 228, 223, 0.45); stroke-width: 0.6; opacity: 0; transition: opacity 300ms ease; }
.footer-wordmark:hover .fw-hover { opacity: 0.7; }
.fw-grad   { fill: transparent; stroke: url(#fw-gradient); stroke-width: 0.6; }

/* Mobile / un-pin fallbacks */
@media (max-width: 768px), (max-height: 500px) {
  /* Manifesto ("root of Adivia") and the services gallery keep their pinned
     scroll animations on phones; shorter runways for a snappier feel */
  .manifesto { height: 180vh; }
  /* long, calm scrub through the service cards.
     NOTE: this 500vh is dead on phones — script.js measure() overwrites the height
     with an inline `height: <vh + maxX>px` derived from the measured strip width.
     Editing this number changes nothing on mobile; edit measure() instead. */
  .hgallery { height: 500vh; }

  /* NO `align-items: center` HERE. It was removed on 2026-08-12 and must not come back.
     It was presumably added to centre .hgallery-head, but .hgallery-sticky is a COLUMN
     flex container, so align-items governs the HORIZONTAL axis and applied to every
     child — including .hgallery-track. Two things followed, and they were the two bugs
     reported on this section.

     First, `center` replaces the default `stretch`, so the track was sized shrink-to-fit
     instead of container-width. Its children are `flex: 0 0 auto` (styles.css:2994), so
     it could not shrink: it laid out at its full max-content width and was then centred.
     Measured on a 393px viewport: track = 23.58 + 8x280 + 7x28 + 23.58 = 2483.16px, so
     the centring offset was (393 - 2483.16) / 2 = -1045.08px. At scroll progress 0 the
     JS transform is translateX(0), so that -1045px WAS the starting position: cards 1-3
     (Residential, Commercial, Renovation) were off-screen at every scroll position and
     never rendered at all, and card 4 was clipped by 97.5 of its 280px — the "30-40%
     cut off" in the report. The visible "first card" was actually the fourth.

     Second, script.js:966 computes travel as `track.scrollWidth - innerWidth` = 2090px,
     which assumes the track starts at x=0. With the centring it started at -1045px, so
     the distance actually needed was only 1045px — exactly half. measure() then sized
     the pinned runway to the full 2090px, leaving 1045px of scroll (50% of the pin) in
     which nothing useful happened; for the last ~652px of it the strip was entirely off
     the left edge and the screen was blank cream. That reads as a frozen phone, which
     is exactly how it was reported.

     Both numbers are algebraically (trackWidth - viewportWidth)/2, so the fault was
     width-independent: every phone lost exactly half its pin and hid exactly half the
     strip. An earlier fix (script.js:948-978) replaced a hardcoded 500vh runway with the
     measured one and cut the dead scroll from 69% to 50% — a real improvement, but it
     corrected the SUPPLY of scroll rather than the DEMAND, so the symptom survived.
     Removing this one declaration makes the track's origin x=0, which makes
     `scrollWidth - innerWidth` the true travel and fixes both defects at once. */

  /* .hgallery-head already carries its own `padding: 0 6vw` (styles.css:2976) and so
     lines up with the track's first card on its own — it never needed centring. */

  .showcase { height: auto; }
  .showcase-sticky { position: static; height: auto; grid-template-columns: 1fr; }
  .showcase-stage { display: none; }
  .showcase-meta { padding: 70px 6vw; }
  .showcase-texts { min-height: 0; display: flex; flex-direction: column; gap: 40px; }
  .showcase-text { position: static; opacity: 1; transform: none; pointer-events: auto; }
  .showcase-rail { flex-wrap: wrap; }
  .showcase-rail .b-card { opacity: 1; }

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

@media (prefers-reduced-motion: reduce) {
  .manifesto { height: auto; }
  .manifesto-sticky { position: static; height: auto; padding: 90px 6vw; }
  .manifesto-title .mw, .manifesto-body { opacity: 1; transform: none; }
  .showcase { height: auto; }
  .showcase-sticky { position: static; height: auto; }
  .showcase-text { position: static; opacity: 1; transform: none; pointer-events: auto; }
  .showcase-texts { min-height: 0; display: flex; flex-direction: column; gap: 40px; }
  .hgallery { height: auto; }
  .hgallery-sticky { position: static; height: auto; padding: 70px 0; }
  .hgallery-track { transform: none !important; overflow-x: auto; }
  .hg-card figcaption { opacity: 1; transform: none; }
  .marquee-track { animation: none; }
  .why-card::before { transition: none; transform: scaleX(1); }
}

/* Cheap paint skips for below-the-fold static sections */
.why-section, .cta-strip { content-visibility: auto; contain-intrinsic-size: auto 100vh; }

.footer-wordmark { padding: 12px 4vw 0; }
/* The ONLY font-size in this file still declared in px, and it must stay that
   way. This <text> lives inside the wordmark <svg>, which is sized
   width:100%/height:100% against a viewBox — so 56 here is a USER-UNIT figure
   inside the viewBox coordinate system, scaled by the preserveAspectRatio
   transform, not a rendered pixel size. Converting it to rem would resolve it
   against the root font size and then scale it again, which changes the
   wordmark's proportion inside its own box (and would make it jump when a reader
   changes their browser's default text size). Everything else in this file moved
   to rem on 2026-08-13; this is the documented exception. */
.footer-wordmark text {
  font-family: var(--font-display), Georgia, serif;
  font-size: 56px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ─── Exploded house — scroll-scrubbed cinematic section ──────────────────── */
.exploded { position: relative; height: 320vh; background: var(--dark); }
.exploded-sticky {
  position: sticky; top: 0; height: 100vh; overflow: hidden;
}
.exploded-sticky video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.exploded-overlay {
  position: absolute; left: 6vw; bottom: 10vh; z-index: 2;
  max-width: 520px;
  opacity: var(--op, 0);
  transform: translateY(calc((1 - var(--op, 0)) * 24px));
}
.exploded-label {
  display: inline-block; margin-bottom: 16px;
  font-family: var(--font-body); font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.24em; text-transform: uppercase;
  color: #fff; background: rgba(26, 26, 26, 0.45);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.25);
  padding: 8px 16px; border-radius: 999px;
}
.exploded-title {
  font-family: var(--font-body); font-weight: 600;
  font-size: clamp(2.2rem, 4.6vw, 4.2rem);
  line-height: 1.04; letter-spacing: -0.03em;
  color: #fff; margin: 0 0 14px;
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.35);
}
.exploded-sub {
  font-family: var(--font-body); font-weight: 400;
  font-size: clamp(0.875rem, 1.25vw, 1rem); line-height: 1.65;
  color: rgba(255, 255, 255, 0.82); margin: 0;
}
.exploded-progress {
  position: absolute; left: 6vw; right: 6vw; bottom: 5vh; z-index: 2;
  height: 2px; background: rgba(255, 255, 255, 0.18);
}
.exploded-progress span {
  display: block; height: 100%; background: var(--teal);
  transform: scaleX(var(--gp, 0)); transform-origin: left;
  will-change: transform;
}
@media (max-width: 768px), (max-height: 500px) {
  .exploded { height: auto; }
  .exploded-sticky { position: static; height: auto; aspect-ratio: 16 / 10; }
  .exploded-overlay { opacity: 1; transform: none; bottom: 8vh; right: 6vw; }
  .exploded-progress { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .exploded { height: auto; }
  .exploded-sticky { position: static; height: auto; aspect-ratio: 16 / 10; }
  .exploded-overlay { opacity: 1; transform: none; }
  .exploded-progress { display: none; }
}

/* ─── Footer wordmark as background behind the columns ────────────────────── */
.site-footer {
  position: relative;
  overflow: hidden;

  /* ── The one place on the site where the home indicator traps content ──────
     Scrolled to the very end — which is a state every page reaches and cannot
     scroll out of — the last 34px of an iPhone's screen is the home-indicator
     band, and what was sitting in it was `.footer-bottom`: the copyright line and
     the "Privacy Policy / Terms of Use" LINKS. Measured at 393x852 on
     project-detail and thank-you before this rule existed: two anchors with
     bottoms at 835.8 and 873.5 against a 852px viewport. Body copy passing through
     the band mid-scroll is fine and expected — you want the hero running under the
     glass — but the document's final row has nowhere left to go.

     ON .site-footer AND NOT ON body, AND THIS IS THE WHOLE POINT OF THE TICKET.
     `body { padding-bottom }` would reserve the same 34px and paint it with body's
     #F5F2EE — a pale strip under a near-black footer, which is precisely the
     "white strip under the detail card that just sits there and does nothing" the
     client reported. Putting it on the footer means the band is filled by the
     footer's own dark glass: background reaches the physical bottom of the screen,
     legal links stop 34px short of it.

     var(--sab, 0px) is 0 on desktop and on Android, so this is `padding-bottom: 0`
     — a no-op — everywhere except a device that actually has a home indicator. */
  padding-bottom: var(--sab, 0px);
}
.footer-wordmark {
  position: absolute; inset: 0 0 auto 0; height: 100%;
  display: flex; align-items: center;
  padding: 0; margin: 0;
  z-index: 0; pointer-events: none;
}
.footer-wordmark svg { width: 100%; height: 100%; }
.footer-inner, .footer-bottom { position: relative; z-index: 1; }

/* ─── Mobile overrides (must stay LAST in this file to win the cascade) ───── */
@media (max-width: 768px), (max-height: 500px) {
  /* About story video: poster shown until the scrub loads (no black screen) */
  .story__video { background: url('assets/images/about-story-first.jpg') center / cover no-repeat; }

  /* Floating cards arc: text block pinned high, spinning cards pushed below it */
  .floatarc__content { top: 5%; }
  .floatarc__content h2 { font-size: clamp(1.5rem, 6.5vw, 2rem); }
  .floatarc__content p { font-size: 0.85rem; max-width: 88vw; }
  .floatarc__stage { top: 32vh; }
}

/* ─── Language switcher: chip in the top-right corner of the OPEN menu ────── */
@media (max-width: 768px), (max-height: 500px) {
  .nav-mobile { position: fixed; }   /* containing block for the chip */
  .nav-mobile .lang-dropdown-item {
    position: absolute;
    top: 12px;
    right: 12px;
    border: none; padding: 0; margin: 0;
    display: block;
    flex-direction: unset;
  }
  .nav-mobile .lang-current {
    display: flex;
    align-items: center;
    gap: 5px;
    height: 34px;
    padding: 0 12px;
    border-radius: 999px;
    border: 1px solid rgba(255,255,255,0.22);
    background: rgba(255,255,255,0.08);
    color: rgba(255,255,255,0.92);
    font-size: 0.75rem;
  }
  .nav-mobile .lang-menu {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    left: auto;
    transform: none;
    margin: 0;
    min-width: 160px;
    background: rgba(30,28,26,0.95);
    border: 1px solid rgba(255,255,255,0.16);
    border-radius: 12px;
    z-index: 5;
  }
  .nav-mobile .lang-dropdown-item.open .lang-menu { display: block; }
  /* menu links keep clear of the chip row */
  .nav-mobile > ul { padding-top: 8px; }
}

/* ─── No horizontal overflow anywhere (fixes white gutter when zoomed out) ── */
html { overflow-x: clip; }
body { overflow-x: clip; }


/* ==== Service partner chips (partners merged into services) ==== */
/* ── Partners strip (services page) ──────────────────────────────────────
   Logos are supplied as JPEGs on white, at wildly different aspect ratios
   (156x138 up to 1329x1329), so each sits in a fixed-height box and is
   contained rather than cropped. */
.partners-strip { padding-top: 0; }
.partners-head { text-align: center; margin-bottom: 34px; }
.partners-head h2 { margin-top: 8px; }
.partners-logos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 22px;
  align-items: stretch;
}
.partner-item {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 22px 18px;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--white);
}
.partner-item img {
  height: 84px;
  width: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;   /* JPEG whites blend into the card */
}
/* Logos carry no captions — two of the four companies have no published name —
   so the card is the logo alone and needs a little more height to breathe. */
.partner-item { padding: 30px 22px; }
@media (max-width: 600px) {
  .partners-logos { grid-template-columns: repeat(2, 1fr); gap: 14px; }
  .partner-item img { height: 64px; }
}

.service-partners { margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--border); }
.service-partners .sp-label { display: block; font-size: 0.75rem; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); margin-bottom: 12px; font-weight: 500; }
.sp-chips { display: flex; flex-wrap: wrap; gap: 10px; }
.sp-chip { display: inline-flex; align-items: center; gap: 9px; padding: 8px 14px 8px 10px; border: 1px solid var(--border); border-radius: 999px; background: var(--white); }
.sp-chip img { width: 20px; height: 20px; object-fit: contain; opacity: .85; }
.sp-chip-name { font-size: 0.8125rem; font-weight: 500; color: var(--dark); white-space: nowrap; }
.sp-chip-role { font-size: 0.75rem; color: var(--muted); white-space: nowrap; border-left: 1px solid var(--border); padding-left: 9px; }
@media (max-width: 640px) {
  .sp-chips { gap: 8px; }
  .sp-chip { padding: 7px 12px 7px 9px; }
}
/* ══════════════════════════════════════════════════════════════════════════════
   MOBILE REFINEMENTS — added 2026-08-11
   ══════════════════════════════════════════════════════════════════════════════
   Everything below is scoped to phone widths and changes nothing on desktop.
   It comes from a measured pass at 393x852 (iPhone 14 Pro, the device the report
   was written on), so the numbers are real measurements rather than estimates.

   The recurring theme is that this site was designed at desktop scale and then
   shrunk. Type sizes that read as "small caps detail" at 1440px become genuinely
   unreadable at 393px, and controls that are comfortable for a mouse cursor are
   below the size a fingertip can reliably hit. Apple's Human Interface Guidelines
   put the minimum touch target at 44x44pt; the audit found 19-24 controls per
   page under that, including the single most important one on the whole mobile
   site -- the hamburger, at 30x23.

   Kept as one block on purpose: it is the newest layer, so it wins the cascade
   without needing !important, and it can be reviewed or reverted in one piece.
   ══════════════════════════════════════════════════════════════════════════════ */

@media (max-width: 768px), (max-height: 500px) {

  /* ── Touch targets ──────────────────────────────────────────────────────────
     The hamburger measured 30x23. Rather than draw a bigger icon (which would
     change the design), the bars stay exactly as they are and the BUTTON grows
     to 44x44 around them: same look, more than double the hittable area. */
  .nav-toggle {
    width: 44px;
    height: 44px;
    padding: 0;
    align-items: center;
    justify-content: center;
    /* pull the extra width back out of the layout so the pill's 3-column grid
       does not shift -- the button overhangs its own box symmetrically */
    margin-right: -7px;
  }

  /* The logo is the "go home" control and measured 21x34. */
  .site-header .nav-logo {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0 10px;
  }

  /* Footer links measured 18px tall — under half the minimum, and stacked 11px
     apart, which on a phone means the wrong link is a real possibility. Padding
     rather than height so the visual rhythm of the column is untouched. */
  .footer-col ul { gap: 2px; }
  .footer-col ul li { display: flex; }
  .footer-col ul li a,
  .footer-col ul li {
    min-height: 40px;
    display: flex;
    align-items: center;
    font-size: 0.84375rem;
    /* 0.52 alpha on a dark ground is roughly 3:1 against the footer background —
       below the 4.5:1 WCAG AA threshold for body text. */
    color: rgba(232, 228, 223, 0.78);
  }

  /* ── Type that was too small to read ────────────────────────────────────────
     Measured on the phone: footer headings 9.5px, spec labels 9.5px, unit
     status 9px, legal line 11px. For scale, iOS refuses to render its own UI
     text below 11px and the body default is 17px. */
  .footer-col h4 {
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    margin-bottom: 14px;
    color: var(--teal);
  }
  .footer-bottom p,
  .footer-attrib,
  .footer-credit { font-size: 0.78125rem; line-height: 1.7; }
  .footer-brand p { font-size: 0.84375rem; line-height: 1.75; }

  /* The eyebrow labels ("── THE PROJECT") at 10.5px with 0.2em tracking are
     the section signposts; at that size the tracking makes them harder, not
     easier, to read. */
  .label { font-size: 0.75rem; letter-spacing: 0.14em; }

  /* Primary buttons: label was 11.5px and the button 43px tall — one pixel
     under the threshold, which is the kind of thing only a measurement finds. */
  .btn-teal,
  .btn-outline {
    min-height: 48px;
    font-size: 0.8125rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/* ── About us: story text over the scrubbing video ───────────────────────────
   Alex's report was "make the text bold, it's barely readable on phone". The
   measurement explains why, and it is not really about boldness:

     .story-p   -> 15.2px, font-weight 300 (Poppins Light), rgba(255,255,255,.85)
     behind it  -> .story__video (about-story-scrub.mp4), playing
     .story__scrim -> 0.42 alpha at the top, 0.50 at the bottom, and 0.12 across
                      the 35%-65% band, which is exactly the vertical band the
                      copy is centred in

   So the lightest weight in the family, at a size 1.8px under the iOS body
   default, in translucent white, sits over the one part of the frame that is
   deliberately NOT darkened, while the picture underneath keeps moving. On a
   desktop monitor at arm's length that reads as elegant restraint; on a phone
   held in one hand outdoors it is close to invisible.

   Fixed on three axes at once, because any one alone is not enough: darken the
   middle of the scrim, move Light 300 up to Regular 400, and take the text back
   to near-opaque white. The video is still clearly visible -- the scrim change
   is 0.12 -> 0.42, not a black box. */
@media (max-width: 768px), (max-height: 500px) {
  .story__scrim {
    background:
      linear-gradient(180deg,
        rgba(0,0,0,0.58) 0%,
        rgba(0,0,0,0.42) 30%,
        rgba(0,0,0,0.42) 70%,
        rgba(0,0,0,0.62) 100%);
  }
  .story-p {
    font-weight: 400;
    font-size: 1rem;
    line-height: 1.75;
    color: rgba(255,255,255,0.96);
    /* Last-resort legibility for the frames where the video goes bright: a
       shadow costs nothing when the backdrop is already dark. */
    text-shadow: 0 1px 12px rgba(0,0,0,0.55);
  }
  .story-h { text-shadow: 0 2px 18px rgba(0,0,0,0.5); }
  .story-sub {
    font-weight: 400;
    color: rgba(255,255,255,0.94);
    text-shadow: 0 1px 12px rgba(0,0,0,0.5);
  }
  .story-stage .label { color: rgba(255,255,255,0.9); }
}

/* ── After-hero: the building info card ──────────────────────────────────────
   Reported as "detail card takes 50-60% of screen, background almost non
   visible". Measured at 393x852 it was 338 x 368 -- 86% of the width and 43%
   of the height, and because it is a frosted-glass panel the building behind
   it is not merely covered, it is blurred.

   The card is doing three jobs: name the building, describe it, link to it.
   On a phone the description is the part that costs the most height and adds
   the least -- the visitor is looking at the building, not reading a paragraph.
   So the paragraph is clamped to three lines, the padding comes in, and the
   facts list goes horizontal. That takes the card to roughly 250px, about 29%
   of the screen, and leaves the building as the subject of the frame.

   NOTE ON THE SELECTORS: index.html carries its own <style> block at line 128,
   AFTER the <link> to this file at line 110. The aura scene is styled entirely
   in there, so a plain `.as-info` rule here loses the cascade to an identical
   `.as-info` rule in that block — same (0,1,0) specificity, and later wins. The
   first attempt at this fix did exactly that and moved the card by 6px. Scoping
   every rule under `.aura-scene` takes them to (0,2,0), which beats the inline
   block on specificity regardless of source order. Keep the parent selector on
   anything added here that also exists in index.html's <style>. */
@media (max-width: 768px), (max-height: 500px) {
  .aura-scene .as-info {
    /* 88vw, not 82: the cap is what sets the width on every phone from 341px up
       (88vw = 300 at 341), so the vw term only ever governs the narrow tail —
       and the narrow tail is exactly where the chip row below runs out of room.
       At 320 this is 281.6px with a 19px gutter either side, which is the same
       edge the old 84vw rule sat on. */
    width: min(88vw, 300px);
    padding: 13px 14px 12px;
    border-radius: 20px;
    bottom: 4.5vh;
  }
  .aura-scene .as-info h3 { font-size: 1.125rem; margin-bottom: 4px; }
  .aura-scene .as-info p {
    font-size: 0.78125rem;
    line-height: 1.5;
    margin-bottom: 9px;
    /* Three lines is enough to establish the character of the building; the
       full text is on the project page, one tap away via the link below. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  /* ── The chip row must stay ONE row. This is the whole ball game ────────────
     Re-measured 2026-08-20 at 390x844: the card was 310 x 418 — 50% of the
     screen, not the ~250px the note above predicted. The paragraph clamp and
     the padding trim had both held; what had not is this row.

     Aura 1 is the only building carrying a Delivery chip (script.js BUILDINGS
     — every other entry has no `delivery` key and the <li> is display:none'd),
     so Aura 1 is the worst case and it was 4.7px over:

       chip "Локация / Варна, България"    134.4px
       chip "Завършване / 2027–2028"       129.2px
       gap                                  16.0px
                                        = 279.6px  vs  274.9px of inner width

     THE CHIP TEXT IS THE FIXED PART — 102.4 + 97.2 = 199.6px of it, set by the
     tracked uppercase label, and untouchable without going back under the 12px
     floor the 2026-08-13 legibility pass established. Only gap and padding are
     negotiable, so those are what pay.

     Four point seven pixels. The row wrapped, and a wrapped row costs a full
     chip height plus a gap — 71.1 + 16 = 87.1px, i.e. 21% of the whole card,
     spent on a 4.7px overflow. Nothing in the card reads as "too big" on its
     own; this one wrap is most of it.

     So the slack is bought back where it is cheapest: 16px gap -> 8, and the
     chip's own 11px 16px -> 8px 9px. New total 235.6 + 8 = 243.6, measured
     against the two viewports that bracket every phone:

       390px screen -> 300px card -> 272.0px inner -> 28.4px of headroom
       320px screen -> 281.6px card -> 253.6px inner -> 10.0px of headroom

     Headroom is the point, not the fit. Bulgarian is the wide language here
     ("ЗАВЪРШВАНЕ" vs "DELIVERY"), so EN has more; the margin is there to absorb
     a font-metric difference on a device we cannot measure.

     DO NOT widen the gap back for looks without re-doing this arithmetic — the
     failure is silent and it costs 87px, not the 8px it appears to.

     flex-wrap stays: wrapping is the correct behaviour at a text size we did
     not anticipate, and a wrapped row is ugly, not broken. */
  .aura-scene .as-info-facts {
    flex-direction: row;
    gap: 8px;
    margin-top: 8px;
    flex-wrap: wrap;
  }
  .aura-scene .as-info-facts li { font-size: 0.75rem; padding: 8px 9px; }
  .aura-scene .as-info-link {
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    padding: 10px 18px;
    margin-bottom: 12px;
  }
  .aura-scene .as-detail-eyebrow { margin-bottom: 8px; }
  .aura-scene .as-eyebrow { margin-bottom: 8px; }
}

/* ── Small touch targets ─────────────────────────────────────────────────────
   CORRECTION, 2026-08-13. This block used to be headed "Remaining sub-12px type"
   and claimed to have finished the sub-12px sweep. It had not. It covered
   .footer-social a and .story-stage .label only — two selectors, both inside
   `@media (max-width: 768px)` — while .filter-btn (9.5px), .card-badge (9.5px),
   .card-location (10.5px), .spec-label (9.5px), .footer-col h4 (9.5px),
   .footer-bottom p (11px), .label (10.5px), .lang-option (11px) and about a
   dozen more were untouched, and none of it applied in landscape because the
   gate was width-only. A landscape phone still measured 9.5px and 10px type.

   The real sweep is now done at the source: every font-size in this file has a
   12px floor and is declared in rem, so it applies at every width, in every
   orientation, and moves with the reader's browser text-size preference. What is
   left in this block is the TOUCH-TARGET half, which is still phone-only and
   still correct.

   .footer-social a is the only outbound social link on the site — a two-letter
   "FB" that measured 14x18 — so it gets a proper 44x44 round target.
   .story-stage .label beats the generic .label on specificity (0,2,0), so it
   keeps its own entry; the size now matches, only the tracking differs. */
@media (max-width: 768px), (max-height: 500px) {
  .footer-social a {
    font-size: 0.75rem;
    color: rgba(232, 228, 223, 0.7);
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(232, 228, 223, 0.22);
    border-radius: 50%;
  }
  .story-stage .label { font-size: 0.75rem; letter-spacing: 0.18em; }
  .floatarc__hint { font-size: 0.78125rem; }
  .lang-option { font-size: 0.78125rem; min-height: 44px; display: flex; align-items: center; }
  .lang-current { min-height: 44px; display: inline-flex; align-items: center; }
}

/* ── Contact form: stop iOS zooming the page on focus ────────────────────────
   The single most disruptive mobile defect found in the audit, and it is one
   line of CSS.

   Every field is font-size: 14px. Mobile Safari has a hard rule: if a focused
   form control renders below 16px, it zooms the whole page in to make the text
   legible — and it does NOT zoom back out when the field is blurred. So on an
   iPhone, tapping "Name" on the contact page magnifies the site, pushes the
   layout off the right edge, and leaves the visitor pinching to get back. They
   then have to do it again for every remaining field. This is the conversion
   page, so it is happening to people who had already decided to get in touch.

   16px is the threshold, not a preference: 15.9px still triggers it. The desktop
   size is deliberately left at 0.875rem (14px), since the rule only exists on
   mobile Safari and 16px fields look oversized on a wide layout.

   THIS ONE VALUE IS `max(1rem, 16px)` AND NOT A BARE rem, ON PURPOSE. The rest
   of the type scale was moved to rem on 2026-08-13 so that a reader who enlarges
   text in their browser actually gets larger text. That cuts both ways: a reader
   who SHRINKS the default below 16px would take a bare `1rem` under the Safari
   threshold and hand the zoom bug back to every visitor who did that. max()
   keeps the accessibility gain (the field grows with the preference) while
   pinning the floor at the literal 16 CSS pixels Safari actually tests. */
@media (max-width: 768px), (max-height: 500px) {
  .form-group input,
  .form-group textarea,
  .form-group select {
    font-size: max(1rem, 16px);
    padding: 14px 16px;
  }
  .form-group label { font-size: 0.78125rem; }
  /* The submit button measured 330x43 — one pixel under the 44pt minimum. */
  .contact-form .btn-teal,
  .contact-form button[type="submit"] { min-height: 50px; font-size: 0.875rem; }
  /* Phone and email in the contact panel are the two things a visitor on a
     phone is most likely to tap, and they measured 20px tall. */
  .contact-details a,
  .contact-block a { min-height: 40px; display: inline-flex; align-items: center; }
}

/* ── Floating menu button (phones only) ──────────────────────────────────────
   Appears only while .site-header carries .nav-hidden, i.e. exactly when the
   normal hamburger has scrolled away. See the "Persistent menu access on
   phones" block in script.js for why this exists.

   Bottom-right, above the safe-area inset so it clears the iPhone home
   indicator. 52px square, comfortably over the 44pt minimum.

   The inset it reads was `env(safe-area-inset-bottom, 0px)` written inline until
   2026-08-13. Same number, but a bare env() cannot be overridden by a test harness
   — env() is resolved by the UA, there is no cascade seat to win — so the rule was
   unverifiable on anything that is not a physical iPhone. Reading --sab instead
   makes it assertable in a headless browser, which is the entire argument for the
   tokens existing. Do not put env() back inline here. */
.nav-fab { display: none; }

@media (max-width: 768px), (max-height: 500px) {
  .nav-fab {
    display: flex;
    position: fixed;
    /* `max` on the side, `calc` on the bottom, and that asymmetry is deliberate:
       portrait has no side inset so `right` must not grow, but held sideways the
       island eats a ~59px column and an 18px offset would park a 52px button half
       under it. Bottom keeps calc — see the two-idioms note at the top of the file. */
    right: max(18px, calc(var(--sar, 0px) + 6px));
    bottom: calc(18px + var(--sab, 0px));
    z-index: 940;
    width: 52px;
    height: 52px;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    padding: 0;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.2);
    background: rgba(30, 28, 26, 0.6);
    -webkit-backdrop-filter: blur(20px) saturate(1.6);
            backdrop-filter: blur(20px) saturate(1.6);
    box-shadow: 0 8px 26px rgba(0, 0, 0, 0.3);
    cursor: pointer;
    /* Hidden by default and non-interactive, so it can never intercept a tap
       meant for the page underneath while it is invisible. */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(10px) scale(0.9);
    transition: opacity .28s ease, transform .28s cubic-bezier(0.22, 1, 0.36, 1), visibility .28s;
  }
  .nav-fab.is-on {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
  }
  .nav-fab span {
    display: block;
    width: 20px;
    height: 1.5px;
    border-radius: 1px;
    background: rgba(255, 255, 255, 0.92);
    transition: transform .26s ease, opacity .2s ease;
  }
  /* Bars fold into an X while the menu is open, so the same control closes it. */
  .nav-fab.is-open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
  .nav-fab.is-open span:nth-child(2) { opacity: 0; }
  .nav-fab.is-open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
}

@media (prefers-reduced-motion: reduce) {
  .nav-fab { transition: opacity .01s, visibility .01s; }
  .nav-fab span { transition: none; }
}
