/* ==========================================================================
   MERAKI - typography2c68.css
   --------------------------------------------------------------------------
   Loaded LAST on every page (after global + page stylesheets) so it wins on
   source order at equal specificity.

   WHY THIS FILE EXISTS
   --------------------
   The design system builds every font size from `--scale-text-rem`, which is
   pinned to `1rem` = 10px (html is `font-size:62.5%`). That made all micro
   copy render at 10px / 11px and small copy at 14px - measured on the real
   pages with headless Chrome:
       labels (.text-c1) ......... 10px      footer (.text-c2-small) ... 8-10px
       header buttons ............ 10-11px   thumb labels / chips ...... 10px
       card prices (flats.html) .. 10px      small copy (.text-small) .. 14px
   Some semantic headings even carried a small-text utility class
   (`<h2 class="text-c1">`), so section titles rendered at 10px.

   WHAT IT DOES
   ------------
   1. Raises the base text unit (13.5px instead of 10px)  -> every size that is
      derived from `--scale-text-rem` grows, including page-specific component
      styles we do not enumerate here.
   2. Re-pins the larger roles (body, headings, display type) to explicit
      clamped values so the boost cannot oversize them or break layouts.
   3. Normalises alignment / placement of the section captions, fixes the
      measured collisions + overflow, and gives every caption a readable
      measure and consistent gutters.
   4. Provides the styling half of the text animation layer
      (assets/javascripts/text-anim2c68.js).
   ========================================================================== */

/* ==========================================================================
   1. GLOBAL TEXT SCALE
   `--scale-text-rem` is used for `font-size` ONLY across every stylesheet
   (verified), so raising it is safe for layout.
   ========================================================================== */

:root {
  /* was 1rem (10px) -> 1.35rem (13.5px): +35% on all derived micro copy */
  --scale-text-rem: 1.35rem;
}

/* Older browsers without `clamp()` fall back to these two steps. */
:root {
  --tx-body: 20px;
  --tx-small: 16px;
  --tx-micro: 14px;
  --tx-h3: 34px;
  --tx-h2: 44px;
  --tx-h1: 52px;
  --tx-display: 88px;
  --tx-giant: 150px;
  --tx-measure: 52ch;
  --tx-gutter: clamp(20px, 4.2vw, 80px);
  --tx-ease: cubic-bezier(0.25, 0.74, 0.22, 0.99);
  /* Top clearance for the FIXED landing header. Measured in headless Chrome at
     1440x900: `.header__content` is 97.4px tall (27.7px padding-top + 50px logo
     + 6.9px padding-bottom + the logo's -8px optical offset), and it is
     `position:fixed; top:0` so it floats over the hero. Reserving this strip at
     the top of the hero caption means the navbar can never sit on the text
     again, whatever the viewport. */
  --tx-header-clearance: clamp(92px, 7.4vw, 128px);
}

@supports (font-size: clamp(1px, 1px, 2px)) {
  :root {
    --tx-body: clamp(17px, 1.1vw, 21px);
    --tx-small: clamp(15px, 0.95vw, 17px);
    --tx-micro: clamp(13px, 0.84vw, 15px);
    --tx-h3: clamp(28px, 2.2vw, 38px);
    --tx-h2: clamp(32px, 2.9vw, 50px);
    --tx-h1: clamp(34px, 3.3vw, 56px);
    --tx-display: clamp(46px, 6.4vw, 96px);
    --tx-giant: clamp(58px, 10.5vw, 172px);
  }
}

/* ==========================================================================
   2. ROLE PINS
   ========================================================================== */

/* --- body copy ---------------------------------------------------------- */
body,
.text-t1,
.text-t2-t1,
.text,
p,
li,
blockquote,
dd,
dt {
  font-size: var(--tx-body);
  line-height: 1.5;
}

/* `p` inside components often inherits a 10px parent; give paragraphs a floor
   without touching the components' own layout. */
p.leading-trim,
p:not([class]) {
  font-size: var(--tx-body);
}

.text-small,
.text-color-small + .text-small {
  font-size: var(--tx-small);
  line-height: 1.45;
}

.text-lead {
  font-size: clamp(19px, 1.5vw, 27px);
  line-height: 1.35;
}

/* --- micro copy: labels, eyebrows, chips, footer ------------------------ */
.text-c1,
.text-c2,
.text-c2-c1 {
  font-size: var(--tx-micro);
  line-height: 1.35;
  letter-spacing: 0.02em;
}

.text-c2-small,
.text-smaller,
.text-small.text-color-small {
  font-size: clamp(12.5px, 0.8vw, 14px);
  line-height: 1.4;
}

.text-c2,
.cookie-consent__description__text {
  font-size: clamp(13px, 0.85vw, 15px);
  line-height: 1.5;
}

