/**
 * HAVEN Child — visual transformation layer.
 *
 * Loaded last. It re-points existing tokens and adds the surfaces, the
 * overlay navigation, the two new full-bleed sections and the motion system.
 * Nothing here introduces a colour outside the approved HAVEN palette: the
 * charcoal is a darkening of Navy Deep, the warm neutrals are the paper token
 * warmed toward the lockup's own off-white, and the accent IS the approved
 * HAVEN tan (#C08953), promoted from decoration to the conversion colour.
 */

/* =========================================================================
   1. EXTENDED SURFACE TOKENS
   The page was white / navy / white / navy. Two more surfaces break that
   without leaving the palette: a warm off-white that reads as paper rather
   than as an empty div, and a cinematic charcoal for media-led sections.
   ========================================================================= */

:root {
  --hvn-gold:        #C08953;   /* = approved HAVEN tan, now the CTA colour */
  --hvn-gold-lift:   #D9A473;
  /* A11Y (R-19, 2026-09-18): was #9E6C3C, which measured 4.13:1 on paper and
     3.76:1 on the warm alt surface. Every use of this token is 11–14px at
     weight 600 — small text, so it needs 4.5:1, not 3:1. Darkened one step
     within the same tan family: now 5.17:1 on paper and 4.70:1 on alt. */
  --hvn-gold-deep:   #8A5E33;
  --hvn-charcoal:    #141A22;
  --hvn-charcoal-2:  #1C242E;
  --hvn-warm:        #F7F5F1;
  --hvn-warm-2:      #EFEAE2;
  --hvn-warm-line:   #E1DAD0;

  /* Re-point the neutral surfaces to the warm ramp. */
  --hvn-surface:     var(--hvn-warm);
  --hvn-surface-alt: var(--hvn-warm-2);
  --hvn-border:      var(--hvn-warm-line);

  --hvn-shadow-1: 0 1px 2px rgba(20, 26, 34, .05), 0 4px 14px rgba(20, 26, 34, .06);
  --hvn-shadow-2: 0 2px 6px rgba(20, 26, 34, .08), 0 18px 42px rgba(20, 26, 34, .13);
  --hvn-nav-h: 5.25rem;
}

body { background: var(--hvn-warm); }

/* Cards keep the true paper white so they lift off the warm ground. */
.hvn-card,
.hvn-svc__card,
.hvn-quick__panel { background: #FFFFFF; }

/* =========================================================================
   2. CTA SYSTEM — gold is the conversion colour
   The primary action was navy on a navy-heavy page, which made the most
   important control the least visible thing on it. Gold is the approved
   accent and is now reserved for one job: the primary action.
   ========================================================================= */

.hvn-btn {
  border-radius: 999px;
  letter-spacing: .01em;
  transition: background-color var(--hvn-dur) var(--hvn-ease),
              color var(--hvn-dur) var(--hvn-ease),
              border-color var(--hvn-dur) var(--hvn-ease),
              transform var(--hvn-dur) var(--hvn-ease),
              box-shadow var(--hvn-dur) var(--hvn-ease);
}

.hvn-btn--primary,
.hvn-invert .hvn-btn--primary,
.hvn-ctap:not(.hvn-ctap--light) .hvn-btn--primary,
.hvn-footer .hvn-btn--primary {
  background: var(--hvn-gold);
  border-color: var(--hvn-gold);
  color: #17212C;
  box-shadow: 0 1px 0 rgba(255,255,255,.25) inset, 0 6px 18px rgba(192,137,83,.30);
}

.hvn-btn--primary:hover,
.hvn-btn--primary:focus-visible,
.hvn-invert .hvn-btn--primary:hover,
.hvn-ctap:not(.hvn-ctap--light) .hvn-btn--primary:hover,
.hvn-footer .hvn-btn--primary:hover {
  background: var(--hvn-gold-lift);
  border-color: var(--hvn-gold-lift);
  color: #17212C;
  transform: translateY(-2px);
  box-shadow: 0 10px 26px rgba(192,137,83,.38);
}

.hvn-btn--primary:active { transform: translateY(0); }

.hvn-btn--ghost { border-color: var(--hvn-navy-40); }
.hvn-btn--ghost:hover { border-color: var(--hvn-primary); transform: translateY(-2px); }
.hvn-btn--ondark:hover { transform: translateY(-2px); }

/* =========================================================================
   3. OVERLAY NAVIGATION
   The header used to be a white bar sitting on top of the Hero, which cut the
   cinema off at the shoulders. It now floats inside the Hero's visual field
   and only becomes a solid bar once the Hero has been left behind.
   ========================================================================= */

.hvn-lab-banner {
  position: relative;
  z-index: 80;
  background: var(--hvn-charcoal);
  color: rgba(255,255,255,.72);
  border-bottom: 1px solid rgba(255,255,255,.08);
}

body.hvn-overlay .hvn-header {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--hvn-banner-h, 0px);
  z-index: 70;
  background: transparent;
  border-bottom: 1px solid rgba(255,255,255,.14);
  transition: background-color 320ms var(--hvn-ease),
              box-shadow 320ms var(--hvn-ease),
              border-color 320ms var(--hvn-ease),
              transform 320ms var(--hvn-ease);
}

/* A short scrim so the nav is legible over any frame the Hero happens to be
   showing, without veiling the artwork the way a full-stage overlay would. */
