/* ==========================================================================
   Grad Invest — landing page styles
   ========================================================================== */

:root {
  /* Kept in sync with the fixed header's actual rendered height by
     main.js (it changes when .is-scrolled toggles padding) — the
     72px here is just a sane pre-JS fallback, not a real measurement. */
  --header-h: 72px;
  --navy-950: #0b1626;
  --navy-900: #0f1f36;
  --navy-800: #142a47;
  --navy-700: #1c3a5e;
  --navy-600: #29517e;
  --gold-500: #c9a15a;
  --gold-400: #d8b876;
  --gold-100: #f4e9d5;
  /* Darker than --gold-500 specifically so small bold label text (the
     .eyebrow kicker) reaches WCAG AA (4.5:1) on light backgrounds —
     gold-500 itself only manages ~2.4:1 there. Kept out of dark panels
     (hero, contact-info, partner), which opt into --gold-400 instead via
     an inline color override and have plenty of contrast either way. */
  --gold-700: #8f6c2f;
  --ink-900: #14202e;
  --ink-700: #3c4a5c;
  --ink-500: #647186;
  --ink-300: #9aa6b6;
  --paper-0: #ffffff;
  --paper-50: #f7f8fa;
  --paper-100: #eef1f5;
  --line: #e2e6ec;
  --shadow-sm: 0 1px 2px rgba(15, 31, 54, 0.04);
  --shadow-md: 0 3px 10px rgba(15, 31, 54, 0.06);
  --shadow-lg: 0 6px 18px rgba(15, 31, 54, 0.08);
  --radius-sm: 8px;
  --radius-md: 10px;
  --radius: 14px;
  --radius-lg: 20px;
  --radius-full: 999px;
  --container: 1180px;
  /* Text on dark panels (hero, about-panel, partner, contact-info,
     footer) previously used a dozen one-off white opacities for what
     were really just two roles. Every value below is well above the
     4.5:1 contrast minimum against --navy-950 (checked: even the
     lightest-touch 0.55 clears 6:1), so standardizing on these two
     doesn't cost any legibility. */
  --on-dark-secondary: rgba(255, 255, 255, 0.72); /* body copy / lead paragraphs */
  --on-dark-muted: rgba(255, 255, 255, 0.6);      /* small labels / captions */
  --success: #1f7a4d;
  --error: #b3401f;
}

* { box-sizing: border-box; }
html {
  scroll-behavior: smooth;
  /* Several Android browsers (Huawei/Samsung/Xiaomi/UC — not Safari,
     which is why this only ever shows up on some phones and not others)
     auto-boost font sizes in narrow text columns for "readability",
     silently rendering text larger than the CSS actually specifies. That
     alone can be enough to push a heading past its container's width.
     Pin the adjustment to 100% everywhere so type renders at the size
     we actually set, consistently across devices. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
/* Safety net: no single element should ever be able to force a
   horizontal scrollbar on the page, regardless of content/browser quirks. */
html, body { overflow-x: hidden; }

body {
  margin: 0;
  font-family: "Inter", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
  color: var(--ink-900);
  background: var(--paper-0);
  -webkit-font-smoothing: antialiased;
  line-height: 1.55;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
.text-link {
  color: var(--gold-700);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.text-link:hover { color: var(--navy-900); }

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 24px;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-700);
}
.eyebrow::before {
  content: "";
  width: 22px;
  height: 2px;
  background: currentColor;
  display: inline-block;
}
/* On dark panels (hero, partner, contact-info) --gold-700 loses too much
   contrast against navy — swap to the lighter --gold-400 used elsewhere
   on those same panels (brand-sub, stat numbers, etc). */
.eyebrow--on-dark { color: var(--gold-400); }

h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -0.01em; }

/* Anchor targets sit below a fixed header — without this, #jump links land
   with their heading hidden behind the nav bar. --header-h is kept live by
   main.js so this stays correct whether the header is in its tall (top of
   page) or short (.is-scrolled) state instead of leaving a stale gap.

   The #about/#objects/#finance/#contact ids live on the inner content
   wrapper (.about-grid / .section-head), not the outer .section — that
   element's own 96px top padding would otherwise land *below* the
   header as extra dead space nobody asked for, on top of the header
   gap itself. Anchoring to the content directly means the heading sits
   right under the header with just this one intentional gap. */