/* --- interactive text --------------------------------------------------- */
.btn,
.btn__text,
.btn--text-small,
.btn__text.btn--text-small,
button,
input,
textarea,
select {
  font-size: clamp(12.5px, 0.82vw, 14.5px);
}

.carousel__thumb__item__text,
.js-label-text,
.form-label,
.breadcrumbs__item__text,
.carousel__thumb__item,
.form-control-range__label {
  font-size: clamp(12px, 0.78vw, 13.5px);
  line-height: 1.3;
}

nav a,
.header__link,
.menu__list a {
  font-size: clamp(13px, 0.86vw, 15px);
}

/* --- headings ----------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 {
  line-height: 1.12;
  text-wrap: balance;
}

.h3, h3 {
  font-size: var(--tx-h3);
}
.h2, h2 {
  font-size: var(--tx-h2);
}
.h1, h1 {
  font-size: var(--tx-h1);
}
.h0, .h0-sm, .text-h0, .text-h0-lg, .text-h3-stc {
  font-size: var(--tx-display);
  line-height: 1.02;
}
.g1 {
  font-size: var(--tx-giant);
  line-height: 0.95;
}
.g0 {
  font-size: clamp(60px, 12vw, 200px);
  line-height: 0.92;
}

/* Headings that (wrongly) carried a small-text utility - e.g.
   <h2 class="pt-2 px-layout text-c1 leading-trim text-center">
   on about.html rendered at 10px. Give them a real heading size. */
h1.text-c1, h2.text-c1, h3.text-c1, h4.text-c1,
h1.text-c2, h2.text-c2, h3.text-c2,
h1.text-c2-small, h2.text-c2-small, h3.text-c2-small,
h1.text-small, h2.text-small, h3.text-small,
h1.text-smaller, h2.text-smaller,
h4.text-c2, h5.text-c1, h6.text-c1 {
  font-size: clamp(20px, 1.9vw, 32px);
  line-height: 1.15;
  letter-spacing: 0;
}

/* Display headings must never collide with the fixed header. */
.a-intro .h0,
.a-intro__content > .h0,
.l-gallery__title h1,
.l-gallery__title .h0 {
  padding-top: 0.12em;
}

/* ==========================================================================
   3. MEASURE + RHYTHM  (readable line length, calmer stacks)
   ========================================================================== */

body {
  text-rendering: optimizeLegibility;
}

/* Long-form paragraphs: cap the measure so lines do not run edge to edge. */
.l-intro__content-text,
.l-nature-bg-caption__text,
.l-nature__caption__text,
.a-place__caption__description,
.l-residences__caption__description,
.l-design__caption__text,
.l-callback__limited-width,
.de-description,
.lo-slider__head p {
  max-width: min(100%, var(--tx-measure));
}

/* Captions should hug their own block, not float mid-canvas. */
.l-gallery__caption,
.l-nature-bg-caption,
.l-place-webgl-caption {
  row-gap: 0.4rem;
}

/* Labels that sit directly above a heading: keep the pair tight. */
[class*="__subtitle"].text-c1,
[class*="__subtitle"].text-c2,
.l-design__caption__subtitle,
.l-place-webgl-caption__subtitle,
.l-nature-bg-caption__subtitle,
.l-intro__opening-subtitle,
.a-intro__subtitle p {
  margin-bottom: 0.45em;
  letter-spacing: 0.06em;
}

.l-intro__opening-subtitle {
  font-size: var(--md, calc(var(--scale-text-rem) * 1.8))
    var(--n-md, calc(var(--scale-text-rem) * 1.45));
  font-weight: 500;
}

.l-intro__content-title {
  flex: 0 1 auto;
  margin-left: auto;
  margin-right: auto;
  max-width: 760px;
  padding-left: 0;
  padding-right: 0;
  text-align: center;
  width: calc(100% - (var(--spacing-layout) * 2));
}

.l-intro__content-text {
  margin-left: auto;
  margin-right: auto;
  max-width: 620px;
  padding-left: var(--spacing-layout);
  padding-right: var(--spacing-layout);
  text-align: center;
  width: calc(100% - (var(--spacing-layout) * 2));
}

/* ==========================================================================
   4. PLACEMENT - LANDING HERO
   The base stylesheet lays this caption out as a 12-column grid: the eyebrow
   is a 25vw column (`.col--md-3`) pushed right by `.offset--md-2` (16.66vw),
   and the headline is a 50vw column (`.col--md-6`) carrying `.text-right`.
   The two lines therefore sat on two different axes, which is what made the
   middle of the hero read as "off centre" at every width.

   These rules neutralise that column sizing/offset (same specificity, and this
   file loads after landing2c68.css so it wins) and let the caption's own flex
   column centre one single stack - eyebrow, then "Book your site visit." -
   on the viewport axis, both horizontally and vertically.
   ========================================================================== */