body.hvn-overlay .hvn-header::before {
  content: '';
  position: absolute;
  inset: -1px 0 auto 0;
  height: 190%;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(20,26,34,.72) 0%, rgba(20,26,34,.34) 52%, rgba(20,26,34,0) 100%);
  transition: opacity 320ms var(--hvn-ease);
}

body.hvn-overlay .hvn-header__inner { position: relative; z-index: 1; min-height: var(--hvn-nav-h); }
body.hvn-overlay .hvn-header__nav a,
body.hvn-overlay .hvn-header__tel { color: #FFFFFF; }
body.hvn-overlay .hvn-lang a,
body.hvn-overlay .hvn-lang span { color: rgba(255,255,255,.72); }
body.hvn-overlay .hvn-lang [aria-current] { color: #FFFFFF; border-bottom-color: var(--hvn-gold); }
body.hvn-overlay .hvn-burger { color: #FFFFFF; border-color: rgba(255,255,255,.34); }
/* Scoped to the bar. Unscoped, this painted EVERY ghost button on the front
   page white — including the FAQ's phone button on a warm ground, which
   rendered as white-on-cream and was effectively invisible. */
body.hvn-overlay .hvn-header .hvn-btn--ghost { color: #fff; border-color: rgba(255,255,255,.5); }

/* --- stuck state: a real bar, warm and opaque --------------------------- */

body.hvn-overlay .hvn-header.is-stuck {
  position: fixed;
  top: 0;
  background: rgba(247,245,241,.94);
  -webkit-backdrop-filter: saturate(150%) blur(10px);
          backdrop-filter: saturate(150%) blur(10px);
  border-bottom-color: var(--hvn-warm-line);
  box-shadow: var(--hvn-shadow-1);
}

body.hvn-overlay .hvn-header.is-stuck::before { opacity: 0; }
body.hvn-overlay .hvn-header.is-stuck .hvn-header__nav a,
body.hvn-overlay .hvn-header.is-stuck .hvn-header__tel { color: var(--hvn-text); }
body.hvn-overlay .hvn-header.is-stuck .hvn-lang a,
body.hvn-overlay .hvn-header.is-stuck .hvn-lang span { color: var(--hvn-text-secondary); }
body.hvn-overlay .hvn-header.is-stuck .hvn-lang [aria-current] { color: var(--hvn-text); }
body.hvn-overlay .hvn-header.is-stuck .hvn-burger { color: var(--hvn-text); border-color: var(--hvn-border); }
body.hvn-overlay .hvn-header.is-stuck .hvn-btn--ghost { color: var(--hvn-text); border-color: var(--hvn-navy-40); }

/* On warm/paper grounds the ghost button is navy on a hairline. */
.hvn-faqwrap__aside .hvn-btn--ghost,
.hvn-section .hvn-btn--ghost { color: var(--hvn-text); border-color: var(--hvn-navy-40); }
body.hvn-overlay .hvn-header.is-stuck .hvn-mnav { background: var(--hvn-warm); }

/* Hidden until the reader scrolls back up — the bar should not sit on the
   page permanently, it should arrive when it is wanted. */
body.hvn-overlay .hvn-header.is-stuck.is-away { transform: translateY(-102%); }

/* --- the brand lockup in the bar ---------------------------------------- */

.hvn-header__brand { gap: var(--hvn-s3); }
.hvn-mark { display: block; }
.hvn-mark img { display: block; height: 100%; width: auto; }

.hvn-brandplate {
  display: inline-flex;
  align-items: center;
  padding: .45rem .8rem;
  border-radius: var(--hvn-radius-lg);
  background: rgba(247,245,241,.94);
  box-shadow: 0 6px 20px rgba(20,26,34,.24);
  transition: background-color 320ms var(--hvn-ease), box-shadow 320ms var(--hvn-ease), padding 320ms var(--hvn-ease);
}

.hvn-brandplate .hvn-mark { height: 3.4rem; }

/* Once the bar is solid the plate has nothing to separate itself from, so it
   dissolves and the lockup sits directly on the warm bar. */
body.hvn-overlay .hvn-header.is-stuck .hvn-brandplate {
  background: transparent;
  box-shadow: none;
  padding-inline: 0;
}

body.hvn-overlay .hvn-header.is-stuck .hvn-brandplate .hvn-mark { height: 2.9rem; }

/* The Hero must start at the very top of the viewport. */
body.hvn-overlay .hvn-cine { margin-top: 0; }

@media (max-width: 1199px) {
  .hvn-brandplate .hvn-mark { height: 2.8rem; }
  body.hvn-overlay .hvn-header.is-stuck .hvn-brandplate .hvn-mark { height: 2.5rem; }
}

@media (max-width: 600px) {
  .hvn-brandplate { padding: .35rem .55rem; }
  .hvn-brandplate .hvn-mark { height: 2.35rem; }
  :root { --hvn-nav-h: 4.25rem; }
}

/* =========================================================================
   4. HERO PRESENTATION
   The choreography is untouched. Only the framing changes: the stage now runs
   to the top of the viewport under the nav, and the copy is pushed clear of it.
   ========================================================================= */

body.hvn-overlay .hvn-cine__copy {
  padding-top: calc(var(--hvn-nav-h) + var(--hvn-s6));
}

.hvn-cine h1 { letter-spacing: -.015em; }

.hvn-cine__intro .hvn-eyebrow,
.hvn-cine__end .hvn-eyebrow { color: var(--hvn-gold); }

/* A quiet gold hairline under the Hero, so the cinema ends on a brand note
   rather than on a colour change. */
.hvn-cine::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 3px;
  background: linear-gradient(to right, transparent, var(--hvn-gold) 22%, var(--hvn-gold) 78%, transparent);
  opacity: .65;
}

/* =========================================================================
   5. FULL-BLEED REEL
   ========================================================================= */

.hvn-reel {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  min-height: clamp(26rem, 62vh, 40rem);
  display: grid;
  align-items: end;
  overflow: hidden;
  background: var(--hvn-charcoal);
  isolation: isolate;
}

.hvn-reel__media { position: absolute; inset: 0; z-index: 0; }

.hvn-reel__poster,
.hvn-reel__vid {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.hvn-reel__vid { opacity: 0; transition: opacity 600ms linear; }
.hvn-reel__vid.is-on { opacity: 1; }

.hvn-reel__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to top, rgba(20,26,34,.90) 0%, rgba(20,26,34,.52) 46%, rgba(20,26,34,.20) 100%),
    linear-gradient(to right, rgba(20,26,34,.72) 0%, rgba(20,26,34,0) 62%);
}

.hvn-reel__inner {
  position: relative;
  z-index: 2;
  padding-block: clamp(2.5rem, 1.5rem + 5vw, 5rem);
  color: var(--hvn-text-invert);
}

.hvn-reel .hvn-eyebrow { color: var(--hvn-gold); }

.hvn-reel__title {
  color: var(--hvn-text-invert);
  font-size: var(--hvn-fs-display);
  line-height: var(--hvn-lh-tight);
  letter-spacing: -.015em;
  font-weight: 600;
  margin: 0 0 var(--hvn-s4);
  max-width: 18ch;
}

.hvn-reel__lede { color: rgba(255,255,255,.84); max-width: 46ch; margin: 0 0 var(--hvn-s6); }

/* =========================================================================
   6. VIENNA NETWORK
   ========================================================================= */

.hvn-net {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  background: var(--hvn-charcoal);
  color: var(--hvn-text-invert);
  padding-block: clamp(3rem, 2rem + 5vw, 6rem);
  overflow: hidden;
  isolation: isolate;
}

.hvn-net__glow {
  position: absolute;
  inset: -30% -10% auto -10%;
  height: 130%;
  pointer-events: none;
  background: radial-gradient(60% 55% at 72% 42%, rgba(34,58,87,.62) 0%, rgba(20,26,34,0) 70%);
}

.hvn-net__inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: clamp(2rem, 1rem + 4vw, 4.5rem);
  grid-template-columns: 1fr;
  align-items: center;
}

.hvn-net .hvn-eyebrow { color: var(--hvn-gold); }

.hvn-net__title {
  color: var(--hvn-text-invert);
  font-size: var(--hvn-fs-display);
  line-height: var(--hvn-lh-tight);
  letter-spacing: -.015em;
  font-weight: 600;
  margin: 0 0 var(--hvn-s5);
  max-width: 16ch;
}

.hvn-net__lede { color: rgba(255,255,255,.78); max-width: 48ch; }

.hvn-net__facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--hvn-s5) var(--hvn-s6);
  margin: var(--hvn-s7) 0;
}