#top, #about, #objects, #finance, #contact, #partner {
  scroll-margin-top: calc(var(--header-h) + 20px);
}

.section {
  padding: 96px 0;
}
.section--alt { background: var(--paper-50); }

.section-head {
  max-width: 680px;
  margin: 0 auto 48px;
  text-align: center;
}
.section-head h2 {
  font-size: clamp(28px, 3.4vw, 38px);
  margin: 14px 0 16px;
  color: var(--navy-900);
}
.section-head p {
  color: var(--ink-500);
  font-size: 16.5px;
  margin: 0;
}
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 28px;
  border-radius: var(--radius-full);
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease, color 0.15s ease, border-color .15s ease;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn-gold {
  background: linear-gradient(135deg, var(--gold-400), var(--gold-500));
  color: var(--navy-950);
  box-shadow: 0 3px 8px rgba(201, 161, 90, 0.18);
}
.btn-gold:hover { box-shadow: 0 4px 10px rgba(201, 161, 90, 0.24); }
.btn-ghost {
  background: transparent;
  border-color: rgba(255,255,255,0.35);
  color: #fff;
}
.btn-ghost:hover { background: rgba(255,255,255,0.1); }
.btn:disabled, .btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none !important;
}

/* ---------- Header / Nav ---------- */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  padding: 18px 0;
  transition: background .25s ease, padding .25s ease, box-shadow .25s ease;
}
.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}
.site-header.is-scrolled {
  background: rgba(11, 22, 38, 0.92);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  backdrop-filter: saturate(160%) blur(10px);
  padding: 12px 0;
  box-shadow: var(--shadow-md);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 800;
  font-size: 19px;
  color: #fff;
  letter-spacing: -0.01em;
}

/* Logo badge — shared by header brand and footer brand so both stay in sync */
.mark {
  flex: none;
  width: 38px; height: 38px;
  border-radius: var(--radius-md);
  background: #fff;
  display: flex; align-items: center; justify-content: center;
  padding: 7px;
  box-shadow: var(--shadow-sm);
}
.mark img { width: 100%; height: 100%; object-fit: contain; }
.mark--sm { width: 30px; height: 30px; padding: 5px; border-radius: var(--radius-sm); }

