/* ==========================================================================
   Raylea — About page
   Layers on css/styles.css and css/home.css. home.css currently carries the
   shared interior-page layer (tokens, reveal grammar, pills, arrow link,
   section rule, header, Enquire band and footer); only what About adds
   lives here. See CLAUDE.md on splitting that shared layer out.

   Colour rhythm, deliberately different from home's:
     hero (orange, image grows) -> vision (sand) -> homesites (sand to navy)
     -> team (navy) -> enquire band (sand to orange) -> footer (orange)
   The orange is in the hero, in the white-on-orange treatment of home's
   Vision band. The Vision fold stays sand: its four golden-hour photographs
   fight brand orange.
   ========================================================================== */

/* ---------- Shared spacing ----------
   The two paddings that meet at the Vision/Homesites seam, named so the
   Homesites image can sit the same distance below the button as the
   Masterplan eyebrow sits below the Vision frame. Both folds are sand, so
   that visible gap is the SUM of the two — 165px at 1440. */
.page-about {
  --about-pad-top: clamp(40px, 4.6vw, 66px);
  --about-pad-bottom: clamp(56px, 6.9vw, 99px);
}

/* ---------- Header over the hero ----------
   Transparent over the orange hero (main.js turns it solid once the copy
   block has scrolled past). In that state: white nav and burger, matching
   the hero copy; the brand's sand wordmark (there is no white logo file);
   and a sand Enquire pill with navy type — the default orange pill would
   vanish on the orange. Navy on sand is 8.34:1. Once scrolled, every
   element drops back to the solid bar's normal treatment.

   Without scripting the header never turns solid, so over the sand folds
   further down its white nav would be faint — the same limitation the home
   page's transparent header has. */
.page-about .site-header--home:not(.is-scrolled) .site-nav--home .site-nav__list,
.page-about .site-header--home:not(.is-scrolled) .nav-toggle {
  color: #ffffff;
}
.page-about .site-header--home:not(.is-scrolled) > .site-header__inner > .btn-pill {
  background: var(--color-sand);
  border-color: var(--color-sand);
  color: var(--color-blue);
}
.page-about .site-header--home:not(.is-scrolled) > .site-header__inner > .btn-pill:hover,
.page-about .site-header--home:not(.is-scrolled) > .site-header__inner > .btn-pill:focus-visible {
  background: var(--color-blue);
  border-color: var(--color-blue);
  color: var(--color-cream);
}

/* ---------- Hero ----------
   Centred white copy on brand orange, then a photograph that grows to fill the
   screen as the page scrolls, lifting the copy ahead of it.

   Two layers, deliberately:
   - The rules directly below are the plain layout — copy, then the image at
     page width. That is what shows with scripting off, with reduced motion,
     or if home.js fails, and it is complete on its own.
   - The scroll scene further down only applies with .js AND no
     reduced-motion preference. home.js drives it through inline transforms. */
.about-hero {
  --hero-start: 0.46;   /* the image's starting width, as a share of the screen */
  /* Clear space above the heading and below the button — 150px on desktop.
     It follows the screen's HEIGHT as well as its width (17vh), so a short
     laptop gets proportionally less space rather than having the gap under
     the button crushed by the image's minimum-visible cap in home.js: on
     1280 x 680, width alone left that gap at 24px. One token for both
     gaps, so they stay equal. */
  --hero-space: clamp(72px, min(10.5vw, 17vh), 150px);
  --hero-pad-bottom: clamp(40px, 4.6vw, 66px);
  /* The plain layout's image height: page width at 16:9. Used to split the
     background behind it — see below. */
  --hero-img-h: calc((100vw - 2 * var(--gutter)) * 9 / 16);

  /* Brand orange with white type — the home page's Vision band treatment,
     on the same token, so a deeper orange swapped into --band-colour
     re-colours both. White on this orange is 2.73:1 and fails AA at every
     size, including the 38px heading; it is the same accepted position as
     the Vision band. See the contrast section in CLAUDE.md.

     In the plain layout the ground splits behind the photograph, orange
     above its midpoint and sand below, so the image straddles the change
     into the sand Vision fold rather than leaving a thin orange strip under
     it. The scroll scene overrides this with flat orange: there the image
     ends full-screen, so the sand simply appears beneath it. */
  position: relative;
  background: linear-gradient(to bottom,
    var(--band-colour) 0,
    var(--band-colour) calc(100% - var(--hero-pad-bottom) - var(--hero-img-h) / 2),
    var(--color-sand) calc(100% - var(--hero-pad-bottom) - var(--hero-img-h) / 2),
    var(--color-sand) 100%);
  color: #ffffff;
  padding: 0 0 var(--hero-pad-bottom);
}