.hvn-net__facts div { border-top: 1px solid rgba(255,255,255,.20); padding-top: var(--hvn-s3); }
.hvn-net__facts dt {
  font-size: var(--hvn-fs-label); letter-spacing: var(--hvn-tr-label);
  text-transform: uppercase; color: var(--hvn-gold); margin-bottom: var(--hvn-s2);
}
.hvn-net__facts dd { margin: 0; font-size: var(--hvn-fs-h3); font-weight: 500; }

.hvn-net__fig { margin: 0; }
.hvn-net__svg { width: 100%; height: auto; display: block; overflow: visible; }

.hvn-net__cap {
  margin-top: var(--hvn-s4);
  font-size: var(--hvn-fs-small);
  color: rgba(255,255,255,.52);
  max-width: 46ch;
}

.hvn-net__hub-label {
  fill: #F7F5F1;
  font-family: var(--hvn-font);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: .22em;
}

/* --- route drawing ------------------------------------------------------ */

.hvn-net__route {
  stroke-dasharray: var(--len, 600);
  stroke-dashoffset: var(--len, 600);
  transition: stroke-dashoffset 1500ms var(--hvn-ease), stroke-opacity 240ms linear, stroke-width 240ms linear;
}

.hvn-net.is-in .hvn-net__route { stroke-dashoffset: 0; }
.hvn-net.is-in .hvn-net__route[data-i="1"] { transition-delay: 140ms; }
.hvn-net.is-in .hvn-net__route[data-i="2"] { transition-delay: 280ms; }
.hvn-net.is-in .hvn-net__route[data-i="3"] { transition-delay: 420ms; }
.hvn-net.is-in .hvn-net__route[data-i="4"] { transition-delay: 560ms; }
.hvn-net.is-in .hvn-net__route[data-i="5"] { transition-delay: 700ms; }

.hvn-net__river-line { stroke-dasharray: 3 9; }