.brand .brand-sub {
  display: block;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-400);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 32px;
  list-style: none;
  margin: 0; padding: 0;
}
.nav-links a {
  color: rgba(255,255,255,0.85);
  font-size: 14.5px;
  font-weight: 600;
  transition: color .15s ease;
}
.nav-links a:hover { color: #fff; }

.header-contacts {
  display: flex;
  align-items: center;
  gap: 20px;
}
.header-contacts .phone {
  color: #fff;
  font-weight: 700;
  font-size: 14.5px;
}
.header-contacts .phone span {
  display: block;
  font-weight: 500;
  font-size: 11.5px;
  color: var(--on-dark-muted);
}

/* Language switch */
.lang-switch {
  display: flex;
  align-items: center;
  border: 1px solid rgba(255,255,255,0.25);
  border-radius: var(--radius-full);
  padding: 3px;
  gap: 2px;
}
.lang-btn {
  border: none;
  background: transparent;
  color: var(--on-dark-muted);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 6px 12px;
  border-radius: var(--radius-full);
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.lang-btn.is-active {
  background: var(--gold-500);
  color: var(--navy-950);
}
.lang-btn:not(.is-active):hover { color: #fff; }

/* Items that only appear inside the open mobile menu (phone / CTA / language,
   otherwise hidden together with .header-contacts on small screens) */
.nav-mobile-only { display: none; }

.nav-toggle {
  display: none;
  width: 42px; height: 42px;
  border-radius: var(--radius-md);
  border: 1px solid rgba(255,255,255,0.25);
  background: rgba(255,255,255,0.06);
  color: #fff;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: 100vh;
  /* 100vh on mobile browsers is the *largest* possible viewport (as if
     the address bar were hidden) in some engines and the *smallest* in
     others — inconsistent, and can leave a gap or overshoot as the bar
     shows/hides while scrolling. 100dvh tracks the actual visible
     viewport and is layered on as an enhancement (100vh stays as the
     fallback for browsers that don't support dvh yet). */
  min-height: 100dvh;
  display: flex;
  align-items: center;
  color: #fff;
  background: linear-gradient(160deg, var(--navy-950) 0%, var(--navy-900) 45%, var(--navy-800) 100%);
  overflow: hidden;
}
.hero::before {
  content: "";
  position: absolute; inset: 0;
  background-image: url("../images/hero-bg.jpg");
  background-size: cover;
  background-position: center;
  opacity: 0.22;
  mix-blend-mode: luminosity;
}
.hero::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at 20% 20%, rgba(201,161,90,0.18), transparent 55%),
              linear-gradient(180deg, rgba(11,22,38,0.4), rgba(11,22,38,0.92));
}
.hero .container {
  position: relative;
  z-index: 2;
  padding-top: 120px;
  padding-bottom: 64px;
}
.hero-inner { max-width: 720px; }
.hero h1 {
  font-size: clamp(36px, 6vw, 62px);
  line-height: 1.05;
  margin: 20px 0 22px;
}
.hero h1 em {
  font-style: normal;
  color: var(--gold-400);
}
.hero p.lead {
  font-size: 18px;
  color: var(--on-dark-secondary);
  max-width: 580px;
  margin: 0 0 34px;
}
.hero-cta { display: flex; gap: 16px; flex-wrap: wrap; }

.hero-stats {
  position: relative;
  z-index: 2;
  margin-top: 64px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: rgba(255,255,255,0.12);
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid rgba(255,255,255,0.12);
}
.hero-stat {
  min-width: 0;
  background: rgba(255,255,255,0.04);
  padding: 22px 20px;
  text-align: left;
}
.hero-stat .num {
  font-size: 30px;
  font-weight: 800;
  color: var(--gold-400);
  letter-spacing: -0.01em;
}
.hero-stat .label {
  font-size: 12.5px;
  color: var(--on-dark-muted);
  margin-top: 4px;
}

/* In normal flow right below .hero-stats (not pinned to the viewport
   edge) — .hero's height already grows past 100vh on shorter windows,
   so anchoring this to "bottom of .hero" could push it below the
   visible area entirely. Sitting right under the stats guarantees it's
   always visible together with them. */
.scroll-cue {
  position: relative;
  z-index: 2;
  margin-top: 36px;
  color: var(--on-dark-secondary);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.scroll-cue .chevron {
  width: 18px; height: 18px;
  color: var(--gold-400);
  animation: scrollcue 1.6s ease-in-out infinite;
}
@keyframes scrollcue {
  0%, 100% { transform: translateY(0); opacity: .55; }
  50% { transform: translateY(7px); opacity: 1; }
}

/* ---------- About ---------- */
.about-grid {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 64px;
  align-items: center;
}
.about-grid > * { min-width: 0; }
.about-copy p {
  color: var(--ink-700);
  font-size: 16.5px;
  margin: 18px 0;
}
.about-list {
  list-style: none;
  margin: 28px 0 0;
  padding: 0;
  display: grid;
  gap: 14px;
}
.about-list li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  font-size: 15px;
  color: var(--ink-700);
}
.about-list .tick {
  flex: none;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--gold-100);
  color: var(--gold-700);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px;
  font-weight: 800;
}
.about-panel {
  background: var(--navy-950);
  border-radius: var(--radius-lg);
  padding: 40px 34px;
  color: #fff;
  position: relative;
  overflow: hidden;
}
.about-panel::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 90% 0%, rgba(201,161,90,0.28), transparent 55%);
}
.about-panel .rows { position: relative; z-index: 1; display: grid; gap: 22px; }
.about-panel .row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding-bottom: 18px;
  border-bottom: 1px solid rgba(255,255,255,0.12);
}
.about-panel .row:last-child { border-bottom: none; padding-bottom: 0; }
.about-panel .row .v {
  font-size: 26px;
  font-weight: 800;
  color: var(--gold-400);
}
.about-panel .row .l {
  font-size: 13.5px;
  color: var(--on-dark-muted);
  max-width: 60%;
  text-align: right;
}