.about-hero__intro {
  max-width: 1240px;
  margin: 0 auto;
  /* The space below the button is padding on this block, not a margin on
     the image, so home.js reads it straight from offsetHeight when placing
     the image in the scroll scene — one source for the gap in both modes. */
  padding: calc(var(--header-height) + var(--hero-space)) var(--gutter) var(--hero-space);
  text-align: center;
}

/* The section headings' scale — the same size, leading and tracking as
   the H2s on both pages (clamp(24px, 2.65vw, 38px): 38px from ~1434px up).
   Not the Home H1's 22px: that one sits under the brandmark, which carries
   its fold. Here nothing sits above the heading, so it has to lead the
   opening itself — and at 22px it was about body size on a phone.

   Two lines, broken where the layout breaks them: "A COASTAL COMMUNITY WITH /
   VIEWS IN EVERY DIRECTION". The measure does the breaking: measured in
   this face and tracking, the first line is 19.3em and "...WITH VIEWS"
   would be 23.8em, so 21.5em sits between them. (The old 26.2em left
   "EVERY DIRECTION" alone on the second line.)
   In em so it holds at every size; recheck if the copy, the tracking or the
   face changes. */
.about-hero__title {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: clamp(24px, 2.65vw, 38px);
  line-height: 1.22;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  max-width: 21.5em;
  margin: 0 auto;
}

.about-hero__lede {
  max-width: 52ch;
  margin: clamp(24px, 3vw, 44px) auto 0;
}

.about-hero__figure {
  margin: 0 var(--gutter);
  overflow: hidden;
  border-radius: 10px;
}

/* <picture> is inline by default; as a block it gives the image a box to
   fill, which the scroll scene's 100% height relies on. */
.about-hero__figure picture { display: block; height: 100%; }

/* height:auto is load-bearing: the width/height attributes are
   presentational hints, and without an author height the aspect-ratio is
   ignored. */
.about-hero__image {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* ---------- Hero: the scroll scene ----------
   The section is two screens tall; the stage inside it is one screen and
   sticks, so the scene plays over one screen of scroll — the first 80% grows
   the image, the last 20% holds it full-bleed before the page moves on.

   The figure is a full-screen layer, scaled down from its top-centre to
   --hero-start and pushed below the copy. Scaling the whole layer, rather
   than clipping a window into it, means the small frame shows the whole
   picture — sky to foreground — exactly as the layout does, and simply
   grows. It also stays on the compositor: transform only, no relayout.

   This is not scroll-jacking: scroll speed is the user's own throughout;
   the page just spends one screen of it on the image. */
@media (prefers-reduced-motion: no-preference) {
  .js .about-hero {
    height: 200svh;
    padding: 0;
    background: var(--band-colour);
  }

  .js .about-hero__stage {
    position: sticky;
    top: 0;
    height: 100svh;
    overflow: hidden;
  }

  .js .about-hero__intro {
    position: relative;
    z-index: 1;
    will-change: transform, opacity;
  }

  /* Starting values are set here too, not only by home.js, so the first
     paint is already the opening frame rather than a flash of full-bleed
     image while the script loads. 62% is a typical copy height; home.js
     replaces it with the measured one. */
  .js .about-hero__figure {
    position: absolute;
    inset: 0;
    margin: 0;
    border-radius: calc(10px / var(--hero-start));
    transform-origin: 50% 0;
    transform: translate3d(0, 62svh, 0) scale(var(--hero-start));
    will-change: transform;
  }

  .js .about-hero__image {
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    transform: scale(1.1);
    will-change: transform;
  }
}

/* ---------- Project Vision ----------
   Same split as home's Vision fold — eyebrow, full-measure rule, heading in
   the wider track, copy in the narrower — then the four aspects below it. */
.vision {
  position: relative;
  background: var(--color-sand);
  color: var(--color-blue);
  padding: clamp(56px, 6.9vw, 99px) 0 var(--about-pad-bottom);
}

.vision__inner { padding: 0 var(--gutter); }

.vision__eyebrow { margin: 0 0 clamp(14px, 1.7vw, 25px); }

.vision__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
  gap: clamp(28px, 6.2vw, 90px);
  margin-top: clamp(28px, 4.6vw, 67px);
  align-items: start;
}