.hvn-net__node { cursor: default; }
.hvn-net__node circle { transition: r 260ms var(--hvn-ease), fill-opacity 260ms linear; }
.hvn-net__node:hover .hvn-net__halo,
.hvn-net__node:focus-visible .hvn-net__halo { r: 30; fill-opacity: .26; }
.hvn-net__node:focus-visible { outline: none; }
.hvn-net__node:focus-visible .hvn-net__halo { stroke: #F7F5F1; stroke-width: 2; }

.hvn-net__route.is-lit { stroke-opacity: 1; stroke-width: 3.4; }

.hvn-net__pulse { transform-origin: 450px 350px; animation: hvnPulse 3.6s var(--hvn-ease) infinite; }

@keyframes hvnPulse {
  0%, 100% { transform: scale(1);    opacity: .55; }
  50%      { transform: scale(1.22); opacity: .18; }
}

@media (min-width: 960px) {
  .hvn-net__inner { grid-template-columns: 1fr 1.08fr; }
  .hvn-net__facts { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* =========================================================================
   7. SECTION SURFACES — break the white/navy alternation
   ========================================================================= */

.hvn-svc  { background: var(--hvn-warm-2); }
.hvn-crew { background: var(--hvn-warm-2); }
.hvn-quick { background: var(--hvn-warm-2); }
.hvn-area { background: var(--hvn-warm-2); }
.hvn-ctap--light { background: var(--hvn-warm-2); border-color: var(--hvn-warm-line); }

/* The honesty band moves to charcoal so it reads as a deliberate pause rather
   than as one more navy block. */
.hvn-assure { background: var(--hvn-charcoal); }
.hvn-assure .hvn-eyebrow { color: var(--hvn-gold); }

.hvn-band { background: var(--hvn-charcoal); }
.hvn-band__kind { color: var(--hvn-gold); }

.hvn-footer { background: var(--hvn-charcoal); }
.hvn-footer h2 { color: var(--hvn-gold); }

/* =========================================================================
   8. CARDS, DEPTH AND HOVER
   ========================================================================= */

.hvn-svc__card {
  border-color: transparent;
  box-shadow: var(--hvn-shadow-1);
  transition: transform 320ms var(--hvn-ease), box-shadow 320ms var(--hvn-ease);
}

.hvn-svc__card:hover,
.hvn-svc__card:focus-within {
  transform: translateY(-6px);
  box-shadow: var(--hvn-shadow-2);
  border-color: transparent;
}

.hvn-svc__media::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to top, rgba(20,26,34,.42) 0%, rgba(20,26,34,0) 46%);
}

.hvn-svc__num {
  background: var(--hvn-gold);
  color: #17212C;
  border-radius: 0 var(--hvn-radius-lg) 0 0;
}

.hvn-svc__go { color: var(--hvn-gold-deep); }
.hvn-svc__card:hover .hvn-shot img { transform: scale(1.06); }
.hvn-svc__media .hvn-shot img { transition: transform 700ms var(--hvn-ease); }

.hvn-quick__panel { box-shadow: var(--hvn-shadow-1); border-color: transparent; }

/* =========================================================================
   9. FAQ — animated disclosure
   ========================================================================= */

.hvn-faq details {
  background: #FFFFFF;
  border: 1px solid transparent;
  border-radius: var(--hvn-radius-lg);
  margin-bottom: var(--hvn-s3);
  box-shadow: var(--hvn-shadow-1);
  transition: box-shadow 260ms var(--hvn-ease);
}

.hvn-faq { border-top: 0; }
.hvn-faq details:hover { box-shadow: var(--hvn-shadow-2); }
.hvn-faq summary { padding: var(--hvn-s4) 3rem var(--hvn-s4) var(--hvn-s5); }
.hvn-faq summary::after { right: 1.25rem; border-color: var(--hvn-gold-deep); }
.hvn-faq p { padding: 0 var(--hvn-s5) var(--hvn-s5); margin: 0; }

.hvn-faq details[open] > *:not(summary) { animation: hvnReveal 320ms var(--hvn-ease) both; }

@keyframes hvnReveal {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* =========================================================================
   10. SCROLL REVEALS
   ========================================================================= */

@media (prefers-reduced-motion: no-preference) {
  .hvn-rise {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity 700ms var(--hvn-ease), transform 700ms var(--hvn-ease);
  }
  .hvn-rise.is-in { opacity: 1; transform: none; }
  .hvn-rise:nth-child(2) { transition-delay: 90ms; }
  .hvn-rise:nth-child(3) { transition-delay: 180ms; }
  .hvn-rise:nth-child(4) { transition-delay: 270ms; }
  .hvn-rise:nth-child(5) { transition-delay: 360ms; }
  .hvn-rise:nth-child(6) { transition-delay: 450ms; }
}

/* =========================================================================
   11. MOBILE CONVERSION BAR — gold primary, charcoal ground
   ========================================================================= */

.hvn-mbar__item { background: var(--hvn-charcoal); }
.hvn-mbar__item--cta { background: var(--hvn-gold); color: #17212C; }

/* =========================================================================
   12. REDUCED MOTION
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  .hvn-net__route { stroke-dasharray: none; stroke-dashoffset: 0; transition: none; }
  .hvn-net__pulse { animation: none; }
  .hvn-rise { opacity: 1; transform: none; transition: none; }
  .hvn-reel__vid { display: none; }
  .hvn-svc__card,
  .hvn-svc__media .hvn-shot img,
  .hvn-btn,
  .hvn-brandplate,
  body.hvn-overlay .hvn-header { transition: none; }
  .hvn-svc__card:hover { transform: none; }
  .hvn-svc__card:hover .hvn-shot img { transform: none; }
  .hvn-btn--primary:hover { transform: none; }
  .hvn-faq details[open] > *:not(summary) { animation: none; }
  body.hvn-overlay .hvn-header.is-stuck.is-away { transform: none; }
}

/* =========================================================================
   13. FULL-BLEED WITHOUT A SCROLLBAR ARTEFACT
   `width: 100vw` counts the scrollbar; the document's client width does not.
   On a desktop with a classic scrollbar the two full-bleed sections were
   therefore 8px wider than the page and produced horizontal scroll.
   `overflow-x: clip` trims that without creating a scroll container, so the
   Hero's `position: sticky` pin keeps working — `hidden` would have broken it.
   ========================================================================= */

html, body { overflow-x: clip; }
.hvn-reel, .hvn-net { max-width: 100vw; }

/* =========================================================================
   14. HEADER FITS ON ONE ROW
   Brand 110 + nav 548 + actions 465 + gaps 48 = 1171 against 1140 of usable
   width, so the bar wrapped onto two rows at 1440px. The lockup is given the
   size it needs to be legible and the space is found by tightening the nav and
   by dropping the phone number from the bar below 1500px — it is still one tap
   away in the mobile bar, the contact band and the footer.
   ========================================================================= */

.hvn-header__inner { flex-wrap: nowrap; gap: var(--hvn-s4); }
.hvn-header__nav { min-width: 0; }
.hvn-header__nav ul { flex-wrap: nowrap; gap: var(--hvn-s4); }
.hvn-header__nav a { white-space: nowrap; font-size: .9rem; }
.hvn-header__actions { gap: var(--hvn-s3); }
.hvn-header__cta { white-space: nowrap; }

@media (max-width: 1499px) {
  body.hvn-overlay .hvn-header__tel,
  .hvn-header__tel { display: none; }
}

/* At 54px the lockup's "LOGISTICS & TRANSPORT" and "VIENNA, AUSTRIA" lines
   were unreadable. 4rem is the smallest size at which they hold together. */
.hvn-brandplate { padding: .4rem .7rem; }
.hvn-brandplate .hvn-mark { height: 4rem; }
body.hvn-overlay .hvn-header.is-stuck .hvn-brandplate .hvn-mark { height: 3.4rem; }

@media (max-width: 1199px) {
  .hvn-brandplate .hvn-mark { height: 3.3rem; }
  body.hvn-overlay .hvn-header.is-stuck .hvn-brandplate .hvn-mark { height: 3rem; }
}

@media (max-width: 600px) {
  .hvn-brandplate .hvn-mark { height: 2.7rem; }
  body.hvn-overlay .hvn-header.is-stuck .hvn-brandplate .hvn-mark { height: 2.5rem; }
}

/* =========================================================================
   15. THE OVERLAY BAR MUST SPAN THE VIEWPORT
   `position: absolute` resolves `left/right` against the nearest positioned
   ancestor, and in Hello Elementor's markup that ancestor turned out to be a
   wrap-width element: the bar measured 1140px at x=143 while every section
   around it measured the full 1425px, so the nav looked inset from the page.
   `fixed` resolves against the viewport instead.

   The Test/Lab banner comes out of flow at the same time. That is what lets
   the Hero genuinely start at the top of the viewport — the banner floats over
   it rather than pushing it down — and in Production, where the banner does
   not exist at all, the layout is identical with the offset at zero.
   ========================================================================= */

.hvn-lab-banner {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 90;
}

body.hvn-overlay .hvn-header,
body.hvn-overlay .hvn-header.is-stuck {
  position: fixed;
  top: var(--hvn-banner-h, 0px);
  left: 0;
  right: 0;
  width: auto;
}

/* Non-front-end templates keep the ordinary flow header, so they need the
   banner's height back as spacing. */
body:not(.hvn-overlay) { padding-top: var(--hvn-banner-h, 0px); }

/* Hello Elementor's theme.css caps `.site-header` at `--container-width`
   (1140px here) and centres it with `margin-inline: auto`. Harmless while the
   header was a static block inside a full-width body; fatal once it is fixed,
   because the bar then floated 143px inside the page while every section
   around it ran edge to edge. */
body.hvn-overlay .hvn-header,
body.hvn-overlay .hvn-header.is-stuck {
  max-width: none;
  margin-inline: 0;
  display: block;
}

body.hvn-overlay .hvn-header .hvn-wrap { width: 100%; }

/* =========================================================================
   16. FOOTER COLUMNS
   `auto-fit, minmax(16rem, 1fr)` inside the 1.6fr share resolved to two
   columns, so "Gebiet & Sprachen" fell underneath "Leistungen" and left a
   whole empty column beside it. Three explicit columns once there is room.
   ========================================================================= */

@media (min-width: 860px) {
  .hvn-footer__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--hvn-s6); }
}

@media (min-width: 960px) {
  .hvn-footer__top { grid-template-columns: .7fr 2fr; }
}

.hvn-footer__plate { align-self: start; }
.hvn-footer li a:hover { color: var(--hvn-gold-lift); }

/* =========================================================================
   PHASE 1 — GLOBAL UX FOUNDATION
   Logo state system · consolidated CTA + glint · motion vocabulary · strip.
   Appended as one block so the phase can be read, reviewed and reverted as a
   unit. Everything below overrides only what it names.
   ========================================================================= */

/* -------------------------------------------------------------------------
   P1.1  BRAND LOCKUP — state aware, no plate

   The plate is gone. Both official one-colour variants are stacked in the same
   grid cell and cross-faded, so the bar never reflows as it changes state and
   the second variant is already decoded when the swap happens.
   ---------------------------------------------------------------------- */

.hvn-brandplate {
  /* Neutralised rather than deleted: the footer markup and the older raster
     helper still reference it, and Phase 1 is not a markup purge. */
  background: transparent;
  box-shadow: none;
  padding: 0;
}

.hvn-brand { display: inline-flex; align-items: center; }

.hvn-brand__stack {
  display: grid;
  grid-template-areas: "mark";
  align-items: center;
  line-height: 0;
}

/*
 * Sizing note. The delivered artwork carries its own clear space: measured on
 * the rendered file, the ink occupies 80% of the canvas height and the
 * wordmark block only ~38% of it. So a 62px canvas puts the word "HAVEN" at
 * roughly 24px and the tagline at 6px — legible, but visually outranked by a
 * 56px button and a 44px nav row. The canvas is therefore sized against the
 * wordmark rather than against the bar.
 */
/*
 * MICRO-PATCH, post-Phase-2.1. Every rule below now sets `--hvn-lk-ink` — the
 * height the VISIBLE MARK should be — instead of `height`, which sized the
 * padded canvas and therefore rendered the mark about a fifth smaller than the
 * number said. Measured on the artwork (both one-colour variants are
 * byte-for-byte identical in geometry: canvas 1200x1086, ink (76,143)-(1124,1009),
 * padding L/R 6.33%, T 13.17%, B 7.09%, ink = 79.74% of canvas height).
 *
 * The single rule here turns that intent into a box and pulls the transparent
 * canvas back out of the layout with negative margins derived from the same
 * measurements. The artwork is untouched — not cropped, not re-exported.
 *
 * The margins are in the transition alongside the height, or the mark jumps
 * sideways as the bar changes state instead of easing with it.
 */
.hvn-lockup {
  grid-area: mark;
  display: block;
  width: auto;

  --hvn-lk-ink: 4.5rem;
  --hvn-lk-box: calc(var(--hvn-lk-ink) / 0.7974);

  height: var(--hvn-lk-box);
  margin-top:    calc(var(--hvn-lk-box) * -0.1317);
  margin-bottom: calc(var(--hvn-lk-box) * -0.0709);
  margin-left:   calc(var(--hvn-lk-box) * -0.0700);
  margin-right:  calc(var(--hvn-lk-box) * -0.0700);

  transition:
    opacity 320ms var(--hvn-ease),
    height 320ms var(--hvn-ease),
    margin 320ms var(--hvn-ease);
}

/* Over the Hero: white. Once the bar is warm and solid: navy. */
.hvn-brand__on-dark { opacity: 1; }
.hvn-brand__on-warm { opacity: 0; }

body.hvn-overlay .hvn-header.is-stuck .hvn-brand__on-dark { opacity: 0; }
body.hvn-overlay .hvn-header.is-stuck .hvn-brand__on-warm { opacity: 1; }

/* Templates without an overlay Hero have a warm bar from the first paint. */
body:not(.hvn-overlay) .hvn-brand__on-dark { opacity: 0; }
body:not(.hvn-overlay) .hvn-brand__on-warm { opacity: 1; }

/*
 * Over the Hero the bar is given room so the lockup can carry brand weight;
 * once it turns solid it compacts, which is what a good sticky bar does
 * anyway — the brand is established by then and the content matters more.
 */
body.hvn-overlay .hvn-header:not(.is-stuck) .hvn-header__inner { min-height: 6.5rem; }
body.hvn-overlay .hvn-header.is-stuck .hvn-lockup { --hvn-lk-ink: 3.5rem; }
body:not(.hvn-overlay) .hvn-lockup { --hvn-lk-ink: 3.5rem; }

@media (max-width: 1199px) {
  .hvn-lockup { --hvn-lk-ink: 3.9rem; }
  body.hvn-overlay .hvn-header:not(.is-stuck) .hvn-header__inner { min-height: 5.75rem; }
  body.hvn-overlay .hvn-header.is-stuck .hvn-lockup,
  body:not(.hvn-overlay) .hvn-lockup { --hvn-lk-ink: 3.1rem; }
}

@media (max-width: 600px) {
  .hvn-lockup { --hvn-lk-ink: 3.1rem; }
  body.hvn-overlay .hvn-header:not(.is-stuck) .hvn-header__inner { min-height: 5rem; }
  body.hvn-overlay .hvn-header.is-stuck .hvn-lockup,
  body:not(.hvn-overlay) .hvn-lockup { --hvn-lk-ink: 2.7rem; }
}

/* The footer ground is charcoal, so the white lockup is the correct variant
   there too — same artwork, no plate, no derivative. */
.hvn-footer__plate { background: transparent; box-shadow: none; padding: 0; }
/* Height is set in haven-p2.css section E, where it is derived from the
   artwork's measured ink box rather than from its padded canvas. Leaving a
   second height here would just be a value for that one to fight. */

/* -------------------------------------------------------------------------
   P1.2  CTA SYSTEM — one place, three roles, one glint

   Button rules previously lived in three files. The role definitions stay
   where they are; what is consolidated here is the interaction layer, so
   hover, focus, press and the sweep are defined exactly once.
   ---------------------------------------------------------------------- */

.hvn-btn {
  position: relative;
  overflow: hidden;
  /* Creates a stacking context so the sweep can sit at z-index -1: painted
     after the button's own background, before the label. The label therefore
     never loses contrast while the highlight passes under it. */
  isolation: isolate;
  transition:
    background-color var(--hvn-dur) var(--hvn-ease),
    color var(--hvn-dur) var(--hvn-ease),
    border-color var(--hvn-dur) var(--hvn-ease),
    transform 160ms var(--hvn-ease),
    box-shadow var(--hvn-dur) var(--hvn-ease);
}

/* The sweep itself. Parked off the left edge and only animated on demand —
   there is no perpetual animation anywhere in this system. */
.hvn-btn::before {
  content: '';
  position: absolute;
  z-index: -1;
  top: -60%;
  bottom: -60%;
  left: 0;
  width: 38%;
  pointer-events: none;
  transform: translateX(-220%) skewX(-18deg);
  background: linear-gradient(
    100deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 255, 255, .52) 50%,
    rgba(255, 255, 255, 0) 100%
  );
}