/* ---------- Cities strip ---------- */
.cities-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin-top: 20px;
}
.cities-strip span {
  padding: 8px 16px;
  border-radius: var(--radius-full);
  background: var(--paper-100);
  color: var(--ink-700);
  font-size: 13.5px;
  font-weight: 600;
}

/* ---------- Portfolio ---------- */
.objects-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 26px;
}
.objects-grid > * { min-width: 0; }
.object-card {
  background: var(--paper-0);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform .2s ease, box-shadow .2s ease;
  display: flex;
  flex-direction: column;
  cursor: pointer;
}
.object-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
}
/* :focus first (universal — keeps a visible ring in browsers that don't
   know :focus-visible at all, rather than silently dropping the whole
   rule), then :focus-visible support layers on top to suppress it for
   mouse/pointer focus specifically, leaving it for keyboard focus. */
.object-card:focus {
  outline: 3px solid var(--gold-500);
  outline-offset: 2px;
}
.object-card:focus:not(:focus-visible) {
  outline: none;
}
.object-media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--navy-800);
}
.object-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .5s ease;
}
.object-card:hover .object-media img { transform: scale(1.06); }
.object-body { padding: 22px 22px 24px; flex: 1; display: flex; flex-direction: column; }
.object-body h3 { font-size: 18.5px; color: var(--navy-900); }
.object-body .city {
  color: var(--gold-700);
  font-weight: 700;
  font-size: 12.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-top: 6px;
}
.object-facts {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px dashed var(--line);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 14px;
  font-size: 13px;
}
.object-facts dt { color: var(--ink-500); margin: 0; }
.object-facts dd { color: var(--ink-900); font-weight: 700; margin: 2px 0 0; }
.object-body .addr {
  margin-top: 14px;
  font-size: 13px;
  color: var(--ink-500);
}

/* ---------- Partner ----------
   Reuses the same dark-panel recipe already established by .about-panel
   and .contact-info (navy-950 + gold radial glow + gold-400 accents) so
   it reads as part of the same design system, not a one-off style. The
   background photo + fade is the same layered approach as .hero, just
   applied to a card instead of the full viewport. Section shares the
   objects section's alt background so the two flow together with no
   visible seam between them. */
.partner-section { padding-top: 0; }
.partner-card {
  background: var(--navy-950);
  border-radius: var(--radius-lg);
  padding: 56px 48px;
  color: #fff;
  position: relative;
  overflow: hidden;
  min-height: 460px;
  display: flex;
  align-items: center;
}
.partner-card::before {
  content: "";
  position: absolute; inset: 0;
  background-image: url("../images/ltc.jpg");
  background-size: cover;
  background-position: center;
  opacity: 0.6;
}
.partner-card::after {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(circle at 100% 0%, rgba(201,161,90,0.2), transparent 55%),
    linear-gradient(100deg, rgba(11,22,38,0.97) 0%, rgba(11,22,38,0.94) 34%, rgba(11,22,38,0.6) 64%, rgba(11,22,38,0.28) 100%);
}
.partner-card > * { position: relative; z-index: 1; }
.partner-content { max-width: 560px; min-width: 0; }
.partner-card h2 {
  font-size: clamp(24px, 2.8vw, 30px);
  color: #fff;
  margin: 14px 0 6px;
}
.partner-tagline {
  font-size: 14px;
  font-weight: 600;
  color: var(--gold-400);
  margin: 0 0 18px;
}
.partner-lead {
  color: var(--on-dark-secondary);
  font-size: 15.5px;
  margin: 0 0 30px;
}
.partner-badges {
  list-style: none;
  margin: 0 0 34px;
  padding: 0;
  display: grid;
  gap: 18px;
}
.partner-badges li {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}
.partner-badges strong {
  display: block;
  color: #fff;
  font-size: 14.5px;
  margin-bottom: 3px;
}
.partner-badges span {
  color: var(--on-dark-muted);
  font-size: 13.5px;
  line-height: 1.5;
}

.partner-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
/* Same transparent/outline treatment as .btn-ghost, just circular and
   icon-only -- a secondary link (the partner's channel) shouldn't
   compete with the primary .btn-ghost CTA next to it. */
.partner-social {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex: none;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.35);
  color: #fff;
  transition: background 0.15s ease, transform 0.15s ease, border-color 0.15s ease;
}
.partner-social:hover {
  background: rgba(255,255,255,0.1);
  transform: translateY(-1px);
}