.vision .heading-lg {
  font-size: clamp(24px, 2.65vw, 38px);
  line-height: 1.22;
  /* Balanced so the short heading splits evenly ("OUR VISION FOR / LIFE IN
     RAYLEA") rather than leaving "RAYLEA" alone on the second line. The
     line splitter measures the rendered lines, so it follows the balance. */
  text-wrap: balance;
  letter-spacing: 0.1em;
  max-width: none;
  margin: 0;
}

/* The grid column already sets the measure; .body-copy's own 52ch would cut
   it narrower than the track and leave half the column empty. */
.vision .body-copy { max-width: none; }
.vision .body-copy p + p { margin-top: 1.1em; }

/* ---------- The four aspects ----------
   One frame, four photographs, switched by the splash page's toggle. The
   toggle, its sliding thumb and the crossfade (.views__image) are the shared
   components from styles.css and main.js, used unchanged; only what differs
   because the pill now sits over a photograph is set here. */
.vision__stage {
  position: relative;
  margin: clamp(40px, 5.2vw, 76px) 0 0;
  border-radius: 10px;
}

/* The photographs' own 2.05:1 on desktop — wide vistas, which a tighter crop
   would fight. The images are stacked absolutely inside, so the frame carries
   the ratio rather than the files. */
.vision__frame {
  position: relative;
  aspect-ratio: 2400 / 1171;
  border-radius: 10px;
  overflow: hidden;
  background: var(--color-blue);
}

/* Bottom-centre. The lower third of all four frames is foreground scrub,
   water or flats, which is darker and steadier than the sky — the pill
   reads off a quieter ground there. Flex rather than translateX(-50%) so
   the reveal's own translateY on this element does not overwrite it. */
.vision__toggle {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(16px, 2.2vw, 32px);
  z-index: 1;
  display: flex;
  justify-content: center;
  padding: 0 var(--gutter);
  pointer-events: none;
}

/* On the splash page the pill sits on a sand gradient. Here it sits on a
   photograph, which changes from bright sky to dark scrub depending on the
   view, so it carries its own ground: navy glass, blurred. That keeps the
   labels legible on every frame without a scrim over the picture itself.

   The active segment is white on the brand orange, matching the site's
   orange pill buttons (2.73:1 — the accepted position for white on this
   orange; navy on --color-orange-aa, 4.53:1, was used before). Inactive labels run at 0.85
   rather than the shared 0.65 for the same reason: on glass over a photo,
   0.65 loses too much.

   0.75 on the glass was set by measuring, not by eye: sampled against the
   brightest pixel under the pill in each photograph, unblurred, the worst
   case is the South frame, where the pill can sit over white glints on the
   tidal flats. At 0.62 that pixel put the inactive labels at 3.33:1 and at
   0.72 at 4.44:1; 0.75 is the first value that clears 4.5:1 there. On the
   average ground under the pill the labels run 8:1 or more. */
