/* Quill-Reference — foundation + Navbar + Hero.
   Rebuilt section-by-section against the bloom3d.studio reference. Other
   sections were deleted, not hidden — they get rebuilt fresh the same way. */

@font-face {
  font-family: "Helvetica Now";
  src: url("../fonts/HelveticaNowDisplay-Regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Helvetica Now";
  src: url("../fonts/HelveticaNowDisplay-Medium.otf") format("opentype");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Helvetica Now";
  src: url("../fonts/HelveticaNowDisplay-Bold.otf") format("opentype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

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

:root {
  --bg: #f7f7f7;
  --bg-alt: #f5f5f3;
  --ink: #2e2e2e;
  --dim: rgba(23,23,23,.55);
  --dimmer: rgba(23,23,23,.35);
  --line: rgba(23,23,23,.12);
  --line-strong: rgba(23,23,23,.2);
  --panel-dark: #171717;
  --panel-dark-line: rgba(255,255,255,.14);
  --panel-dark-ink: #f5f5f3;
  --panel-dark-dim: rgba(245,245,243,.58);
  --ease: cubic-bezier(.23, 1, .32, 1);
  --nav-gutter: 2rem;
  --gutter: clamp(20px, 5vw, 5rem);
}

html, body { min-height: 100%; background: var(--bg); color: var(--ink); }
html { scroll-behavior: smooth; }
/* No root font-size override at any width — checked directly: the reference
   CSS has exactly two `html {}` rules (a base reset and one setting
   height:100%) and neither touches font-size, at any media width. A prior
   claim here that it stepped up to 22px above ~1920px had no basis in the
   actual scraped CSS and has been removed; root stays the 16px browser
   default throughout. */
body {
  font-family: "Helvetica Now", Arial, sans-serif;
  overflow-x: hidden;
}

a { color: inherit; }
img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; }

/* ---------- Preloader ---------- */
/* Values (sizes, the clip-path polygons, opacities) copied exactly from the
   reference — see site.js for the GSAP timeline that drives this. The
   clip-path starts as an imperceptible hairline slit at the exact center
   (a wide rectangle with a ~0.02px-wide notch cut into its middle, which
   reads as fully opaque white) and gets animated open in two steps: first
   to a 15rem square window, then to the full viewport. */
.preloader {
  z-index: 999;
  background: #fff;
  display: flex;
  flex-flow: column;
  justify-content: space-between;
  align-items: center;
  width: 100vw;
  height: 100dvh;
  padding: 2rem;
  position: fixed;
  inset: 0;
  clip-path: polygon(0% 0%, 0% 100%, calc(50% - 0.01px) 100%, calc(50% - 0.01px) calc(50% - 0.01px), calc(50% + 0.01px) calc(50% - 0.01px), calc(50% + 0.01px) calc(50% + 0.01px), calc(50% - 0.01px) calc(50% + 0.01px), calc(50% - 0.01px) 100%, 100% 100%, 100% 0%);
}
.preloader-mask {
  z-index: 2;
  width: 0%;
  height: 0%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.preloader-num {
  opacity: 0;
  font-size: 1.125rem;
  letter-spacing: .009375rem;
  line-height: 1.4;
  color: var(--ink);
}
/* Giant faint watermark of Quill's own mark, not a bare/full-opacity logo —
   opacity is animated up to only 0.03 (see site.js), same as reference.
   Real vector logo now (see the <symbol> defs at the top of body), so
   color comes from `fill` on each part directly instead of a raster
   `filter` — .logo-colors below sets both parts on every instance. */
.preloader-logo {
  z-index: 1;
  opacity: 0;
  width: 15rem;
  height: auto;
  position: absolute;
  top: 50%;
  transform: translate(0, -50%);
}
.preloader-content {
  opacity: 0;
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: center;
  gap: 1rem;
}
/* 5rem, not the reference's 6.875rem — same ratio-compensation reasoning as
   .navbar-logo: reference's wordmark is ~4.6:1, Quill's mark is ~1.8:1, so
   matching their width would look oversized at that squarer ratio. */
.preloader-content-logo { width: 5rem; height: auto; }

/* Logo color system — one place, not scattered per-instance. Four variants,
   each a reusable modifier class on the wrapping <svg>; every usage site
   picks whichever one fits its background instead of hand-setting fill.
     .logo--white       both parts white   (on dark, no gold accent wanted)
     .logo--black       both parts black   (on light, no gold accent wanted)
     .logo--white-gold  white wordmark + gold bulb   (on dark)
     .logo--black-gold  black wordmark + gold bulb   (on light)
   No default fill on .logo-wordmark/.logo-bulb themselves — every instance
   must carry one of the four classes above, so there's no bare/unstyled
   state to accidentally fall back to. */
.logo--white .logo-wordmark, .logo--white .logo-bulb { fill: #fff; }
.logo--black .logo-wordmark, .logo--black .logo-bulb { fill: #171717; }
.logo--white-gold .logo-wordmark { fill: #fff; }
.logo--white-gold .logo-bulb { fill: #d4a537; }
.logo--black-gold .logo-wordmark { fill: #171717; }
.logo--black-gold .logo-bulb { fill: #d4a537; }
.preloader-content-text {
  color: #595959;
  font-weight: 500;
  font-size: 1rem;
  letter-spacing: .009375rem;
  line-height: 1.4;
}

/* ---------- Navbar (fixed, persistent) ---------- */
.navbar {
  position: fixed;
  inset: 1rem var(--nav-gutter) auto;
  z-index: 777;
}
.navbar-container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}
/* The two navbar controls calculate contrast independently from the pixels
   directly behind them. Difference blending makes white turn black over a
   light backdrop and remain white over a dark one, including when the two
   controls sit over differently exposed areas of the same photograph. */
.navbar-logo-wrapper {
  position: relative;
  display: block;
  width: 3.614rem;
  height: 2rem;
  line-height: 0;
}
.navbar-logo {
  /* 2rem, not the reference's 1.25rem: that value was calibrated for their
     own wide wordmark (viewBox ~4.85:1). Quill's mark is much more square
     (~1.8:1) — matching their pixel height would render ours narrower and
     visually lighter than intended, so this compensates for the ratio. */
  height: 2rem;
  width: auto;
}
.navbar-logo-wordmark,
.navbar-logo-bulb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.navbar-logo-wordmark {
  fill: #fff;
  transition: fill .6s cubic-bezier(.23, 1, .32, 1);
}
.navbar-logo-wordmark use {
  fill: inherit;
  transition: fill .6s cubic-bezier(.23, 1, .32, 1);
}
.navbar-logo-bulb { fill: #d4a537; }
.navbar-logo-wrapper.has-light-backdrop .navbar-logo-wordmark { fill: #171717; }

/* Menu button: reference pads the button itself by 1rem around a 1.5rem
   icon (3.5rem total hit area) — the icon sits inset from the navbar edge
   by that 1rem, not flush against it. */
.navbar-menu-btn {
  padding: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.navbar-menu-icon {
  width: 1.5rem;
  height: 1.5rem;
}
.navbar-menu-icon svg { display: block; width: 100%; height: 100%; }
/* The icon itself is the reference's exact Lottie asset (burger -> X, see
   site.js), not a CSS approximation. Lottie's SVG renderer draws literal
   fill="#000" on the paths; override it the same way the reference does —
   a plain descendant selector beats the presentation attribute.
   Unlike the logo, the icon also goes dark whenever the nav panel is open
   (regardless of section theme) since the panel itself is white and sits
   right behind it — matches the reference's separate on_hero.active rule. */
.navbar-menu-icon path {
  fill: #fff;
  transition: fill .6s cubic-bezier(.23, 1, .32, 1);
}
.navbar-menu-btn.has-light-backdrop .navbar-menu-icon path { fill: #171717; }
.navbar.nav-open .navbar-menu-icon path { fill: #171717; }

/* ---------- Sliding nav panel ---------- */
.navbar-nav-wrapper {
  position: fixed;
  inset: 0 0 0 auto;
  z-index: 776;
  height: 100dvh;
  min-width: 30rem;
  width: min(30rem, 100vw);
  background: #fff;
  color: var(--ink);
  transform: translateX(100%);
  transition: transform .8s var(--ease);
  pointer-events: none;
}
.navbar-nav-wrapper.open {
  transform: translateX(0);
  pointer-events: auto;
}
.navbar-nav-inner {
  height: 100%;
  padding: 3rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  overflow: auto;
}
/* gap: .5rem — corrected. Previously set to no gap at all on the theory
   that .navbar_nav/.navbar_nav_item/.navbar_nav_link set nothing — true,
   but incomplete: I'd missed a generic `li { margin-bottom: .5rem }` reset
   earlier in the same stylesheet that nothing overrides for this element
   (.navbar_nav_item is an <li> and never sets its own margin-bottom), so it
   wins by default, same cascade trap as the h1 font-weight issue. Margins
   don't collapse in a flex column, so that .5rem is real, visible spacing —
   using `gap` here instead of `margin-bottom` since the list is already a
   flex column. */
.navbar-nav-list { display: flex; flex-direction: column; gap: .5rem; }
/* font-weight: 400, not 500 — reference's .navbar_nav_link (an <a>, not a
   heading) never sets a weight, so it renders at the browser's normal
   default. Checked directly: no rule in the reference CSS touches its
   weight. */
.navbar-nav-link {
  position: relative;
  display: block;
  color: #2e2e2e;
  font-size: 2rem;
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: 0;
  text-decoration: none;
}
.navbar-nav-link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1px;
  width: 0%;
  background: #222;
  transition: width .4s var(--ease);
}
.navbar-nav-link:hover::after { width: 100%; }

/* Services dropdown — reference uses this as a real Webflow hover-dropdown
   (data-hover="true"), not a flat link. Replicated with plain CSS :hover
   since the effect (a white panel appearing below the trigger) doesn't need
   any JS to reproduce correctly. */
.navbar-nav-dd { position: relative; max-width: 100%; }
.navbar-nav-dd-btn {
  display: flex;
  gap: .5rem;
  justify-content: flex-start;
  align-items: center;
  color: #2e2e2e;
  font-size: 2rem;
  line-height: 1.2;
  letter-spacing: 0;
  cursor: pointer;
}
.navbar-nav-dd-icon { width: 2rem; transition: transform .4s var(--ease); }
.navbar-nav-dd:hover .navbar-nav-dd-icon { transform: rotate(180deg); }
.navbar-nav-dd-list {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .25rem;
  background: #fff;
  position: absolute;
  top: 100%;
  left: 0;
  padding: 1rem 1.25rem;
  box-shadow: .25rem .5rem 4rem rgba(0,0,0,.1), 0 1rem 1rem -.5rem rgba(0,0,0,.02);
  opacity: 0;
  pointer-events: none;
  transition: opacity .4s var(--ease);
  z-index: 1;
}
.navbar-nav-dd:hover .navbar-nav-dd-list { opacity: 1; pointer-events: auto; }
.navbar-nav-dd-link {
  position: relative;
  color: #2e2e2e;
  font-size: 1.25rem;
  line-height: 1.2;
  letter-spacing: .009375rem;
  white-space: nowrap;
  text-decoration: none;
  padding: .25rem 0;
}
.navbar-nav-dd-link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1px;
  width: 0%;
  background: #222;
  transition: width .4s var(--ease);
}
.navbar-nav-dd-link:hover::after { width: 100%; }

.navbar-cta { display: flex; flex-direction: column; gap: 2rem; }
/* font-weight: 400, not 500 — same reasoning as .navbar-nav-link: reference's
   .navbar_cta_title is a plain <div> with no weight rule anywhere. */
.navbar-cta-title { font-size: 1.5rem; font-weight: 400; line-height: 1.2; letter-spacing: 0; }
/* .25rem, not 8px (.5rem) — matches reference's .navbar_nav_btns gap. */
.navbar-cta-btns { display: flex; gap: .25rem; flex-wrap: wrap; }
/* These now use the same front/back flip-face structure as the hero
   buttons (see .btn/.btn-face), not a flat single-face button — reference's
   u-btn-black flips front (dark bg/white text) to back (white bg/dark
   text), same mechanism, different colors. */
.btn-black .btn-face-front { background: #222; color: #fff; }
.btn-black .btn-face-back { background: #fff; color: #222; }
.btn-icon { width: 1.25rem; }

.navbar-overlay {
  position: fixed;
  inset: 0;
  z-index: 775;
  background: rgba(0,0,0,.33);
  opacity: 0;
  pointer-events: none;
  transition: opacity .8s cubic-bezier(.23, 1, .32, 1);
}
.navbar-overlay.open { opacity: 1; pointer-events: auto; }

/* ---------- Google Calendar booking drawer ---------- */
.booking-modal { z-index: 1100; visibility: hidden; pointer-events: none; position: fixed; inset: 0; }
.booking-modal.is-open { visibility: visible; pointer-events: auto; }
.booking-backdrop { opacity: 0; background: rgba(0,0,0,.42); backdrop-filter: blur(4px); position: absolute; inset: 0; transition: opacity .6s var(--ease); }
.booking-modal.is-open .booking-backdrop { opacity: 1; }
.booking-panel { width: min(48rem, 100vw); height: 100dvh; margin-left: auto; padding: 2rem; background: #f7f7f7; position: relative; transform: translateX(100%); transition: transform .8s var(--ease); display: flex; flex-flow: column; }
.booking-modal.is-open .booking-panel { transform: translateX(0); }
.booking-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 2rem; margin-bottom: 1.5rem; }
.booking-eyebrow { color: #595959; margin-bottom: .5rem; font-size: .875rem; line-height: 140%; }
.booking-title { color: #2e2e2e; font-size: 2rem; font-weight: 400; line-height: 120%; }
.booking-close { flex: none; width: 3rem; height: 3rem; border: 1px solid #e7e7e7; position: relative; cursor: pointer; }
.booking-close span { width: 1.25rem; height: 2px; background: #2e2e2e; position: absolute; top: 50%; left: 50%; }
.booking-close span:first-child { transform: translate(-50%,-50%) rotate(45deg); }
.booking-close span:last-child { transform: translate(-50%,-50%) rotate(-45deg); }
.booking-frame-wrap { flex: 1; min-height: 0; overflow: hidden; background: #fff; }
.booking-frame-wrap iframe { display: block; border: 0; width: 100%; height: 100%; min-height: 600px; }

@media (max-width: 479px) {
  .navbar { top: 0; }
  .navbar-nav-wrapper {
    left: 0;
    width: 100%;
    min-width: 0;
  }
  .navbar-nav-inner {
    width: 100%;
    min-width: 0;
    padding: 4rem 1rem 1rem;
    gap: 4rem;
  }
  .navbar-nav-link,
  .navbar-nav-dd-btn {
    padding-top: .25rem;
    padding-bottom: .25rem;
  }
  .navbar-nav-dd-list {
    position: static;
    display: none;
    box-shadow: none;
    opacity: 1;
  }
  .navbar-nav-dd.open .navbar-nav-dd-list {
    display: flex;
    pointer-events: auto;
  }
  .navbar-nav-dd.open .navbar-nav-dd-icon { transform: rotate(180deg); }
  .navbar-cta { gap: 1rem; width: 100%; }
  .navbar-cta-btns {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }
  .navbar-cta-btns .btn { width: 100%; }
}

/* ---------- Hero ---------- */
.section-hero {
  position: relative;
  z-index: 1;
  width: 100vw;
  height: 200svh;
  margin-bottom: -100svh;
  background: var(--panel-dark);
  color: #fff;
}
.hero-media {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100svh;
  overflow: hidden;
}
/* Hero background is a rotating set of photos, not a single static one —
   standing in for the reference's looping showreel video. The motion itself
   comes from a pool of moves (direction, focal point, duration, easing —
   see HERO_MOVES in site.js), not a fixed per-photo animation: each photo
   gets assigned a different move from that pool every time it comes back
   around, so the same photo doesn't repeat the same zoom on its next turn.
   The keyframe here just reads whatever that move wrote into these custom
   properties right before .is-active was added. */
/* A simple concurrent opacity crossfade: outgoing and incoming both
   transition at the same time, over the same duration. That necessarily
   means a brief window where both are partially visible and blending —
   that's the crossfade look itself, not a defect. (A wipe or hard cut
   avoids the blend entirely, but that's a different aesthetic; this
   project intentionally uses a crossfade instead.) The Ken Burns zoom/pan
   below is separate — it animates `transform`, this animates `opacity`. */
.hero-media-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1);
  transition: opacity 1.5s ease-in-out;
}
.hero-media-img.is-active {
  opacity: 1;
  animation: hero-kb var(--kb-duration, 8000ms) var(--kb-ease, ease-in-out) forwards;
}
@keyframes hero-kb {
  from {
    transform:
      scale(var(--kb-scale-from, 1))
      translate(var(--kb-x-from, 0%), var(--kb-y-from, 0%));
  }
  to {
    transform:
      scale(var(--kb-scale-to, 1.1))
      translate(var(--kb-x-to, 0%), var(--kb-y-to, 0%));
  }
}

/* Exact reference gradient: fully transparent for the top third, darkening
   to only 50% black at the very bottom — much lighter than a guessed
   "heavy vignette" would be. */
.hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100svh;
  background: linear-gradient(rgba(0,0,0,0) 0%, rgba(0,0,0,0) 33%, rgba(0,0,0,.5) 100%);
}

.hero-inner {
  position: relative;
  z-index: 3;
  width: 100%;
  height: 100svh;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: flex-end;
  padding: 5rem var(--gutter);
  gap: 2rem;
}
.hero-pin-stage {
  position: sticky;
  top: 0;
  width: 100%;
  height: 100svh;
}
.hero-content {
  width: 28rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}
.hero-subheading {
  font-size: 1.125rem;
  font-weight: 500;
  letter-spacing: .009375rem;
  line-height: 1.4;
  text-shadow: .25rem .25rem 1rem rgba(0,0,0,.1);
}
/* font-weight: 400. Previously set to 700 here on the theory that nothing
   overrides the generic `h1,h2,h3,h4,h5,h6 { font-weight: bold }` reset —
   that was wrong: there's a *later* `h1 { font-weight: 400 }` rule further
   down the same stylesheet (Webflow's own typography defaults, not the
   browser normalize), same specificity, later in source order, so it wins
   the cascade. Checked by walking every top-level `h1` rule in the file in
   order — this is the last one and nothing after it touches font-weight. */
.hero-title {
  font-size: 3rem;
  font-weight: 400;
  letter-spacing: -.03125rem;
  line-height: 1.2;
  overflow: hidden;
}
.hero-title-desktop { display: block; }
.hero-title-mobile { display: none; }
.hero-title-line {
  display: block;
  white-space: nowrap;
  overflow: hidden;
}
.hero-title-line-inner { display: block; }
.hero-title .line { overflow: hidden; }

.hero-btns { display: flex; justify-content: flex-end; gap: .25rem; flex: 0 0 auto; }
/* The reference's flip is a vertical slide, not a 3D rotation: each face is
   its own full-size padded box with its own background/color; the back face
   rests exactly one box-height below (inset: 100% 0% 0%), invisible behind
   the wrapper's overflow:hidden, and on hover BOTH faces translateY(-100%)
   in lockstep — the old face slides out the top, the new one slides up into
   its place. The wrapper itself carries no background — only the faces do,
   which is also what fixes the text getting its own tight highlight-looking
   background: that happened because the color was on the bare text instead
   of a full padded face box. */
.btn {
  position: relative;
  display: inline-flex;
  overflow: hidden;
  border-radius: 0;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: .009375rem;
  line-height: 1.4;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
/* Exact Webflow IX2 values from the reference: both directions run for
   600ms with outQuint. The outgoing front intentionally ends at -101%, one
   percent beyond the back face's -100%, to prevent a fractional-pixel seam
   from remaining at the clipping edge and snapping away on completion. */
.btn-face {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .25rem;
  width: 100%;
  height: 100%;
  padding: 1rem 1.25rem;
  transition: transform .6s cubic-bezier(.23, 1, .32, 1);
}
.btn-face-front { transform: translateY(0%); }
.btn-face-back {
  position: absolute;
  inset: 100% 0% 0%;
  transform: translateY(0%);
}
.btn:hover .btn-face-front { transform: translateY(-101%); }
.btn:hover .btn-face-back { transform: translateY(-100%); }

/* Primary ("Start project"): white front, slides to a solid dark face on
   hover — matches the reference's u-btn-white front/back pairing exactly
   (front #fff/#222, back #2a2a2a/#fff), not a lightened/darkened tint of
   the same color. */
.btn-primary .btn-face-front { background: #fff; color: var(--ink); }
.btn-primary .btn-face-back { background: #2a2a2a; color: #fff; }
/* Secondary ("Portfolio"): frosted glass front, slides to solid white on
   hover. The reference puts the same glass treatment on both the stationary
   outer shell and the moving front face, keeping the blur continuous while
   the front clears the clipping edge. */
.btn-secondary {
  background: rgba(255,255,255,.15);
  -webkit-backdrop-filter: blur(1rem);
  backdrop-filter: blur(1rem);
}
.btn-secondary .btn-face-front {
  background: rgba(255,255,255,.15);
  -webkit-backdrop-filter: blur(1rem);
  backdrop-filter: blur(1rem);
  color: #fff;
}
.btn-secondary .btn-face-back { background: #fff; color: var(--ink); }

/* ---------- Featured Projects (mosaic) ---------- */
/* position:relative + z-index:2, exactly matching reference's own
   .section_portfolio — required, not decorative: the hero is pinned via
   ScrollTrigger (see setupHeroPin), which puts it on position:fixed while
   pinned. Any plain in-flow (position:static) content — which this section
   was before this fix — always paints *below* fixed-position content in
   the stacking order regardless of DOM order, so the hero stayed visually
   on top the whole time no matter how far you scrolled past it. Giving
   this section its own stacking context with a higher z-index than the
   hero's is what lets it actually scroll up and visually cover the pinned
   hero as you scroll — the reveal effect that wasn't happening before. */
.section-portfolio { position: relative; z-index: 2; background: #f7f7f7; }
.portfolio-wrapper {
  display: flex;
  flex-flow: column;
  align-items: center;
  gap: 8rem;
  /* 120rem/.25rem side padding, not 90rem/var(--gutter) — matches
     reference's actual two nested containers (.w-layout-blockcontainer
     .u-container-wide, max-width:120rem + .25rem side padding; and
     .portfolio_wrapper itself, padding-top:8rem/padding-bottom:.25rem)
     collapsed into this one element. */
  max-width: 120rem;
  margin: 0 auto;
  padding: 8rem .25rem .25rem;
}
/* font-weight: 400, not 700 — this is an <h2>, not an <h1>. Same cascade
   pattern as .hero-title: nothing in .u-h1 sets a weight, so it falls
   through to Webflow's own typography defaults further down the same
   stylesheet — which for h2 specifically (not h1) set font-weight: 400,
   confirmed by reading that rule directly rather than assuming it matches
   h1's. Different tag, different fallback weight. */
.portfolio-heading {
  font-size: 4rem;
  font-weight: 400;
  letter-spacing: -.09375rem;
  line-height: 1.1;
  text-align: center;
}
.portfolio-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: .25rem;
  width: 100%;
}
.portfolio-project {
  position: relative;
  display: block;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  color: #fff;
  text-decoration: none;
}
.portfolio-project--big { grid-column: span 6; aspect-ratio: 3 / 2; }
.portfolio-project--small { grid-column: span 4; aspect-ratio: 3 / 4; }
/* No zoom on the image — checked directly against the reference, there's
   no hover transform on .portfolio_project_img at all. Only the dark
   overlay and the text label respond to hover. */
.portfolio-project-img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.portfolio-project-overlay {
  z-index: 3;
  position: absolute;
  inset: 0;
  background: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity .6s cubic-bezier(.23, 1, .32, 1);
}
.portfolio-project:hover .portfolio-project-overlay { opacity: .33; }
/* Text label hides by default and reveals on hover — this was showing all
   the time before, which is wrong: the reference keeps the mosaic clean by
   default and only surfaces the title/location on hover. */
.portfolio-project-info {
  z-index: 4;
  position: absolute;
  left: 1rem;
  right: 1rem;
  bottom: 1rem;
  font-size: 1.125rem;
  line-height: 1.4;
  letter-spacing: .009375rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  overflow: hidden;
}
.portfolio-project-content {
  display: contents;
}
.project-btn { position: relative; overflow: hidden; }
.portfolio-project-title {
  font-size: 1.125rem;
  font-weight: 500;
  line-height: 1.4;
}
.portfolio-project-title,
.portfolio-project-text {
  transform: translateY(100%);
  transition: transform .6s cubic-bezier(.23, 1, .32, 1);
}
.portfolio-project:hover .portfolio-project-title,
.portfolio-project:hover .portfolio-project-text {
  transform: translateY(0%);
}
.project-btn-underline {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 0%;
  background: #fff;
  transition: width .4s cubic-bezier(.77, 0, .175, 1);
}
.project-btn:hover .project-btn-underline {
  width: 100%;
  transition-timing-function: cubic-bezier(.165, .84, .44, 1);
}
.portfolio-card {
  grid-column: span 6;
  aspect-ratio: 3 / 2;
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: center;
  gap: 3rem;
  padding: 10rem;
  background: #222;
  color: #fff;
  text-align: center;
  text-decoration: none;
  transition: background-color .6s var(--ease);
}
.portfolio-card:hover { background: #1a1a1a; }
.portfolio-card:active { background: #2a2a2a; }
.portfolio-card-text { font-size: 1.5rem; line-height: 1.2; }

/* ---------- Services: reference 14-face cylindrical carousel ---------- */
.section-services { background: #f7f7f7; color: #2e2e2e; overflow: hidden; }
.services-container { width: 100%; padding-inline: var(--gutter); }
.services-wrapper {
  display: flex; flex-flow: column; align-items: center;
  padding-top: 8rem; position: relative;
}
.services-heading {
  width: 42rem; margin-bottom: 8rem; text-align: center;
  font-family: "Helvetica Now", Arial, sans-serif;
  font-size: 3rem; font-weight: 400; line-height: 120%; letter-spacing: -.03125rem;
}
.services-carousel-wrapper {
  --services-total: 14; --services-item-width: 29.6875rem;
  --services-inner-angle: calc((360 / var(--services-total)) * 1deg);
  --services-radius: calc((var(--services-item-width) / sin(var(--services-inner-angle))) * -1);
  width: 100%; perspective-origin: 50%; transform-origin: 50%; position: relative;
}
.services-carousel-container {
  z-index: 1; perspective: 5000px; display: flex;
  justify-content: center; align-items: center; position: relative;
}
.services-carousel {
  width: var(--services-item-width); height: var(--services-item-width);
  margin: 0; padding: 0; list-style: none; position: relative;
  transform-style: preserve-3d;
  transform: translate3d(0, 0, var(--services-radius)) rotateY(-102deg);
}
.services-carousel-card {
  aspect-ratio: 1; backface-visibility: hidden;
  width: var(--services-item-width); height: var(--services-item-width);
  position: absolute; inset: 0; overflow: hidden;
  transform: rotateY(calc(var(--services-inner-angle) * var(--carousel-index))) translate3d(0, 0, calc(var(--services-radius) * -1));
}
.services-carousel-card[data-carousel-index="1"] { --carousel-index: 1; }
.services-carousel-card[data-carousel-index="2"] { --carousel-index: 2; }
.services-carousel-card[data-carousel-index="3"] { --carousel-index: 3; }
.services-carousel-card[data-carousel-index="4"] { --carousel-index: 4; }
.services-carousel-card[data-carousel-index="5"] { --carousel-index: 5; }
.services-carousel-card[data-carousel-index="6"] { --carousel-index: 6; }
.services-carousel-card[data-carousel-index="7"] { --carousel-index: 7; }
.services-carousel-card[data-carousel-index="8"] { --carousel-index: 8; }
.services-carousel-card[data-carousel-index="9"] { --carousel-index: 9; }
.services-carousel-card[data-carousel-index="10"] { --carousel-index: 10; }
.services-carousel-card[data-carousel-index="11"] { --carousel-index: 11; }
.services-carousel-card[data-carousel-index="12"] { --carousel-index: 12; }
.services-carousel-card[data-carousel-index="13"] { --carousel-index: 13; }
.services-carousel-card[data-carousel-index="14"] { --carousel-index: 14; }
.services-card {
  width: 100%; height: 100%; padding: 1.5rem; color: #fff; text-decoration: none;
  display: flex; gap: 1.5rem; justify-content: space-between; align-items: flex-end;
}
.services-carousel-card-img {
  z-index: 1; object-fit: cover; width: calc(100% + 200px); max-width: none;
  height: calc(100% + 200px); position: absolute; inset: -100px auto auto -100px;
  will-change: transform;
}
.services-card-title { z-index: 4; width: fit-content; max-width: 100%; position: relative; font-size: 2rem; font-weight: 500; line-height: 120%; }
.services-card-title::after { content: ""; display: block; width: 0; height: 2px; position: absolute; left: 0; bottom: -.12em; background: #fff; transition: width .4s cubic-bezier(.77,0,.175,1); }
.services-card-gradient { z-index: 2; background: linear-gradient(#0000 66%, #00000054); position: absolute; inset: 0; }
.services-card-overlay { z-index: 3; opacity: 0; background: #00000040; position: absolute; inset: 0; transition: opacity .6s var(--ease); }
.services-card:hover .services-card-overlay { opacity: 1; }
.services-card:hover .services-card-title::after { width: 100%; }

/* ---------- About / footprint ---------- */
.section-about { background: #f7f7f7; color: #2e2e2e; }
.about-container {
  width: 100%; max-width: 120rem; height: 100%;
  margin-inline: auto; padding-inline: 5rem;
}
.about-wrapper {
  display: flex; flex-flow: column; gap: 5rem;
  padding-top: 8rem; padding-bottom: 8rem;
}
.about-heading {
  width: 100%; max-width: 53rem;
  font-family: "Helvetica Now", Arial, sans-serif;
  font-size: 3rem; font-weight: 400; line-height: 120%; letter-spacing: -.03125rem;
}
.about-nums { display: flex; gap: 2rem; width: 100%; }
.about-num { display: flex; flex: 1; flex-flow: column; gap: .5rem; }
.about-num-title { font-size: 2rem; font-weight: 400; line-height: 120%; }
.about-num-text { color: #595959; font-size: 1.25rem; line-height: 140%; letter-spacing: .009375rem; }
.about-nums-divider { width: 1px; background: #e7e7e7; }

/* ---------- Advantages: pinned accordion ---------- */
.section-advantages { height: 200svh; background: #f7f7f7; color: #2e2e2e; }
.advantages-container { width: 100%; max-width: 120rem; height: 100%; margin-inline: auto; padding-inline: .25rem; }
.advantages-wrapper { display: flex; gap: .25rem; width: 100%; height: 100svh; padding-block: .25rem; }
.advantages-content {
  display: flex; flex-flow: column; justify-content: space-between;
  width: 100%; height: 100%; padding: 4rem 4rem 2.5rem; background: #fff;
}
.advantages-heading { font-size: 3rem; font-weight: 400; line-height: 120%; letter-spacing: -.03125rem; }
.advantages-list-wrapper { display: flex; justify-content: flex-start; align-items: flex-end; height: 100%; overflow: hidden; }
.advantages-list { display: flex; flex-flow: column; width: 100%; margin: 0; padding: 0; list-style: none; position: relative; }
.advantage {
  display: flex; flex-flow: column; gap: 1rem; cursor: pointer;
  margin: 0; padding-top: 1rem; position: relative;
  background: #fff; border-top: 1px solid #f7f7f7;
}
.advantage-header { display: flex; align-items: center; gap: 1.5rem; }
.advantage-num { border: 1px solid #efefef; padding: .875rem; position: relative; }
.advantage-num-title { z-index: 2; position: relative; }
.advantage-num-bg { z-index: 1; position: absolute; inset: 0; background: #f7f7f7; }
.advantage-heading { flex: 1; font-size: 1.5rem; font-weight: 400; line-height: 120%; }
.advantage-body { color: #595959; letter-spacing: .009375rem; padding-left: 4.5rem; font-size: 1rem; line-height: 140%; overflow: hidden; }
.advantage-body-text { margin: 0; padding-bottom: 1rem; }
.advantage-divider { width: 0; height: 1px; position: absolute; top: -1px; left: 0; background: #222; }
.advantages-img-wrapper { object-fit: cover; flex: none; width: calc(50% - .125rem); position: relative; overflow: hidden; }
.advantage-img { object-fit: cover; width: 100%; height: 100%; position: absolute; inset: 0; }

/* ---------- Closing CTA ---------- */
.section-cta { width: 100vw; height: 150svh; position: relative; overflow: hidden; }
.cta-container { z-index: 3; width: 100%; max-width: 120rem; height: 100%; margin-inline: auto; padding-inline: 5rem; position: relative; }
.cta-wrapper {
  display: flex; flex-flow: column; justify-content: flex-end; align-items: flex-start;
  gap: 3rem; width: 24rem; height: 100%; padding-block: 5rem;
}
.cta-heading { color: #fff; font-size: 4rem; font-weight: 400; line-height: 110%; letter-spacing: -.09375rem; }
.cta-btns { display: flex; align-items: center; gap: .25rem; }
.cta-btn .btn-face { display: flex; align-items: center; gap: .5rem; }
.cta-btn-arrow { font-size: 1.25rem; line-height: 1; }
.cta-image-overlay { z-index: 2; pointer-events: none; background: linear-gradient(180deg, rgba(0,0,0,.14) 0%, rgba(0,0,0,.22) 50%, rgba(0,0,0,.58) 100%); position: absolute; inset: 0; }
.cta-bg { z-index: 1; object-fit: cover; width: 100%; max-width: none; height: 105%; position: absolute; inset: -2.5% 0; }

/* ---------- Footer ---------- */
.section-footer { padding: 0 .25rem .25rem; background: #222; }
.footer-container { width: 100%; max-width: 120rem; margin-inline: auto; }
.footer-wrapper { padding: 4.75rem 4.75rem 0; background: #222; color: #fff; }
.footer-cols { display: grid; grid-template-columns: minmax(15rem, 1fr) 2fr; gap: 4rem; margin-bottom: 3rem; }
.footer-cta { display: flex; flex-flow: column; align-items: flex-start; gap: 2rem; padding-right: 1.75rem; }
.footer-heading { color: #fff; font-size: 2rem; font-weight: 500; line-height: 120%; }
.footer-cols-wrapper { display: flex; gap: 2rem; }
.footer-col { flex: 1; min-width: 0; }
.footer-col-title { color: #898989; letter-spacing: .009375rem; margin-bottom: 1.5rem; font-size: .875rem; line-height: 140%; }
.footer-col-list { display: flex; flex-flow: column; align-items: flex-start; gap: .25rem; margin: 0; padding: 0; list-style: none; }
.footer-col-list li { margin: 0; }
.footer-link, .footer-address { color: #fff; letter-spacing: .009375rem; padding-block: .25rem; font-size: 1rem; line-height: 140%; text-decoration: none; }
.footer-contact-name { color: #fff; font-size: 1rem; line-height: 140%; }
.footer-contact-role { color: #898989; margin-bottom: .5rem; font-size: .875rem; line-height: 140%; }
.footer-link, .footer-address { position: relative; display: inline-block; }
.footer-link::after, .footer-address::after, .footer-bottom-link::after { content: ""; width: 0; height: 1px; background: currentColor; position: absolute; left: 0; bottom: 0; transition: width .4s var(--ease); }
.footer-link:hover::after, .footer-address:hover::after, .footer-bottom-link:hover::after { width: 100%; }
.footer-socials { display: flex; gap: .25rem; margin: 0; padding: 0; list-style: none; }
.footer-socials li { margin: 0; }
.footer-socials a { display: flex; justify-content: center; align-items: center; width: 3rem; height: 3rem; color: #dfdfdf; background: #2a2a2a; text-decoration: none; transition: background-color .4s var(--ease); }
.footer-socials a:hover { color: #fff; background: #323232; }
.footer-bottom { display: flex; justify-content: space-between; align-items: center; padding-block: 2rem; border-top: 1px solid #2a2a2a; color: #dfdfdf; font-size: .75rem; line-height: 140%; }
.footer-bottom-link { color: #dfdfdf; text-decoration: none; position: relative; }
[data-section-split] .section-split-line { overflow: hidden; }

@media (max-width: 900px) {
  .hero-inner {
    flex-direction: column;
    justify-content: flex-end;
    align-items: flex-start;
    gap: 2rem;
    padding-top: 2rem;
    padding-bottom: 1rem;
  }
  .hero-content { width: auto; }
  .hero-btns { justify-content: flex-start; }
  .portfolio-heading { font-size: 2.5rem; }
  .portfolio-project--big,
  .portfolio-project--small,
  .portfolio-card { grid-column: span 12; aspect-ratio: 3 / 2; }
  .portfolio-card { gap: 2rem; padding: 2rem; }
  .about-container { padding-inline: 2rem; }
  .about-wrapper { gap: 4rem; padding-block: 6rem; }
  .advantages-content { padding: 2rem 2rem 1rem; }
  .cta-container { padding-inline: 2rem; }
  .footer-wrapper { padding: 1.75rem 1.75rem 0; }
  .footer-cols { grid-template-columns: 1fr; gap: 4rem; }
  .footer-cta { width: 50%; padding-right: 0; }
}

@media (max-width: 720px) {
  :root { --gutter: 20px; --nav-gutter: 16px; }
  .hero-inner {
    gap: 2rem;
    padding-top: 1rem;
    padding-bottom: 1rem;
  }
  .hero-content { gap: 1rem; }
  .hero-subheading { font-size: 1rem; }
  .hero-title {
    width: 100%;
    font-size: min(2.25rem, calc((100vw - 40px) / 18));
  }
  .hero-title-desktop { display: none; }
  .hero-title-mobile { display: block; }
  .portfolio-card { padding: 4rem; }
}

@media (max-width: 767px) {
  .services-container { padding-inline: .25rem; }
  .services-wrapper { padding-top: 4rem; }
  .services-heading { width: calc(100% - 2rem); margin-bottom: 4rem; font-size: 2.25rem; }
  .services-carousel-wrapper { height: auto !important; }
  .services-carousel-container { perspective: none; }
  .services-carousel { display: flex; flex-flow: column; gap: .25rem; width: 100%; height: auto; transform: none !important; }
  .services-carousel-card { width: auto; height: auto; position: static; transform: none; }
  .services-carousel-card:not([data-service-empty]) { aspect-ratio: 1; }
  .services-carousel-card[data-service-empty] { display: none; }
  .services-card { position: relative; }
  .services-carousel-card-img { width: 100%; height: 100%; inset: 0; transform: none !important; }
  .about-container { padding-inline: 1rem; }
  .about-wrapper { gap: 4rem; padding-block: 4rem; }
  .about-heading { max-width: none; font-size: 2.25rem; }
  .about-nums { gap: 1rem; }
  .about-num-text { font-size: 1rem; }
  .advantages-img-wrapper { display: none; }
  .advantages-content { gap: 2rem; }
  .cta-container { padding-inline: 1rem; }
  .cta-heading { font-size: 2.25rem; letter-spacing: -.03125rem; line-height: 120%; }
  .cta-btns { flex-flow: column; align-items: stretch; }
  .footer-cta { width: 100%; }
  .footer-cols-wrapper { flex-wrap: wrap; }
  .footer-col { flex: 0 0 calc(50% - 1rem); }
  .footer-col-title { margin-bottom: .5rem; }
  .footer-col-list { gap: 0; }
}

/* Keep the reference's phone-specific sidebar geometry after the broader
   tablet rules above so tablet padding cannot override it in the cascade. */
@media (max-width: 479px) {
  .hero-inner { gap: 1rem; }
  .hero-content { gap: .5rem; }
  .hero-title {
    font-size: min(1.75rem, calc((100vw - 40px) / 18));
    letter-spacing: 0;
  }
  .navbar-nav-inner { padding: 4rem 1rem 1rem; }
  .portfolio-card { padding: 2rem; }
  .about-nums { flex-wrap: wrap; }
  .about-num { flex: 0 auto; width: calc(50% - .5rem); }
  .about-nums-divider { display: none; }
  .section-advantages { height: auto; }
  .advantages-wrapper { height: auto; }
  .advantage-header { gap: 1rem; }
  .advantage-num { padding: .75rem; }
  .advantage-num-title { font-size: .75rem; }
  .advantage-heading { font-size: 1rem; }
  .advantage-body { height: auto !important; padding-left: 3.375rem; }
  .advantage-body-text { font-size: .875rem; }
  .cta-wrapper { width: 100%; padding-block: 2rem; }
  .footer-wrapper { padding: 1.5rem 1rem 0; }
  .footer-cols-wrapper { flex-flow: column; }
  .footer-col { width: 100%; flex-basis: auto; }
  .footer-bottom { align-items: flex-start; gap: 1rem; }
  .booking-panel { width: 100%; padding: 1rem; }
  .booking-header { margin-bottom: 1rem; }
  .booking-title { font-size: 1.5rem; }
}