@media (max-width: 640px) {
  .partner-card { padding: 36px 28px; min-height: 0; }
  .partner-card::after {
    background:
      radial-gradient(circle at 100% 0%, rgba(201,161,90,0.2), transparent 55%),
      rgba(11,22,38,0.9);
  }
}

/* ---------- Financial statements ---------- */
/* auto-fit + minmax instead of a fixed column count so the grid keeps
   wrapping sensibly as more years are added (2025, 2026, ...) without
   needing a manual breakpoint/column-count tweak every year. */
.fin-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
}
.fin-card {
  min-width: 0;
  background: var(--paper-0);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 26px 22px;
  text-align: center;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.fin-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: var(--gold-500);
}

.fin-card .icon {
  width: 52px; height: 52px;
  margin: 0 auto 16px;
  border-radius: 12px;
  background: var(--navy-950);
  color: var(--gold-400);
  display: flex; align-items: center; justify-content: center;
  font-weight: 800;
  font-size: 13px;
}
.fin-card .year { font-size: 21px; font-weight: 800; color: var(--navy-900); }
.fin-card .desc { font-size: 13px; color: var(--ink-500); margin: 6px 0 18px; }
.fin-card a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--navy-800);
  border-bottom: 2px solid var(--gold-500);
  padding-bottom: 2px;
}

/* Not-yet-available year (e.g. the current year before its statement
   exists) — reads as "coming later", not as a broken/dead download. */
.fin-card--soon {
  border-style: dashed;
  background: var(--paper-50);
}
.fin-card--soon:hover { transform: none; box-shadow: none; border-color: var(--line); }
.fin-card--soon .icon { background: var(--paper-100); color: var(--ink-300); }
.fin-card--soon .year { color: var(--ink-500); }
.fin-card--soon .desc { color: var(--ink-300); margin-bottom: 14px; }
.fin-soon-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-300);
}
.fin-soon-label .dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ink-300);
}

/* Older years stay hidden behind this toggle so the grid doesn't grow
   indefinitely as more years are added — only the 3 most recent (plus
   this tile) show by default, filling exactly one row. */