/* Darker faces need a brighter sweep to read at all; the outline variants on
   light grounds need a much quieter one or it looks like a rendering fault. */
.hvn-btn--ondark::before { background: linear-gradient(100deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.34) 50%, rgba(255,255,255,0) 100%); }
.hvn-btn--ghost::before  { background: linear-gradient(100deg, rgba(34,58,87,0) 0%, rgba(34,58,87,.16) 50%, rgba(34,58,87,0) 100%); }

@keyframes hvnGlint {
  from { transform: translateX(-220%) skewX(-18deg); }
  to   { transform: translateX(320%)  skewX(-18deg); }
}

/* Pointer and keyboard get the same affordance. */
.hvn-btn:hover::before,
.hvn-btn:focus-visible::before {
  animation: hvnGlint 760ms var(--hvn-ease) 1;
}

.hvn-btn:hover  { transform: translateY(-2px); }
.hvn-btn:active { transform: translateY(0); transition-duration: 60ms; }

/* One restrained entrance sweep, on the Hero's primary call to action only,
   once, after the Hero copy has settled. Not a loop and not site-wide. */
.hvn-cine__intro .hvn-btn--primary::before {
  animation: hvnGlint 900ms var(--hvn-ease) 1400ms 1;
}

/* Touch: hover is not a state a finger can express, so the sweep is removed
   rather than left to fire on tap and look like a glitch. Colour, shadow and
   the press state carry the feedback instead. */