.l-gallery__caption {
  /* >>> THE ACTUAL COLLISION <<<
     landing2c68.css only sets `display:flex` on this element inside the phone /
     portrait media query:

       @media (max-width:567px) and (max-aspect-ratio:13/9),
              (max-width:667px) and (min-aspect-ratio:13/9),
              (max-width:979px) and (max-height:415px) and (min-aspect-ratio:13/9) {
         .l-gallery__caption{display:flex;flex-direction:column;justify-content:center}
       }

     Everywhere else - i.e. on every desktop / tablet - the caption stayed
     `display:block`, so `align-items`/`justify-content` were dead declarations
     and the two children simply stacked from the TOP EDGE of the box. That put
     the eyebrow paragraph at y=0 and the headline at y=44px, i.e. directly
     under the fixed navbar (97.4px tall - measured), which is the overlap that
     was reported. Declaring the flex column here, unconditionally, makes the
     centring real on every breakpoint instead of only on phones. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  /* Symmetric padding keeps the stack truly centred instead of being shifted
     off axis by the base `.pr-layout` right padding. */
  padding-left: max(var(--tx-gutter), env(safe-area-inset-left));
  padding-right: max(var(--tx-gutter), env(safe-area-inset-right));
  /* Fixed-navbar clearance: the flex centring below happens inside what is left
     of the box, so the stack is centred in the *visible* area instead of under
     the header. */
  padding-top: var(--tx-header-clearance);
  padding-bottom: 0;
  row-gap: 0.6rem;
}

/* Belt and braces: the base height is `calc(100 * var(--svh))`, which collapses
   to `auto` if the JS that defines `--svh` has not run yet. `min-height` keeps
   the vertical centring axis in place either way. */
@supports (height: 100svh) {
  .l-gallery__caption {
    min-height: 100svh;
  }
}

/* Strip the grid column sizing/offset from EVERY direct child so the flex
   column decides placement. Beats `.col--md-3`, `.col--md-6`, `.col--xxxl-2`,
   `.offset--md-2`, `.pl-layout`, `.pl-0:md` and `.pt-7:md`. */
.l-gallery__caption > .col,
.l-gallery__caption > .l-gallery__title {
  flex: 0 0 auto;
  width: 100%;
  margin-left: auto;
  margin-right: auto;
  padding-left: 0;
  padding-right: 0;
  padding-top: 0;
  text-align: center;
}

/* eyebrow line ("Exclusive villa plots in a gated township ...")
   Capped by a comfortable reading measure instead of by 25vw. */
.l-gallery__caption > .col {
  max-width: min(100%, 46ch);
}

/* "Book your site visit."
   The base capped this block at min(100%, 24ch), which squeezed the display
   type into a ~240px box. The line break is explicit in the markup
   (<br />), so the block only has to be wide enough for its own text. */
.l-gallery__caption > .l-gallery__title {
  position: static;
  top: auto;
  right: auto;
  bottom: auto;
  left: auto;
  max-width: 100%;
}

.l-gallery__caption .l-gallery__title h1,
.l-gallery__caption .l-gallery__title .h0,
.l-gallery__caption .l-gallery__title .h1 {
  text-align: center;
}

/* scroll-down control: centred under the title instead of bottom-left */
.l-gallery-next {
  left: 0;
  right: 0;
  top: auto;
  bottom: var(--tx-gutter);
  margin-left: auto;
  margin-right: auto;
  width: var(--btn-height);
}

/* ==========================================================================
   5. PLACEMENT - SECTION CAPTIONS, GUTTERS, HEADER, FOOTER
   ========================================================================== */

/* Captions keep the same gutter as the rest of the page so their text edge
   lines up with headings and images on every breakpoint. */
.l-gallery__caption,
.l-nature-bg-caption__text,
.l-place-description__title,
.footer__content {
  padding-left: max(var(--tx-gutter), env(safe-area-inset-left));
  padding-right: max(var(--tx-gutter), env(safe-area-inset-right));
}

.l-nature-bg-caption__text {
  max-width: min(100%, var(--tx-measure));
  bottom: calc(var(--tx-gutter) + (100vh - 100dvh));
}

.l-place-webgl-caption__subtitle,
.l-design__caption__subtitle {
  opacity: 0.92;
}

/* Header: comfortable hit areas and a legible nav. */
.header__content {
  padding-left: max(var(--tx-gutter), env(safe-area-inset-left));
  padding-right: max(var(--tx-gutter), env(safe-area-inset-right));
}
.header .btn__text,
.header__logo + .btn .btn__text {
  letter-spacing: 0.08em;
}