.vision__toggle .toggle-group {
  --toggle-thumb: var(--color-orange);
  margin: 0;
  color: var(--color-cream);
  border-color: color-mix(in srgb, var(--color-cream) 55%, transparent);
  background: rgba(32, 33, 54, 0.75);
  -webkit-backdrop-filter: blur(12px) saturate(1.1);
  backdrop-filter: blur(12px) saturate(1.1);
  pointer-events: auto;
}
.vision__toggle .toggle-group__btn { opacity: 0.85; }
.vision__toggle .toggle-group__btn:hover,
.vision__toggle .toggle-group__btn:focus-visible { opacity: 1; }
.vision__toggle .toggle-group__btn.is-active {
  opacity: 1;
  color: #ffffff;
}
/* The shared button has no visible focus ring of its own; on a photograph
   the browser default can vanish, so draw one in cream. */
.vision__toggle .toggle-group__btn:focus-visible {
  outline: 2px solid var(--color-cream);
  outline-offset: 2px;
}

/* ---------- Homesites ----------
   A centred head over one wide image, then a single call to action. Each
   fold is laid out differently — hero left, Vision copy over a toggled
   frame, this centred — so the page reads as designed rather than as one
   layout repeated down the screen.

   The masterplan is deliberately not on this page: it lives behind "View
   Now Selling", and this fold exists to send people there. */
/* The ground fades sand to navy behind the photograph, the way the Enquire
   band fades sand to orange behind the form block: the image floats on the
   transition, and the fade lands on full navy exactly at this fold's foot,
   where the Team fold picks it up — so there is no seam.

   The fade starts at the image's TOP edge, so every word above it — eyebrow,
   heading, copy, button — stays on flat sand at 8.34:1. That stop is
   measured up from the bottom: the bottom padding, then the image's height,
   which is the content width at 8:5. 100vw includes a classic scrollbar on
   Windows, which puts the stop ~10px high; that lands beside the image, not
   behind any text. */
.homesites {
  --homesites-img-h: calc((100vw - 2 * var(--gutter)) * 1030 / 1648);

  position: relative;
  background: linear-gradient(to bottom,
    var(--color-sand) 0%,
    var(--color-sand) calc(100% - var(--about-pad-bottom) - var(--homesites-img-h)),
    var(--color-blue) 100%);
  color: var(--color-blue);
  padding: var(--about-pad-top) 0 var(--about-pad-bottom);
}

.homesites__inner { padding: 0 var(--gutter); }

.homesites__head {
  max-width: 62ch;
  margin: 0 auto;
  text-align: center;
}

.homesites__head .eyebrow { margin: 0 0 clamp(14px, 1.7vw, 25px); }

.homesites__head .heading-lg {
  font-size: clamp(24px, 2.65vw, 38px);
  line-height: 1.22;
  letter-spacing: 0.1em;
  max-width: none;
  margin: 0 0 clamp(18px, 2vw, 28px);
}

.homesites__head .body-copy { max-width: none; }
.homesites__head .body-copy p + p { margin-top: 1.1em; }

/* The same distance below the button as there is above the eyebrow: the
   Vision fold's bottom padding plus this fold's top padding, because both
   are sand and read as one gap. Built from the same two tokens, so the two
   gaps cannot drift apart. */
.homesites__figure {
  margin: calc(var(--about-pad-bottom) + var(--about-pad-top)) 0 0;
  border-radius: 10px;
}

/* 8:5, fixed on the box so the page does not reflow when the image loads.
   cover, not contain: this is a photograph, so a slight crop is fine — the
   masterplan that was here before needed contain because its cropped edge
   would have been lots. */
.homesites__image {
  display: block;
  width: 100%;
  /* height:auto is load-bearing: the width/height attributes on the <img>
     are presentational hints, and with no author height rule they keep the
     used height non-auto, so aspect-ratio below is simply ignored. */
  height: auto;
  aspect-ratio: 1648 / 1030;
  object-fit: cover;
  background: color-mix(in srgb, var(--color-blue) 6%, transparent);
  border-radius: 10px;
}

/* Under the copy, inside the head, so the call to action is read with the
   words that make the case for it rather than after the photograph. */