.fin-card--more {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  cursor: pointer;
  border-style: dashed;
  background: var(--paper-50);
  /* Its row can be taller than its own content (siblings have an extra
     download-link line it doesn't), so center within whatever height
     the row stretches it to instead of sitting pinned to top. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  font: inherit;
  color: inherit;
}
.fin-card--more:hover {
  border-color: var(--gold-500);
  transform: translateY(-3px);
}
.fin-card--more .icon { background: var(--paper-100); color: var(--ink-500); }
.fin-more-icon { transition: transform .2s ease; }
.fin-card--more.is-open .fin-more-icon { transform: rotate(45deg); }
.fin-more-label-open { display: none; }
.fin-card--more.is-open .fin-more-label-closed { display: none; }
.fin-card--more.is-open .fin-more-label-open { display: inline; }

/* ---------- Contact / form ---------- */
.contact-wrap {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: 0;
  background: var(--navy-950);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.contact-info {
  /* Grid items default to min-width:auto, meaning they refuse to shrink
     below their content's natural (unwrapped) width — a long heading or
     a boosted font size can then force this whole column, and the grid
     that contains it, wider than the viewport instead of just wrapping.
     min-width:0 lets it shrink and wrap like normal block content. */
  min-width: 0;
  padding: 52px 44px;
  color: #fff;
  position: relative;
}
.contact-info::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 0% 100%, rgba(201,161,90,0.22), transparent 55%);
}
.contact-info > * { position: relative; z-index: 1; }
.contact-info h3 { font-size: 26px; margin: 14px 0 14px; color: #fff; }
.contact-info p { color: var(--on-dark-secondary); font-size: 15px; }
.contact-list { list-style: none; margin: 30px 0 0; padding: 0; display: grid; gap: 18px; }
.contact-list li { display: flex; gap: 14px; align-items: center; }
/* Icon chip on a dark panel — shared by the contact list and the partner
   badges so both reuse the exact same recipe instead of drifting apart. */
.ic {
  flex: none;
  width: 42px; height: 42px;
  border-radius: var(--radius-md);
  background: rgba(255,255,255,0.08);
  color: var(--gold-400);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700;
}
.partner-badges .ic { width: 30px; height: 30px; border-radius: var(--radius-sm); font-size: 13px; }
.contact-list a, .contact-list span.txt {
  font-weight: 600;
  font-size: 14.5px;
  color: #fff;
}
.contact-list .text-link { color: var(--gold-400); }
.contact-list .lbl {
  display: block;
  font-size: 11.5px;
  color: var(--on-dark-muted);
  font-weight: 500;
  margin-bottom: 2px;
}

.contact-form {
  min-width: 0;
  background: var(--paper-0);
  padding: 52px 44px;
}
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-bottom: 16px;
}
.form-row > * { min-width: 0; }
.field { display: flex; flex-direction: column; gap: 7px; }
.field label {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink-700);
  letter-spacing: 0.02em;
}
.field input, .field select {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  /* iOS Safari auto-zooms the whole page on focus for any input/select
     with a computed font-size under 16px — an unrequested, jarring
     zoom on every tap into the form on iPhone. 16px is the threshold
     that keeps it from triggering at all. */
  font-size: 16px;
  font-family: inherit;
  color: var(--ink-900);
  background: var(--paper-50);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field input:focus, .field select:focus {
  outline: none;
  border-color: var(--gold-500);
  box-shadow: 0 0 0 3px rgba(201,161,90,0.18);
  background: #fff;
}
.field.span-2 { grid-column: span 2; }
.field-error {
  font-size: 12px;
  font-weight: 600;
  color: var(--error);
  display: none;
}
.field.has-error .field-error { display: block; }
.field.has-error input,
.field.has-error select {
  border-color: var(--error);
}
.field.has-error input:focus,
.field.has-error select:focus {
  box-shadow: 0 0 0 3px rgba(179,64,31,0.18);
}
.form-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 20px;
  flex-wrap: wrap;
}
.form-note { font-size: 12px; color: var(--ink-500); max-width: 320px; }
.form-status {
  font-size: 13.5px;
  font-weight: 600;
  margin-top: 14px;
  display: none;
}
.form-status.ok { display: block; color: var(--success); }
.form-status.err { display: block; color: var(--error); }

/* Honeypot spam trap (assets/php/TenantFormHandler.php) -- off-screen
   rather than display:none/visibility:hidden, since some bots skip
   fields hidden that way but still fill in anything with a normal box
   model. Real visitors and screen readers (aria-hidden) never see it. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---------- Footer ---------- */
.site-footer {
  background: var(--navy-950);
  color: var(--on-dark-muted);
  /* Extra bottom clearance (beyond the visual 40px rhythm) so the fixed
     back-to-top button — bottom-right, ~68px footprint with its own
     margin — never sits on top of the copyright line, at any viewport
     width: on desktop the copyright column ends up in that same corner;
     on mobile the stacked layout puts it flush with the page bottom. */
  padding: 40px 0 96px;
  font-size: 13px;
}
.footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}
.footer-inner > * { min-width: 0; }
.footer-brand { display: flex; align-items: center; gap: 10px; color: #fff; font-weight: 700; }
/* Footer links wrap whole items on narrow screens. */
.footer-links { display: flex; flex-wrap: wrap; gap: 10px 24px; list-style: none; margin: 0; padding: 0; }
.footer-links a { white-space: nowrap; }
.footer-links a:hover { color: #fff; }

/* ---------- Back to top ---------- */
.back-to-top {
  position: fixed;
  right: 22px;
  bottom: 22px;
  z-index: 90;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: none;
  background: var(--navy-950);
  color: var(--gold-400);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
  transition: opacity .2s ease, transform .2s ease, background .15s ease;
}
.back-to-top.is-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.back-to-top:hover { background: var(--navy-800); }
.back-to-top:focus {
  outline: 3px solid var(--gold-500);
  outline-offset: 2px;
}
.back-to-top:focus:not(:focus-visible) {
  outline: none;
}
@media (max-width: 640px) {
  .back-to-top { right: 16px; bottom: 16px; }
}

/* ---------- Modal ---------- */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(11,22,38,0.72);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  /* iOS Safari can still scroll the page behind the overlay via a touch
     drag on the backdrop even with body { overflow: hidden } (a known
     iOS quirk — that CSS alone doesn't reliably block touch-driven
     scrolling). Blocking the backdrop's own scroll gesture directly is
     the reliable fix; .modal-box below opts back into normal touch
     scrolling so long modal content still scrolls fine. */
  touch-action: none;
}
.modal-overlay.is-open { display: flex; }
.modal-box {
  background: #fff;
  border-radius: 18px;
  max-width: 780px;
  width: 100%;
  max-height: 88vh;
  overflow: auto;
  overscroll-behavior: contain;
  touch-action: auto;
  position: relative;
  box-shadow: var(--shadow-lg);
}
.modal-close {
  position: absolute;
  top: 16px; right: 16px;
  width: 38px; height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--paper-100);
  border: none;
  cursor: pointer;
  color: var(--ink-700);
  z-index: 2;
}
/* Object photos are ~1000×707 (≈1.41:1) infographic collages, not generic
   16:9 crops — matching the container ratio to the source keeps captions
   and labels baked into the image fully visible instead of cropped. */