/* Footer: legal copy is no longer 8-10px and lines up on a shared left edge. */
.footer .text-c2-small,
.footer .text-color-small,
.footer p,
.footer a,
.footer span {
  font-size: clamp(12.5px, 0.82vw, 14.5px);
  line-height: 1.55;
}
.footer__content {
  row-gap: 0.75rem;
}

/* ==========================================================================
   6. TEXT ANIMATION LAYER
   Styling half of assets/javascripts/text-anim2c68.js.
   Nothing is hidden unless the script first marks the element with
   `data-tx-armed`, so a JS failure can never leave text invisible.
   Opt out per element with `data-tx="none"`, opt out globally with
   `data-tx-disable` on <html> or <body>.
   ========================================================================== */

[data-tx-armed] {
  will-change: opacity, transform, clip-path;
}

[data-tx-armed="reveal-up"]:not([data-tx-done]) {
  opacity: 0;
  transform: translateY(1.2em);
}
[data-tx-armed="reveal"]:not([data-tx-done]) {
  opacity: 0;
}
[data-tx-armed="mask"]:not([data-tx-done]) {
  clip-path: inset(0 0 105% 0);
  -webkit-clip-path: inset(0 0 105% 0);
}

[data-tx-done] {
  opacity: 1;
  transform: none;
  clip-path: none;
  -webkit-clip-path: none;
}

[data-tx-done="reveal"],
[data-tx-done="reveal-up"] {
  transition: opacity 0.9s var(--tx-ease), transform 1.05s var(--tx-ease);
}
[data-tx-done="mask"] {
  transition: clip-path 1.05s var(--tx-ease), -webkit-clip-path 1.05s var(--tx-ease);
}

/* --- line-by-line masked reveal ----------------------------------------- */
[data-tx-armed="split-lines"] .tx-line {
  display: block;
  overflow: hidden;
  /* a little room so tight leading / descenders are never clipped by the mask,
     pulled back with negative margins so the layout is unchanged */
  padding-top: 0.06em;
  padding-bottom: 0.16em;
  margin-top: -0.06em;
  margin-bottom: -0.16em;
}
[data-tx-armed="split-lines"] .tx-line__inner {
  display: block;
  transform: translateY(140%);
}
[data-tx-done="split-lines"] .tx-line__inner {
  transform: translateY(0);
  transition: transform 1s var(--tx-ease);
  transition-delay: var(--tx-delay, 0ms);
}

/* --- typing ------------------------------------------------------------- */
[data-tx-armed="type"] .tx-char {
  opacity: 0;
}
[data-tx-done="type"] .tx-char {
  animation: tx-char-in 0.06s var(--tx-ease) forwards;
  animation-delay: var(--tx-char-delay, 0ms);
}
@keyframes tx-char-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* "Type it, then this appears" -> a second line that fades in after typing. */
[data-tx-after] {
  opacity: 0;
  transform: translateY(0.6em);
}
[data-tx-after-reveal] {
  opacity: 1;
  transform: none;
  transition: opacity 0.7s var(--tx-ease), transform 0.7s var(--tx-ease);
}

.tx-caret {
  display: inline-block;
  width: 0.055em;
  height: 0.92em;
  margin-left: 0.08em;
  background: currentColor;
  vertical-align: -0.06em;
  animation: tx-caret-blink 0.9s steps(1, end) infinite;
}
@keyframes tx-caret-blink {
  50% {
    opacity: 0;
  }
}

/* --- underline sweep ----------------------------------------------------- */
.tx-hl {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0% 1px;
  background-position: 0 calc(100% - 0.04em);
  transition: background-size 1.1s var(--tx-ease);
}
[data-tx-done="highlight"] .tx-hl {
  background-size: 100% 1px;
}

/* --- safety net ----------------------------------------------------------
   The landing hero is only un-hidden by the preloader chain. If that chain is
   interrupted, its text stays at opacity .005 (26 of 58 measured text nodes
   were in that state). This forces such on-screen text visible; normally the
   site's own reveal has already run by then and nothing matches. */
[data-tx-force-visible] {
  opacity: 1 !important;
  pointer-events: auto !important;
}

/* --- respect user motion preferences ------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  [data-tx-armed],
  [data-tx-armed="reveal-up"],
  [data-tx-armed="reveal"],
  [data-tx-armed="mask"] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    -webkit-clip-path: none !important;
  }
  [data-tx-armed] .tx-char,
  [data-tx-after] {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
  [data-tx-armed] .tx-line__inner {
    transform: none !important;
  }
  .tx-caret {
    display: none !important;
  }
}