@media (hover: none) {
  .hvn-btn::before { display: none; }
  .hvn-btn:hover { transform: none; }
}

/* Focus stays loud. The ring is drawn outside the button, so `overflow:
   hidden` above cannot clip it. */
.hvn-btn:focus-visible {
  outline: 3px solid var(--hvn-focus-ring) !important;
  outline-offset: 3px !important;
}

.hvn-btn--ondark:focus-visible,
body.hvn-overlay .hvn-header .hvn-btn:focus-visible { outline-color: #FFFFFF !important; }

/* -------------------------------------------------------------------------
   P1.3  MOTION VOCABULARY

   Four primitives, all driven by one observer adding `.is-in`. `.hvn-reveal`
   is kept as an alias of `.hvn-rise` so the three sections already using it
   keep working without touching their markup.
   ---------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {

  /* 1. rise — the base entrance */
  .hvn-reveal {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity 700ms var(--hvn-ease), transform 700ms var(--hvn-ease);
  }
  .hvn-reveal.is-in { opacity: 1; transform: none; }

  /* 2. staggered reveal — children arrive in sequence, capped at six so a
        long list never ends in a visible wait */
  .hvn-stagger > * {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 620ms var(--hvn-ease), transform 620ms var(--hvn-ease);
  }
  .hvn-stagger.is-in > * { opacity: 1; transform: none; }
  .hvn-stagger.is-in > *:nth-child(1) { transition-delay: 0ms; }
  .hvn-stagger.is-in > *:nth-child(2) { transition-delay: 80ms; }
  .hvn-stagger.is-in > *:nth-child(3) { transition-delay: 160ms; }
  .hvn-stagger.is-in > *:nth-child(4) { transition-delay: 240ms; }
  .hvn-stagger.is-in > *:nth-child(5) { transition-delay: 320ms; }
  .hvn-stagger.is-in > *:nth-child(n+6) { transition-delay: 380ms; }

  /* 3. media mask reveal — the image is uncovered rather than faded, which
        reads as intent rather than as a slow load.

        CORRECTED IN PHASE 2. The clip was originally on `.hvn-mask` itself,
        which is also the element the reveal observer watches. Chromium
        computes an IntersectionObserver's intersection rectangle after the
        target's own clip-path: an element clipped to zero height has zero
        intersection area, never reaches the 0.08 threshold, and is therefore
        never given `.is-in` — it hides itself from the thing that would
        reveal it. The primitive was written in Phase 1 and first used in
        Phase 2, which is when it turned out never to have worked: the three
        Phase 2 figures rendered as empty columns.

        The clip now goes on the children. The observed box is unclipped, the
        visual result is identical. */
  .hvn-mask > * { clip-path: inset(0 0 100% 0); transition: clip-path 900ms var(--hvn-ease); }
  .hvn-mask.is-in > * { clip-path: inset(0 0 0 0); }

  /* 4. bounded parallax — the engine writes --hvn-par in the range -1..1 and
        the travel is capped in CSS, so it can never become a scroll effect
        large enough to cause overlap or layout surprise */
  .hvn-par { transform: translate3d(0, calc(var(--hvn-par, 0) * var(--hvn-par-max, 14px)), 0); will-change: transform; }
}