.modal-img { width: 100%; aspect-ratio: 1000/707; object-fit: cover; background: var(--paper-100); }
.modal-body { padding: 30px 34px 34px; }
.modal-body h3 { font-size: 22px; color: var(--navy-900); }
.modal-body .city { color: var(--gold-700); font-weight: 700; font-size: 12.5px; text-transform: uppercase; letter-spacing: .05em; margin: 8px 0 20px; }
.modal-facts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 20px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}
.modal-facts dt { font-size: 12.5px; color: var(--ink-500); margin: 0; }
.modal-facts dd { font-size: 14.5px; font-weight: 700; color: var(--ink-900); margin: 2px 0 0; }

/* ---------- Reveal on scroll ----------
   Content only starts hidden once JS confirms it can actually reveal it
   (html.reveal-ready, set right before the IntersectionObserver is wired
   up). Without JS — or if it fails/hasn't run yet — everything stays
   visible by default, so the page never ships blank sections. */
.reveal-ready [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s ease, transform .6s ease;
}
.reveal-ready [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .reveal-ready [data-reveal] { opacity: 1; transform: none; transition: none; }
}
/* Printed pages render every section at once regardless of scroll
   position — nothing should stay invisible waiting for a scroll that
   will never happen. Independent of the JS safety net (see main.js),
   which is timing-based and not guaranteed to apply before printing. */