.homesites__actions {
  display: flex;
  justify-content: center;
  margin-top: clamp(24px, 2.6vw, 36px);
}

/* ---------- Developer and selling team ----------
   Navy, so the page's most factual copy sits on its strongest pair
   (cream on navy, 10.07:1) and About gets a fold of its own rather than a
   third sand section in a row. */
.team {
  position: relative;
  background: var(--color-blue);
  color: var(--color-cream);
  padding: clamp(56px, 6.9vw, 99px) 0;
}

.team__inner { padding: 0 var(--gutter); }

.team__inner .eyebrow { margin: 0 0 clamp(14px, 1.7vw, 25px); opacity: 1; }

.team__heading {
  font-size: clamp(24px, 2.65vw, 38px);
  line-height: 1.22;
  letter-spacing: 0.1em;
  max-width: 20ch;
  margin: clamp(28px, 4.6vw, 67px) 0 0;
}

.team__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(32px, 4.5vw, 64px);
  margin-top: clamp(40px, 5.2vw, 74px);
  align-items: stretch;
}

/* Each entry is a column so its website link can sit at the foot of it: the
   two descriptions run to different lengths, and the links should line up
   across the row rather than follow the copy. */
.team__member {
  margin: 0;
  display: flex;
  flex-direction: column;
}

/* The site's secondary-link style, not an orange pill — pills are kept for
   the primary actions (Enquire, Register now, View Now Selling). Pushed to
   the bottom of the column; the body copy's margin keeps a minimum gap above
   when the copy is the longer of the two. */
.team .body-copy { margin-bottom: clamp(24px, 2.4vw, 32px); }
.team__link {
  align-self: flex-start;
  margin-top: auto;
}

/* These leave the site, so the arrow points up and out (\2197) rather than
   forward, and they open in a new tab — announced to screen readers by a
   visually hidden note in the link text. */
.link-arrow--external::after { content: '\2197'; }
.link-arrow--external:hover::after,
.link-arrow--external:focus-visible::after { transform: translate(3px, -3px); }

.team__media {
  margin: 0 0 clamp(20px, 2.2vw, 30px);
  position: relative;
}
.team__media img {
  display: block;
  width: 100%;
  /* height:auto is load-bearing: the width/height attributes on the <img>
     are presentational hints, and with no author height rule they keep the
     used height non-auto, so aspect-ratio below is simply ignored. */
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 10px;
}

/* The caption credits a photograph of another Resi Ventures community, so
   it has to be legible rather than decorative — it is the only thing
   telling the reader this is not Raylea. */
.team__media-caption {
  margin-top: 12px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.75;
}

/* Holds the grid while the second agent is unknown. Hairline and labelled
   rather than a grey fill, so it reads to a reviewer as a reserved space
   rather than as an image that failed to load. */
.team__media--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 3 / 2;
  border-radius: 10px;
  border: 1px dashed color-mix(in srgb, currentColor 30%, transparent);
}

.team__role {
  margin: 0 0 12px;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.team .body-copy { max-width: none; }

.team__media--empty span {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.45;
}

/* ---------- Narrow ---------- */
@media (max-width: 860px) {
  /* Wider from the start on phones: at the desktop 46% a phone frame would be a
     sliver. */
  .about-hero { --hero-start: 0.8; }

  .vision__grid,
  .team__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(20px, 4vw, 32px);
  }

  /* Taller on narrow screens. At 2.05:1 the frame is ~167px high on a phone,
     and a 40px pill laid over that covers a quarter of the picture. Cropping
     the sides costs some sweep, but the toggle gives the reader the other
     three directions, so the frame no longer has to show everything. */
  .vision__frame { aspect-ratio: 3 / 2; }

  .homesites__head { text-align: left; }
  .homesites__actions { justify-content: flex-start; }
}

@media (max-width: 600px) {
  .vision__frame { aspect-ratio: 4 / 3; }
  .homesites__actions .btn-pill { width: 100%; }
}