/* -------------------------------------------------------------------------
   P1.4  INFORMATION STRIP
   ---------------------------------------------------------------------- */

.hvn-strip {
  position: relative;
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  background: var(--hvn-charcoal);
  border-block: 1px solid rgba(255, 255, 255, .09);
  color: var(--hvn-text-invert);
  overflow: hidden;
}

/* A fixed height reserved up front — the band must never change size as the
   items load or the language switches, or it would push the page. */
.hvn-strip__mask {
  --hvn-strip-h: 3.5rem;
  height: var(--hvn-strip-h);
  display: flex;
  align-items: center;
  overflow: hidden;
  /* Fades at both ends so items enter and leave rather than being cut off. */
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 6%, #000 94%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 6%, #000 94%, transparent 100%);
}

.hvn-strip__track { display: flex; width: max-content; will-change: transform; }

.hvn-strip__run {
  display: flex;
  align-items: center;
  gap: clamp(1.75rem, 1rem + 2.4vw, 3.25rem);
  list-style: none;
  margin: 0;
  padding: 0 clamp(.875rem, .5rem + 1.2vw, 1.625rem);
}

.hvn-strip__item {
  display: inline-flex;
  align-items: baseline;
  gap: .6rem;
  white-space: nowrap;
}

/* A hairline gold tick before each fact — the separator is the brand accent
   rather than a bullet or a pipe. */