@media print {
  .reveal-ready [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* ---------- Responsive ---------- */
@media (max-width: 980px) {
  .about-grid { grid-template-columns: 1fr; }
  .contact-wrap { grid-template-columns: 1fr; }
  .objects-grid { grid-template-columns: repeat(2, 1fr); }
  .hero-stats { grid-template-columns: repeat(2, 1fr); }
}

/* The burger threshold intentionally sits well above where the nav
   would merely start looking "tight" — nav links + phone + lang switch
   + CTA genuinely don't fit on one row below ~1070px (verified: brand
   and phone number start wrapping mid-word there), so the switch to the
   compact mobile header happens with real margin instead of cutting it
   close. */
@media (max-width: 1180px) {
  .nav-links, .header-contacts { display: none; }
  .nav-toggle { display: flex; }
  .site-header.is-open .nav-links {
    display: flex;
    position: absolute;
    top: 100%; left: 0; right: 0;
    background: rgba(11,22,38,0.98);
    flex-direction: column;
    padding: 20px 24px 26px;
    gap: 4px;
  }
  .site-header.is-open .nav-links a {
    padding: 12px 0;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    width: 100%;
  }
  .site-header.is-open .nav-links .nav-mobile-only {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    width: 100%;
    padding: 16px 0 4px;
  }
  .site-header.is-open .nav-links .nav-mobile-only .phone {
    color: #fff;
    font-weight: 700;
    font-size: 14.5px;
  }
  .site-header.is-open .nav-links .nav-mobile-only .phone span {
    display: block;
    font-weight: 500;
    font-size: 11.5px;
    color: var(--on-dark-muted);
  }
  .site-header.is-open .nav-links .nav-mobile-only .btn { width: 100%; }
}

@media (max-width: 640px) {
  .section { padding: 64px 0; }
  .objects-grid { grid-template-columns: 1fr; }
  .form-row { grid-template-columns: 1fr; }
  .field.span-2 { grid-column: span 1; }
  .contact-info, .contact-form { padding: 36px 26px; }
  .about-panel { padding: 30px 24px; }
  .hero .container { padding-top: 110px; }
}

/* ---------- 404 page ---------- */
.error-hero {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh; /* see .hero's comment on min-height: 100dvh */
  display: flex;
  align-items: center;
  color: #fff;
  background: linear-gradient(160deg, var(--navy-950) 0%, var(--navy-900) 45%, var(--navy-800) 100%);
  overflow: hidden;
}
.error-hero::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at 80% 15%, rgba(201,161,90,0.16), transparent 55%);
}
.error-hero .container {
  position: relative;
  z-index: 2;
  padding: 150px 0 80px;
  text-align: center;
}
.error-illustration { margin: 0 auto 8px; color: var(--gold-400); }
.error-illustration .sign {
  animation: signswing 3.5s ease-in-out infinite;
  /* Browsers have historically disagreed on the default reference box
     for transform-origin on nested SVG elements (fill-box vs. the SVG
     viewBox) — pin it to view-box explicitly (the current spec default,
     and what these coordinates are authored against: 150,40 is the
     rope's anchor point in the SVG's own 0 0 180 120 viewBox) so the
     swing pivots around the same point everywhere instead of drifting
     off-center in engines still defaulting to fill-box. */
  transform-box: view-box;
  transform-origin: 150px 40px;
}
@keyframes signswing {
  0%, 100% { transform: rotate(-4deg); }
  50% { transform: rotate(4deg); }
}
.error-code {
  font-size: clamp(72px, 14vw, 132px);
  font-weight: 800;
  line-height: 1;
  color: var(--gold-400);
  letter-spacing: -0.02em;
  margin: 8px 0 4px;
}
.error-hero h1 {
  font-size: clamp(24px, 3.2vw, 34px);
  margin: 0 0 14px;
}
.error-hero p.lead {
  font-size: 17px;
  color: var(--on-dark-secondary);
  max-width: 520px;
  margin: 0 auto 8px;
}
.error-hero p.error-sub {
  font-size: 14px;
  color: var(--on-dark-muted);
  max-width: 480px;
  margin: 0 auto 34px;
}
.error-actions { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; }

/* ---------- Privacy policy (plain-document page) ----------
   Deliberately not styled like the rest of the site (no header/nav,
   no brand chrome): this page is meant to read like a standalone
   legal document -- closer to a printed/PDF page than a landing
   section. .doc-page is that "page": a narrow, high-contrast reading
   column on a muted backdrop, sized for prose rather than marketing
   copy. */
.doc-body { background: var(--paper-50); }
.doc-section { padding: 72px 0; }
.doc-page {
  max-width: 720px;
  margin: 0 auto;
  background: var(--paper-0);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 56px 64px;
}
.doc-page .section-head { margin-bottom: 8px; }
.doc-meta {
  color: var(--ink-500);
  font-size: 13.5px;
  margin: 0 0 40px;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--line);
  text-align: center;
}
.doc-clause { margin: 0 0 32px; }
.doc-clause:last-child { margin-bottom: 0; }
.doc-clause h2 {
  font-size: 17px;
  font-weight: 700;
  color: var(--navy-900);
  margin: 0 0 10px;
}
.doc-clause p {
  color: var(--ink-700);
  margin: 0 0 12px;
}
.doc-clause p:last-child { margin-bottom: 0; }

@media (max-width: 640px) {
  .doc-section { padding: 40px 0; }
  .doc-page { padding: 32px 24px; border-radius: var(--radius-sm); }
  .doc-meta { margin-bottom: 28px; padding-bottom: 20px; }
}

/* Printing a "document" page should look like the document, not the
   website around it -- drop the card chrome/backdrop and let the
   prose use the full printable width. */
@media print {
  .doc-body { background: #fff; }
  .doc-section { padding: 0; }
  .doc-page {
    max-width: 100%;
    box-shadow: none;
    border: none;
    border-radius: 0;
    padding: 0;
  }
}