.hvn-strip__item::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--hvn-gold);
  flex: none;
  transform: translateY(-.15em);
}

.hvn-strip__k {
  font-size: var(--hvn-fs-label);
  letter-spacing: var(--hvn-tr-label);
  text-transform: uppercase;
  color: var(--hvn-gold);
}

.hvn-strip__v {
  font-size: var(--hvn-fs-small);
  font-weight: 500;
  color: rgba(255, 255, 255, .90);
  font-variant-numeric: tabular-nums;
}

@keyframes hvnStrip {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

@media (prefers-reduced-motion: no-preference) {
  .hvn-strip__track { animation: hvnStrip var(--hvn-strip-dur, 64s) linear infinite; }
  /* Readable on demand: pointing at it or tabbing into it stops it. */
  .hvn-strip:hover .hvn-strip__track,
  .hvn-strip:focus-within .hvn-strip__track { animation-play-state: paused; }
}

@media (max-width: 600px) { .hvn-strip__mask { --hvn-strip-h: 3.25rem; } }

/* -------------------------------------------------------------------------
   P1.5  REDUCED MOTION
   ---------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .hvn-btn::before,
  .hvn-cine__intro .hvn-btn--primary::before { animation: none; display: none; }
  .hvn-btn:hover { transform: none; }
  .hvn-lockup { transition: none; }

  /* The strip becomes a static, horizontally scrollable row of the same
     facts — the content stays available, the movement does not. */
  .hvn-strip__track { animation: none; width: auto; }
  .hvn-strip__mask { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .hvn-strip__run[aria-hidden="true"] { display: none; }

  .hvn-reveal, .hvn-stagger > * { opacity: 1; transform: none; transition: none; }
  .hvn-mask > * { clip-path: none; transition: none; }
  .hvn-par { transform: none; }
}

/* -------------------------------------------------------------------------
   P1.6  TWO CORRECTIONS FOUND IN VALIDATION
   ---------------------------------------------------------------------- */

/*
 * 1. Layout shift on load.
 *
 * The overlay bar is offset by the Test/Lab banner's height, which only
 * JavaScript can measure, so the bar started at top:0 and jumped down once the
 * measurement arrived — a real, recorded 0.05 layout shift attributed to the
 * header and the Hero copy.
 *
 * Seeding the variable with the measured heights (37px, and 57px below 600px
 * where the banner wraps to two lines) means the JavaScript correction is a
 * no-op in the ordinary case and only does anything if the banner is ever
 * restyled. In Production, where the banner does not exist, the value is
 * overwritten with 0 by the same code.
 */
:root { --hvn-banner-h: 37px; }
@media (max-width: 600px) { :root { --hvn-banner-h: 57px; } }

/*
 * 2. The bar on templates without a Hero was still HAVEN Paper (#FDFDFD)
 * while the body around it had moved to the warm ramp, so the navigation read
 * as a slightly cooler rectangle floating on a warm page. It now uses the same
 * warm surface the sticky state uses, which is what makes the two states look
 * like one component.
 */
body:not(.hvn-overlay) .hvn-header {
  background: var(--hvn-warm);
  border-bottom-color: var(--hvn-warm-line);
}

body:not(.hvn-overlay) .hvn-mnav { background: var(--hvn-warm); }

/*
 * 3. The page ground.
 *
 * Elementor's Global Kit writes `.elementor-kit-5 { background-color: #FDFDFD }`
 * — HAVEN Paper, the value the kit was configured with long before the warm
 * ramp existed. A class selector beats a bare `body`, so the warm background
 * above never applied and inner pages sat on a cooler white than their own
 * sections and navigation.
 *
 * Matched on the attribute rather than the numbered class so this keeps
 * working if the kit is ever rebuilt under a different post ID. The kit
 * setting itself is left alone: it is the client's Global Design System entry
 * and changing it is a database edit, not a stylesheet fix.
 */
body[class*="elementor-kit"] { background-color: var(--hvn-warm); }
