/* ==========================================================================
   Sections.

   Pinning is done with position:sticky rather than ScrollTrigger.pin(). Sticky
   needs no pin-spacer, so it cannot introduce layout shift on refresh, and it
   survives mobile browser-chrome resize — which is exactly where GSAP pins
   tend to jump. GSAP still drives the scrubbed content inside the pin.

   An act's length is set by --act-scroll (in viewports). Mobile overrides it
   to 1, which collapses the pin into an ordinary section.
   ========================================================================== */

/* --- Full-bleed media bleed ------------------------------------------------
   A section whose background is a photo or a video has to keep painting below
   its own last line, because the section after it is pulled up by the furrow's
   negative margin and its clip-path then cuts a notch straight through to
   whatever is behind. Growing the box by --bleed and pulling the next section
   back up by the same amount leaves the flow untouched while the media runs on
   under the deepest point of the curve. Without it the notch shows page
   background — the white slivers under full-screen images on mobile.
   -------------------------------------------------------------------------- */
.section.has-bleed {
  --bleed: clamp(64px, 12vw, 140px);
  padding-block-end: var(--bleed);
  margin-block-end: calc(-1 * var(--bleed));
}
/* The bleed is ADDED to whatever bottom padding the section already wanted,
   never used in place of it: swallowing that padding is what left the final
   CTA button sitting a few pixels above the footer's curve. Each has-bleed
   section therefore restates its own value here, with --bleed falling back to
   0 so the same declaration is correct when the class is absent. */

.act {
  --act-scroll: 1;
  min-block-size: calc(var(--act-scroll) * var(--svh));
}

.act__inner {
  position: sticky;
  inset-block-start: 0;
}

/* --- Hero ------------------------------------------------------------------ */

.hero {
  position: relative;
  min-block-size: var(--svh);
  color: #fff;
  background: var(--ink);
  overflow: hidden;
}

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

.hero__video,
.hero__media img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}



/* The nav sits over moving footage whose luminance changes frame to frame, so
   contrast is guaranteed by this scrim rather than by the video. */
.hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgb(35 31 32 / 0.55) 0%,
    rgb(35 31 32 / 0.25) 38%,
    rgb(35 31 32 / 0.55) 100%
  );
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--u-8);
  min-block-size: var(--svh);
  padding-block: calc(var(--u-9) + var(--u-6)) var(--u-7);
}

.hero__title {
  display: grid;
  gap: 0.04em;
  /* 80% of the inner width — fitText fills this box, so the headline lands ~20%
     smaller than full-bleed. Centred. */
  inline-size: 80%;
  margin-inline: auto;
  font-family: var(--font-display);
  font-size: var(--fs-hero);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  line-height: var(--lh-display);
}

.hero__line {
  display: block;
  /* max-content is load-bearing: a block-level line reports the container's
     width, so fitText() would measure 1160px for every line and compute a
     ratio of 1. Shrink-wrapping makes scrollWidth the actual text width. */
  inline-size: max-content;
  max-inline-size: 100%;
  justify-self: center;
  text-align: center;
  /* First line ("מחוברים לקרקע") reads lighter than the bold payoff line. */
  font-weight: 500;
  /* fitText() writes --fit so both lines render the same width. */
  font-size: calc(1em * var(--fit, 1));
}
.hero__line--2 {
  font-weight: var(--fw-display);
}

.hero .cue {
  color: #fff;
}

/* --- Acts ------------------------------------------------------------------ */

/* No overflow here. A scroll-clipping ancestor would make the sticky inner
   stick to this box instead of the viewport, which is the same as not
   pinning at all. The decorative bands clip themselves — .furrows is
   overflow:hidden — so nothing escapes anyway. */
.act {
  position: relative;
}

/* Carries the container's own width constraint rather than the .container
   class, so it cannot be caught by `.section > .container` rules. */
.act__inner {
  inline-size: min(100% - (2 * var(--gutter)), var(--w-max));
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--u-7);
  min-block-size: var(--svh);
  padding-block: calc(var(--u-9) + var(--u-6)) var(--u-7);
}

.act__grid {
  display: grid;
  gap: var(--u-7);
  align-items: center;
}

.act__copy > * + * {
  margin-block-start: var(--u-5);
}

.act__copy .h2,
.act-title {
  margin-block-end: var(--u-2);
}

.act-title {
  font-size: var(--fs-act);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  line-height: 1.05;
}

.act__figure {
  display: grid;
  place-items: center;
}

.act__figure--tree {
  gap: 0;
  align-content: center;
}

.act__tree {
  inline-size: clamp(90px, 14vw, 168px);
  block-size: auto;
}

.act__roots {
  inline-size: clamp(38px, 6vw, 70px);
  block-size: auto;
  margin-block-start: -2px;
  opacity: 0.55;
}

.act__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--u-5);
  color: var(--t-muted);
}

/* --- Story: two scroll-sections, one sticky scene ------------------------
   A tree (with roots) is pinned on the RIGHT across both scroll sections, both
   on a light ground. Section 1: the tree grows, family text reveals. Section 2:
   the buildings grow up on the LEFT — larger than the tree, their water line
   level with the tree's roots — and the continuation text reveals. Phases come
   from story.js (is-1 / is-2); each section reveals its text on one trigger.
   -------------------------------------------------------------------------- */
.story {
  position: relative;
  block-size: 200svh;              /* one viewport of scroll per section */
  color: var(--t-fg);
  /* Buildings drive the scale; the tree is 30% smaller. Both hang off the
     stage's vertical middle, the shared ground line. */
  --bldg-h: clamp(190px, 27vh, 360px);
  --tree-h: calc(0.7 * var(--bldg-h));
}

.story__stage {
  position: sticky;
  inset-block-start: 0;
  block-size: 100svh;
  overflow: hidden;
  background-color: var(--paper);
}

/* --- sticky scene: tree right, buildings left --------------------------- */
.story__scene {
  position: absolute;
  inset: 0;
  z-index: 1;
  color: var(--field);
  pointer-events: none;
}

/* Tree on the right (inline-start in RTL). Its trunk/root junction sits on the
   ground line (top:50%): the canopy grows up from it, the roots hang below. */
.story__tree {
  position: absolute;
  inset-inline-start: clamp(1.5rem, 5vw, 6rem);
  inset-block-start: 50%;
  inline-size: calc(var(--tree-h) * 84 / 120);
}

.story__tree-canopy {
  position: absolute;
  inset-block-end: 0;              /* base on the ground line */
  inset-inline: 0;
  inline-size: 100%;
  block-size: var(--tree-h);
  object-fit: contain;
  object-position: bottom center;
  transform-origin: bottom center;
  /* grows up when section 1 is reached */
  clip-path: inset(100% 0 0 0);
  scale: 0.6;
  transition: clip-path 0.9s var(--ease-out) 0.15s,
    scale 0.9s var(--ease-out) 0.15s;
}
.story.is-1 .story__tree-canopy {
  clip-path: inset(0 0 0 0);
  scale: 1;
}

.story__tree-roots {
  position: absolute;
  inset-block-start: 0;            /* hang from the ground line */
  inset-inline: 0;
  margin-inline: auto;
  inline-size: 42%;
  /* Height from the aspect ratio, not a fraction of --tree-h: the box was
     slightly taller than the artwork's 35:47, and `contain` put that slack
     under the crown — which the flip then turned into a gap between the
     trunk's foot and the roots. */
  block-size: auto;
  opacity: 0.5;
  scale: 1 -1;                     /* authored up; flip to point down */
  /* The trunk meets the ground at 51.5% across the mark, while the roots'
     crown sits at 49.9% once centred — this closes that 1.6% and puts the two
     on the same axis. Physical, so it holds in both directions. */
  translate: 4% 0;
  /* grows down, a beat after the canopy */
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.9s var(--ease-out) 0.35s;
}
.story.is-1 .story__tree-roots {
  clip-path: inset(0 0 0 0);
}

/* Buildings on the left (inline-end in RTL), centred on the same ground line,
   larger than the tree. The container spans the full city.svg (buildings +
   reflection); its middle — the water line — sits on top:50%. */
.story__city {
  position: absolute;
  inset-inline-end: clamp(1.5rem, 6vw, 7rem);
  inset-block-start: 50%;
  translate: 0 -50%;
  block-size: calc(var(--bldg-h) * 2);
  inline-size: calc(var(--bldg-h) * 162 / 266);
}

.story__city-half {
  position: absolute;
  inset-inline: 0;
  block-size: 50%;
  overflow: hidden;
}
.story__city-half img {
  position: absolute;
  inset-inline: 0;
  inline-size: 100%;
  block-size: 200%;               /* full asset, cropped by the half */
}

/* Upper half: the solid buildings, rising up out of the ground line. */
.story__city-half--up {
  inset-block-start: 0;
}
.story__city-half--up img {
  inset-block-start: 0;
  translate: 0 100%;
  transition: translate 1s var(--ease-out);
}
.story.is-2 .story__city-half--up img {
  translate: 0 0;
}

/* Lower half: the reflection, descending — and faded out at the bottom so it
   can run off any screen height without a hard edge. */
.story__city-half--down {
  inset-block-end: 0;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 92%);
          mask-image: linear-gradient(to bottom, #000 0%, transparent 92%);
}
.story__city-half--down img {
  inset-block-end: 0;
  translate: 0 -100%;
  transition: translate 1s var(--ease-out);
}
.story.is-2 .story__city-half--down img {
  translate: 0 0;
}

/* --- copy: centre-left, right-aligned, cross-fading between sections ----- */
.story__copy {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  align-content: center;
  justify-items: center;
  padding-inline: var(--gutter);
  text-align: center;
}
.story__copy > * {
  max-inline-size: 620px;
  margin-inline: auto;
}
.story__copy > * + * {
  margin-block-start: var(--u-5);
}

/* Body paragraphs after the lead run on as one block, no gap between them. */
.story__copy > p:not(.lead) + p:not(.lead) {
  margin-block-start: 0;
}

/* Hand-placed line breaks for the desktop measure only (to keep a last line
   from holding a word or two); on narrower screens the text wraps freely. */
@media (max-width: 991px) {
  .br-desk {
    display: none;
  }
}

.story__copy .lead {
  color: var(--t-muted);
}

/* Section 1: shows in phase 1, clears in phase 2. It clears quickly and fully
   BEFORE section 2 begins, so the two never cross-fade on top of each other. */
[data-story-copy="1"] {
  opacity: 0;
  translate: 0 20px;
  transition: opacity 0.6s var(--ease-out), translate 0.6s var(--ease-out);
}
.story.is-1 [data-story-copy="1"] {
  opacity: 1;
  translate: 0 0;
}
.story.is-2 [data-story-copy="1"] {
  opacity: 0;
  translate: 0 -20px;
  transition: opacity 0.45s var(--ease-out), translate 0.45s var(--ease-out);
}

/* Section 2: held back ~0.55s so block 1 has fully cleared first — a beat of
   pause between them rather than an abrupt swap. */
[data-story-copy="2"] {
  opacity: 0;
  translate: 0 20px;
  transition: opacity 0.6s var(--ease-out) 0.55s,
    translate 0.6s var(--ease-out) 0.55s;
}
.story.is-2 [data-story-copy="2"] {
  opacity: 1;
  translate: 0 0;
}

/* --- Static (touch / narrow): stack; one reveal each ------------------- */
.story.is-static {
  block-size: auto;
}
.story.is-static .story__stage {
  position: relative;
  block-size: auto;
  overflow: visible;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-block: var(--u-9) var(--u-8);
  padding-inline: var(--gutter);
  max-inline-size: var(--w-max);
  margin-inline: auto;
}
.story.is-static .story__copy {
  position: relative;
  inset: auto;
  display: block;
  opacity: 1;
  translate: none;
  padding: 0;
  max-inline-size: 100%;
}
.story.is-static .story__copy > * {
  max-inline-size: 100%;
}

/* Icons and text stack in reading order, one pair revealing after the other
   as the page scrolls: tree + text 1, then building + text 2. .story__scene
   only existed to group tree/city for the pinned desktop scene, so it's
   flattened here to let each icon sit next to its own text block. */
.story.is-static .story__scene {
  display: contents;
}
.story.is-static .story__tree { order: 1; }
.story.is-static [data-story-copy="1"] { order: 2; }
.story.is-static .story__city { order: 3; }
.story.is-static [data-story-copy="2"] { order: 4; }

/* Same height as the tree icon — two beats of one story, not one dwarfing
   the other. */
.story.is-static {
  --tree-h: calc(0.7 * clamp(96px, 26vw, 140px));
  --bldg-h: var(--tree-h);
}
.story.is-static .story__tree {
  position: relative;
  inset: auto;
  margin-block-end: var(--u-5);
}
/* Buildings only — no reflection, no root shown on mobile: just the two
   icons marking each beat of the story. Pulled close to text 2 (its own
   pair) and pushed well clear of text 1 above, so it doesn't read as
   trailing off the first block. */
.story.is-static .story__city {
  position: relative;
  inset: auto;
  translate: none;
  block-size: var(--bldg-h);
  overflow: hidden;
  margin-block-start: var(--u-8);
  margin-block-end: var(--u-4);
}
.story.is-static .story__city-half--down {
  display: none;
}
/* With the reflection half gone, the "up" half (previously 50% of the
   parent, per the two-half desktop layout, so the pair together filled the
   full svg) needs to fill the whole box on its own — otherwise the parent's
   own block-size still reserves room for a second half that never renders,
   leaving a dead gap below the visible building before text 2. The img
   stays at its base 200%-of-half sizing, so the crop ratio (top mask only,
   no reflection) is unchanged — only the window showing it gets taller. */
.story.is-static .story__city-half--up {
  block-size: 100%;
}
.story.is-static .story__tree-roots {
  display: none;
}

/* Stage 1 reveals via .is-in-1, stage 2 via .is-in-2 (story.js), each firing
   independently as its own icon+text pair scrolls into view. */
.story.is-static .story__tree-canopy {
  clip-path: inset(100% 0 0 0);
  scale: 0.6;
  transition: clip-path 0.9s var(--ease-out), scale 0.9s var(--ease-out);
}
.story.is-static.is-in-1 .story__tree-canopy {
  clip-path: inset(0 0 0 0);
  scale: 1;
}
.story.is-static [data-story-copy="1"] {
  opacity: 0;
  translate: 0 16px;
  transition: opacity 0.6s var(--ease-out) 0.2s, translate 0.6s var(--ease-out) 0.2s;
}
.story.is-static.is-in-1 [data-story-copy="1"] {
  opacity: 1;
  translate: 0 0;
}
.story.is-static .story__city-half--up img {
  translate: 0 100%;
  transition: translate 1s var(--ease-out);
}
.story.is-static.is-in-2 .story__city-half--up img {
  translate: 0 0;
}
.story.is-static [data-story-copy="2"] {
  opacity: 0;
  translate: 0 16px;
  transition: opacity 0.6s var(--ease-out) 0.2s, translate 0.6s var(--ease-out) 0.2s;
}
.story.is-static.is-in-2 [data-story-copy="2"] {
  opacity: 1;
  translate: 0 0;
}

/* --- שורשים ומשפחה — the wordplay, per the Figma adaptation -----------------
   A centred head (sprig, title, subtitle) over two photo-backed panels
   (rock → האבן, dirt → האדמה), then a centred closing line. Text weights map
   onto the page's own tokens rather than the Figma's hard-coded 600.
   -------------------------------------------------------------------------- */
.roots {
  position: relative;
  padding-block: var(--u-8) 0;    /* piles bleed off the bottom — no gap */
  overflow: hidden;               /* crops the piles at the section edges */
}

.roots__head {
  display: grid;
  justify-items: center;
  text-align: center;
  gap: var(--u-4);
}

.roots__sprig {
  inline-size: 36px;
  block-size: auto;
}

.roots__title {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
}

.roots__sub {
  max-inline-size: 52ch;
  font-size: var(--fs-lead);
  color: var(--t-muted);
}
.roots__sub b {
  font-weight: var(--fw-body-strong);
  color: var(--t-fg);
}

/* --- the two panels ------------------------------------------------------- */
.roots__closing {
  max-inline-size: var(--w-text);
  margin-inline: auto;
  text-align: center;
  font-size: var(--fs-lead);
  font-weight: var(--fw-body-strong);
  color: var(--t-fg);
}

/* --- the two piles: full-bleed cut-outs at the section bottom -------------
   Soil (earth) on the left, rock (stone) on the right; both bleed off the
   bottom and their outer edge and overlap in the centre. The section clips
   them (overflow:hidden on .roots), so only part of each pile shows — which
   is what lets them reach the screen edges cleanly at any width. */
.roots__scene {
  position: relative;
  /* Pulled up so the piles' transparent tops overlap the closing line a touch. */
  margin-block-start: calc(-1 * var(--u-6));
  block-size: clamp(380px, 36vw, 540px);
}

/* Sized by HEIGHT so the wide piles fill the band and bleed off the sides
   (cropped by the section), rather than going short at narrow widths. */
.roots__pile {
  position: absolute;
  inset-block-end: -4%;               /* bleed off the section bottom */
  block-size: 104%;
  inline-size: auto;
  max-inline-size: none;
}
/* RTL: inline-end is the left edge, inline-start the right edge. */
.roots__pile--soil {
  inset-inline-end: min(-6vw, -48px);
}
.roots__pile--rock {
  inset-inline-start: min(-7vw, -56px);
}

.roots__labels {
  position: absolute;
  inset-block-end: 28%;
  inset-inline: 0;
  z-index: 2;
  display: flex;
  justify-content: center;
  gap: clamp(var(--u-6), 9vw, var(--u-10));
  padding-inline: var(--gutter);
  pointer-events: none;
}

.roots__label {
  display: grid;
  gap: var(--u-1);
  text-align: start;
}

.roots__word {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
  line-height: 1.1;
}

.roots__desc {
  font-size: var(--fs-lead);
}

/* Light on the earth, ink on the paler stone. */
.roots__label--soil {
  color: #fff;
  text-shadow: 0 1px 12px rgb(60 30 10 / 0.45);
}
.roots__label--rock {
  color: #fff;
  text-shadow: 0 1px 12px rgb(20 18 14 / 0.55);
  justify-items: end;
  text-align: end;
}

/* --- Variant B: one combined cut-out -------------------------------------
   The whole image is shown (contain, not cover), with room left below it so
   its full height reads inside the section rather than bleeding off.
   -------------------------------------------------------------------------- */
.roots--combined {
  /* Double the base .roots top padding. The furrow notch above eats into the
     first 70px of the section, so the title needs the extra clearance before
     it stops reading as crowded by the curve. */
  padding-block-start: var(--u-10);
  padding-block-end: clamp(var(--u-8), 12vw, var(--u-10));
  overflow: visible;
}

.roots--combined .roots__scene {
  block-size: auto;
  /* Close to the head copy — the image is the answer to the line above it. */
  margin-block-start: var(--u-3);
}

/* The cut-out reads soil-left / rock-right, which matches the RTL label order.
   Under LTR the labels swap sides, so the picture is mirrored to follow them
   rather than leaving each word over the wrong pile. */
[dir="ltr"] .roots__pile--combined {
  scale: -1 1;
}

.roots__pile--combined {
  position: relative;
  inset: auto;
  /* block, not inline: an inline image leaves descender space under it, which
     makes the scene box taller than the picture and throws the centred labels
     off the middle of the image. */
  display: block;
  inline-size: min(100%, 1408px);
  block-size: auto;
  margin-inline: auto;
  object-fit: contain;
}

/* Under the words only: the cut-out is transparent between the grains, so
   white type over a thin patch would otherwise land on the cream page. */
.roots__wash {
  position: absolute;
  /* Only as wide as the pair of labels: at 12% inset the wash reached past
     the piles on a wide screen and read as a grey band across the image. */
  inset-inline: 0;
  inline-size: min(660px, 62%);
  margin-inline: auto;
  inset-block-start: 35%;
  block-size: 30%;
  z-index: 1;
  pointer-events: none;
  /* Tight to the words and fading to nothing well inside the pile, so it
     never reads as a grey panel laid over the cream. */
  background: radial-gradient(
    ellipse 58% 70% at 50% 50%,
    rgb(16 20 12 / 0.5) 0%,
    rgb(16 20 12 / 0.22) 58%,
    rgb(16 20 12 / 0) 100%
  );
}

/* Centred on the image, where the body of each pile is densest — down in the
   scatter the cut-out thins out and the type loses its ground. Centred by
   stretching the row rather than by a transform: the entrance animation owns
   `translate` on this element and would cancel it. */
.roots--combined .roots__labels {
  inset-block: 0;
  align-items: center;
  z-index: 2;
}

/* Below desktop the two labels wrap to different line counts, and centring
   each on its own drops their titles out of line with each other. One grid
   row instead: the row stays centred on the image, both titles share its top
   edge, and each description follows underneath. Desktop is unchanged. */
@media (max-width: 991px) {
  .roots--combined .roots__labels {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-content: center;
    align-items: start;
  }
}

@media (max-width: 640px) {
  .roots--combined .roots__scene {
    margin-block-start: var(--u-4);
    /* The image runs wider than the screen here: at viewport width this
       landscape cut-out is only ~200px tall, far too small to carry the two
       words. Overscaling it puts the dense body of each pile behind its own
       label, at the cost of losing the outermost scatter off both edges. */
    overflow: hidden;
  }
  .roots--combined .roots__pile--combined {
    inline-size: 190%;
    max-inline-size: none;
    margin-inline-start: -45%;
  }
  .roots--combined .roots__labels {
    gap: var(--u-4);
  }
  .roots__wash {
    inline-size: min(340px, 92%);
    inset-block-start: 30%;
    block-size: 40%;
  }
}

/* --- entrance: the piles rise and settle in on scroll -------------------- */
[data-reveal-panel] .roots__pile {
  opacity: 0;
  translate: 0 44px;
  transition: opacity 0.8s var(--ease-out), translate 0.9s var(--ease-out);
}
[data-reveal-panel].is-in .roots__pile {
  opacity: 1;
  translate: 0 0;
}
[data-reveal-panel] .roots__pile--rock {
  transition-delay: 0.12s;
}
[data-reveal-panel] .roots__labels {
  opacity: 0;
  translate: 0 16px;
  transition: opacity 0.6s var(--ease-out) 0.45s, translate 0.6s var(--ease-out) 0.45s;
}
[data-reveal-panel].is-in .roots__labels {
  opacity: 1;
  translate: 0 0;
}

/* --- Activities: the four areas of activity --------------------------------
   Figma "Desktop - 9" frame. Icons are the client's own exported SVGs
   (assets/svg/activity-*.svg), used as provided rather than redrawn.
   -------------------------------------------------------------------------- */

.activities {
  padding-block: var(--u-9) calc(var(--u-9) + clamp(40px, 6vw, 88px));
}

.activities__head {
  display: grid;
  justify-items: center;
  gap: var(--u-3);
  max-inline-size: 640px;
  margin-inline: auto;
  margin-block-end: var(--u-7);
  text-align: center;
}

.activities__title {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
}

.activities__sub {
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: var(--fw-body-strong);
  color: var(--field-ink);
}

.activities__lead {
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--t-muted);
}

.activities__grid {
  display: grid;
  gap: var(--u-4);
  grid-template-columns: 1fr;
}

.activity {
  display: grid;
  align-content: start;
  justify-items: start;
  gap: var(--u-3);
  padding: var(--u-5);
  background: var(--paper);
  border: 1px solid var(--t-line);
  border-radius: var(--r-md);
  text-align: start;
  box-shadow: 0 6px 9px rgb(0 0 0 / 0.05);
}

.activity__icon {
  inline-size: 40px;
  block-size: 40px;
}

.activity__title {
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: var(--fw-heading);
}

.activity__desc {
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--t-muted);
}

/* Two-up on tablets, four in a row on desktop — same breakpoints as the
   values grid, so the two card sections respond in step with each other. */
@media (min-width: 620px) and (max-width: 991px) {
  .activities__grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 992px) {
  .activities__grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* --- Reveal: the future beneath the land, with overlaid copy ---------------
   Fine pointer: a lens follows the cursor and cuts through the top (today)
   image to the plan underneath. Touch: a scroll crossfade. Driven by
   sections/reveal.js via --mx / --my / --r (lens) and --reveal (touch).
   -------------------------------------------------------------------------- */
.reveal {
  position: relative;
  color: #fffdf7;
  --mx: 50%;
  --my: 42%;
  --r: 0px;       /* lens radius, driven per-frame on desktop; closed until hover */
  --feather: 1px; /* crisp cut-out edge — the drop shadow gives the depth */
  --reveal: 0;    /* touch: scroll crossfade 0..1 */
  block-size: 100svh;
}

/* Full-bleed section: the furrow's top padding would leave a strip of page
   background above the image (the "grey area"). Drop it and let the stage fill
   the whole clipped section, so the diagonal edge shows the photo overlapping
   the section above. The section keeps a little extra height for the overlap. */
.reveal.furrow-top {
  padding-block-start: 0;
  /* The sticky stage lives in this section's CONTENT box, so the bleed padding
     below has to be added on top of a full viewport — otherwise the content box
     is shorter than the stage, sticky has negative travel, and the stage simply
     scrolls away instead of pinning. */
  block-size: calc(100lvh + var(--bleed) + clamp(40px, 6vw, 88px));
}

/* The sticky stage can only paint inside this section's own box — the box is
   what the section's clip-path clips to, and the sticky stop is its bottom.
   So the bleed has to grow the SECTION, not just the stage: without it the
   photo ends on a straight edge above the next section's curve and the page
   background shows through the notch. The negative margin hands the extra
   height straight back to the flow, so nothing below moves. */
.reveal {
  --bleed: clamp(64px, 12vw, 140px);
  /* The sticky stage stops at the section's content edge, so the bleed strip
     below it would otherwise show the section's own ink. Carrying the same
     photo on the section background means whatever the stage does not cover
     is still the photo — no arithmetic to keep in sync, at any breakpoint. */
  /* image-set, not the original: the <img> above is now served from the
     resized set, and pointing the backing layer at the 2.7MB master would
     have quietly downloaded it anyway. */
  background-image: image-set(
    url(../img/reveal-after-1280.webp?v=2) type("image/webp"),
    url(../img/reveal-after-1280.jpg?v=2) type("image/jpeg")
  );
  background-size: cover;
  background-position: center bottom;
  background-repeat: no-repeat;
}
.reveal.furrow-top {
  padding-block-end: var(--bleed);
  margin-block-end: calc(-1 * var(--bleed));
}

.reveal__stage {
  /* lvh, not svh: when the mobile URL bar collapses the visible viewport is
     taller than svh, and a stage sized in svh leaves a band of page
     background under the photo at the section's bottom edge. */
  /* Absolute, so it covers the section's PADDING box rather than its content
     box — that is the whole fix for the seam above the next section's curve.
     In flow the stage stopped at the content edge, 139px short of the bottom,
     and that strip was painted by the section's own background-image: the
     same photograph, but `cover`-cropped to a 1177px-tall box while the <img>
     inside the stage was cover-cropped to 1038px. Two different crops of one
     picture meeting along a straight horizontal line, right where the eye is
     already looking for the curve. One box, one crop, no seam.

     Safe to take out of flow because the section sets its own block-size.

     It also does not pin: on a fine pointer the reveal is driven by the cursor
     lens, not by scroll, so there is nothing for a pin to hold still — and
     pinning left sticky ~70px of travel, so the copy slid up the screen with
     200px of photograph still below it. The touch rules below restore sticky,
     where the scroll crossfade does need it. */
  position: absolute;
  inset: 0;
  overflow: hidden;
  isolation: isolate;
  opacity: 0;
  transition: opacity 0.35s var(--ease-out);
}
.reveal.is-in .reveal__stage {
  opacity: 1;
}

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

.reveal__img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* The planned future, revealed underneath. */
.reveal__img--after { z-index: 0; }

/* The land today, on top. A radial lens punches a clean hole through it at the
   pointer, so the future shows through. */
.reveal__img--before {
  z-index: 1;
  filter: sepia(0.32) saturate(0.95) brightness(0.96) contrast(1.01);
  --lens: radial-gradient(circle var(--r) at var(--mx) var(--my),
      rgba(0, 0, 0, 0) 0,
      rgba(0, 0, 0, 0) calc(100% - var(--feather)),
      #000 100%);
  -webkit-mask-image: var(--lens);
          mask-image: var(--lens);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}

/* Centred legibility wash for the centred copy — a soft vignette that darkens
   toward the middle band where the text sits. */
.reveal__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 70% 55% at 50% 50%, rgba(16, 20, 12, 0.5) 0%, rgba(16, 20, 12, 0.12) 70%, rgba(16, 20, 12, 0) 100%),
    linear-gradient(to bottom, rgba(16, 20, 12, 0.28) 0%, rgba(16, 20, 12, 0) 30%, rgba(16, 20, 12, 0) 70%, rgba(16, 20, 12, 0.28) 100%);
}

/* A dark ring hugs the inner rim of the cut-out — depth in place of blur. */
.reveal__glow {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(circle var(--r) at var(--mx) var(--my),
      rgba(0, 0, 0, 0) calc(100% - 22px),
      rgba(14, 18, 10, 0.5) 100%);
}

.reveal__inner {
  position: relative;
  z-index: 3;
  /* The stage minus the bleed: the bleed strip runs on under the next
     section's curve and is not part of what the reader sees, so centring in
     the full stage would push the copy low by half of it. */
  block-size: calc(100% - var(--bleed));
  display: grid;
  align-content: center;
  justify-items: center;
  padding-inline: var(--gutter);
  padding-block: clamp(3rem, 10vh, 7rem);
  max-inline-size: var(--w-max);
  margin-inline: auto;
  inline-size: 100%;
}

.reveal__copy {
  max-inline-size: 60ch;
  display: grid;
  justify-items: center;
  gap: var(--u-4);
  text-align: center;
  text-shadow: 0 1px 22px rgba(10, 14, 8, 0.5);
}

.reveal__label {
  color: rgb(255 255 255 / 0.85);
  margin-block-end: var(--u-3);
}

/* The title leads (large, display weight); the text below it is the
   quieter explanation — same headline/answer hierarchy as the closing CTA. */
.reveal__message {
  font-family: var(--font-display);
  font-size: clamp(1.875rem, 1.2rem + 2.6vw, 3.25rem);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  line-height: 1.15;
  color: #fff;
  text-wrap: balance;
}

.reveal__text {
  max-inline-size: 52ch;
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  color: rgb(255 255 255 / 0.88);
  text-wrap: pretty;
}

/* Everything else is one uniform body size — no competing tiers. */
.reveal__body {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: rgb(255 255 255 / 0.88);
}

/* Touch / no hover: no cursor, so the reveal is a scroll crossfade. */
@media (hover: none), (pointer: coarse) {
  /* .reveal.furrow-top (below, at equal specificity but declared earlier)
     sets its own block-size for the full-bleed desktop layout; matching its
     specificity here is what lets this actually win on touch. Getting this
     wrong left the section barely taller than one viewport, so the entire
     scroll crossfade fired within ~40px of scroll — jarringly fast. */
  .reveal.furrow-top {
    /* One swipe, not two: the scrim and copy have to land inside a single
       flick, so the scroll runway stays close to one viewport. */
    block-size: calc(150svh + var(--bleed));
  }
  /* At 200svh tall, furrow-top's 0.055 notch (a fraction of this element's
     own height) cuts a much deeper corner than intended, exposing a large
     wedge of the section above. Swap in the scaled-down variant. */
  .reveal.furrow-top {
    clip-path: url(#furrow-top-shallow);
  }
  /* The before/after crossfade read as too aggressive on a small screen —
     just show the planned neighbourhood throughout, and let the copy land
     on top of it as the reader scrolls in. */
  /* Sticky again here, and only here: on touch the reveal IS scroll-driven, so
     the stage has to hold still for the length of the section while --reveal
     runs from 0 to 1. */
  .reveal__stage {
    /* inset:auto first — the desktop rule sets all four, and a sticky element
       with a bottom constraint pins against the wrong edge. */
    position: sticky;
    inset: auto;
    inset-block-start: 0;
    block-size: 100lvh;
    /* Sticky stops at its containing block's CONTENT edge, which left the same
       139px seam as on desktop: the strip below it fell through to the
       section's background-image — the same photograph at a different crop,
       meeting the stage along a straight line just above the curve. A negative
       bottom margin buys the stage exactly that much more travel, so it comes
       to rest flush with the padding box instead. */
    margin-block-end: calc(-1 * var(--bleed));
  }
  .reveal__inner {
    block-size: 100lvh;
  }
  .reveal__img--before {
    display: none;
  }
  .reveal__scrim {
    background: rgba(16, 20, 12, 0.56);
    opacity: clamp(0, calc(var(--reveal) / 0.25), 1);
  }
  .reveal__copy {
    opacity: clamp(0, calc((var(--reveal) - 0.12) / 0.3), 1);
    translate: 0 calc((1 - clamp(0, calc((var(--reveal) - 0.12) / 0.3), 1)) * 16px);
  }
  .reveal__glow { display: none; }
}

/* --- Values ----------------------------------------------------------------
   The one horizontal moment on the site. The reader still scrolls down; the
   track translates sideways in response. No scroll hijacking.
   -------------------------------------------------------------------------- */

/* Static one-screen grid — no pin, no scrub. Extra bottom padding offsets the
   next section's furrow pull-up, so the top and bottom overlap curves read with
   equal breathing room. */
.values {
  padding-block: var(--u-10);
}

/* The furrow's notch is proportionally deeper against a narrow screen, so the
   title needs more clearance under it before it starts reading as crowded by
   the section above. */

/* Sized close to the card titles so the section reads as one family, not a
   giant header over small cards. */
.values__title {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
  margin-block-end: var(--u-6);
  text-align: center;
}

.values__grid {
  display: grid;
  gap: var(--u-4);
  grid-template-columns: 1fr;
}

.value {
  display: grid;
  align-content: start;
  gap: var(--u-2);
  padding: var(--u-5);
  background: var(--paper);
  border: 1px solid var(--t-line);
  border-radius: var(--r-md);
}

/* The redesigned marks are flat, filled SVGs (green on cream). */
.value__icon {
  inline-size: 34px;
  block-size: 34px;
  margin-block-end: var(--u-1);
}

.value__title {
  font-size: var(--fs-body);
  font-weight: var(--fw-body-strong);
}

.value__desc {
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--t-muted);
}

/* --- Statement ------------------------------------------------------------- */

.statement {
  position: relative;
  display: grid;
  align-items: center;
  min-block-size: clamp(560px, 88vh, 900px);
  /* Top padding clears the fixed nav so the manifesto is never sitting
     underneath it when the section comes to rest. */
  padding-block: calc(var(--u-9) + var(--u-6)) var(--u-9);
  overflow: hidden;
}

/* Specificity has to match .section.has-bleed (0,2,0) or the generic bleed
   padding wins and the section loses its own bottom padding. */
.section.statement,
.section.cta {
  padding-block-end: calc(var(--u-9) + var(--bleed, 0px));
}

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

.statement__media img {
  inline-size: 100%;
  block-size: 118%;
  object-fit: cover;
}

.statement__scrim {
  position: absolute;
  inset: 0;
  background: rgb(35 31 32 / 0.5);
}

.statement__inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--u-6);
  color: #fff;
}

.statement__title {
  font-size: var(--fs-act);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  line-height: 1.1;
}

/* --- Statement CTA — the invitation that closes the manifesto -------------- */

/* Question, then invitation, then the button — all centred on the separator
   line rather than split into a text-left/button-right row, which stopped
   working once the title became two lines instead of one. */
.statement__cta {
  display: grid;
  justify-items: center;
  gap: var(--u-5);
  text-align: center;
}

.statement__cta-title {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
  line-height: var(--lh-heading);
}

/* On the dark statement image the button reads as light. */
.statement__cta .btn {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--paper);
}
.statement__cta .btn:hover {
  background: var(--field);
  color: var(--paper);
  border-color: var(--field);
}

/* Two-up on tablets, so five compact cards don't stack into a tall column. */
@media (min-width: 620px) and (max-width: 991px) {
  .values__grid {
    grid-template-columns: 1fr 1fr;
  }
}

/* ==========================================================================
   Desktop — pins get their scroll length, layouts go two-column
   ========================================================================== */

@media (min-width: 992px) {
  /* One viewport. The hero used to run two viewports so the footage could be
     scroll-scrubbed, but the scrub encode (home-hero-scrub.mp4) does not exist
     yet, so that second viewport was just empty dark ink between the hero and
     the story. A single viewport removes the gap; when the scrub clip is
     produced, restore `--act-scroll: 2` + the sticky media/inner rules and
     hero.js will pick the scrub source up again. */
  .hero {
    --act-scroll: 1;
    min-block-size: var(--svh);
  }

  .act__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
    gap: var(--u-9);
  }

  .act__grid--reverse {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  }

  .act__grid--reverse .act__figure {
    order: 2;
  }

  /* All five values in one row, on one screen. */
  .values__grid {
    grid-template-columns: repeat(5, 1fr);
    gap: var(--u-4);
  }
}

@media (min-width: 1400px) {
  .value {
    flex-basis: 460px;
  }
}

/* ==========================================================================
   Mobile — no pins, no horizontal, no parallax
   ========================================================================== */

@media (max-width: 991px) {
  .act__inner {
    position: relative;
    min-block-size: 0;
    padding-block: var(--u-9) var(--u-8);
  }

  .act__foot {
    display: none;
  }

  .act__grid {
    gap: var(--u-6);
  }

  .statement__media img {
    block-size: 100%;
  }
}

@media (max-width: 640px) {
  .hero__inner {
    padding-block-end: var(--u-6);
    gap: var(--u-6);
  }

  /* Mobile, per the Figma mock: soil is the dominant pile (wider), rock the
     smaller one, overlapping at centre. Each source photo is naturally dense
     on one side and scatters toward the other — soil dense-LEFT/scatter-RIGHT,
     rock dense-RIGHT/scatter-LEFT — so cropping toward each one's own dense
     side (object-position) already meets correctly in the middle. No mirror
     needed; the earlier attempt had both the crop side and a scaleX flip
     working against each other. */
  .roots__scene {
    block-size: clamp(400px, 92vw, 580px);
    margin-block-start: calc(-1 * var(--u-9));
  }
  .roots__head { gap: var(--u-2); }
  .roots__pile {
    block-size: 92%;
    object-fit: cover;
  }
  .roots__pile--soil {
    inset-inline-end: -14%;
    inline-size: 104%;
    /* The dense pile is the source's left ~60%; the loose, dispersed dust
       that should read in the overlap sits from ~60% to ~85%. Crop toward
       that edge rather than the flat dense face, but not so far that the
       overlap band under the labels is mostly transparent dust. */
    object-position: 74% center;
  }
  .roots__pile--rock {
    inset-inline-start: -14%;
    inline-size: 80%;
    /* Mirror logic: rock's dust tapers off across its left ~15%-45%. */
    object-position: 26% center;
  }
  .roots__labels { gap: var(--u-5); inset-block-end: 26%; }
  .roots__label { text-align: center; justify-items: center; }
  .roots__desc { max-inline-size: 13ch; margin-inline: auto; }

  .value {
    padding: var(--u-5);
  }
}

/* ==========================================================================
   Urban renewal page
   ========================================================================== */

/* --- Page hero ------------------------------------------------------------- */

.phero {
  position: relative;
  display: grid;
  align-items: end;
  /* Full viewport, matching the home hero — a shorter box (this used to clamp
     at 78vh) left a large flat run of the next section's background showing
     below the furrow's small notch, instead of the curve doing the work. */
  min-block-size: var(--svh);
  color: #fff;
  background: var(--ink);
  overflow: hidden;
}

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

.phero__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.phero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgb(35 31 32 / 0.5) 0%,
    rgb(35 31 32 / 0.2) 40%,
    rgb(35 31 32 / 0.6) 100%
  );
}

.phero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--u-4);
  padding-block: calc(var(--u-9) + var(--u-6)) var(--u-7);
}

.phero__title {
  font-size: var(--fs-act);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  line-height: 1.02;
}

.phero__sub {
  font-size: var(--fs-lead);
  color: rgb(255 255 255 / 0.85);
}

.phero .cue {
  color: #fff;
}

/* --- Section video --------------------------------------------------------- */

/* Full-bleed: the floating .furrow-band handles the curve + overlap at both
   edges (see furrow.css), so this section only needs a height and to let the
   stage cover it edge to edge regardless of the band's own padding. */
.vid {
  position: relative;
  min-block-size: clamp(360px, 56vw, 720px);
  overflow: hidden;
}

.vid__stage {
  position: absolute;
  inset: 0;
}

.vid__el {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* Source footage has ~6% black pillarboxing baked into each side; scale
     past it so the crop never shows the encoded black bars. */
  transform: scale(1.16);
}

.vid__controls {
  position: absolute;
  inset-block-end: var(--gutter);
  inset-inline-end: var(--gutter);
  display: flex;
  gap: var(--u-2);
}

.vid__btn {
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  border-radius: var(--r-pill);
  background: rgb(35 31 32 / 0.62);
  color: #fff;
  transition: background var(--dur-s) var(--ease-out);
}

.vid__btn:hover {
  background: rgb(35 31 32 / 0.85);
}

.vid__btn .icon {
  inline-size: 18px;
  block-size: 18px;
}

/* --- How we work ----------------------------------------------------------- */

.approach-intro {
  padding-block: var(--u-10);
}

/* --- One body scale across the page ---------------------------------------
   These sections had a mix of .lead and plain paragraphs, so the same kind of
   copy changed size from one section to the next. They all read at the larger
   scale now, with one rhythm between paragraphs.
   -------------------------------------------------------------------------- */
.intro .prose p,
.approach-intro .prose p,
.owners .prose p,
.faq__lead,
.faq__a p {
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
}

.intro .prose p + p,
.approach-intro .prose p + p,
.owners .prose p + p,
.approach-intro .prose h2 + p,
.intro .prose h2 + p,
.owners .prose h2 + p {
  margin-block-start: var(--u-5);
}

/* --- The four steps -------------------------------------------------------- */

/* A section's own padding-block shorthand fully overrides .furrow-top's
   padding-block-start (same specificity, later in the cascade) — so the
   furrow's clip clearance never actually adds on top of this; generous,
   symmetric padding is what gives these sections room to breathe. */
.intro {
  padding-block: var(--u-10);
}

.steps {
  padding-block: var(--u-10);
}

.steps__title {
  max-inline-size: var(--w-text);
  margin-inline: auto;
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
  margin-block-end: var(--u-6);
}

.steps__list {
  display: grid;
  gap: var(--u-4);
  max-inline-size: var(--w-text);
  margin-inline: auto;
}

.step {
  display: grid;
  align-content: start;
  gap: var(--u-2);
  padding: var(--u-5);
  background: var(--paper);
  border: 1px solid var(--t-line);
  border-radius: var(--r-md);
}

/* Filled chip in brand green with the mark in negative white — matching the
   home page's filled icon style rather than thin outlines. */
.step__icon {
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  margin-block-end: var(--u-2);
  border-radius: var(--r-sm);
  background: var(--field);
}
.step__icon svg {
  inline-size: 22px;
  block-size: 22px;
  color: #fff;              /* symbols' fill="currentColor" parts read white */
  fill: none;
  stroke: #fff;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.step__title {
  font-size: var(--fs-body);
  font-weight: var(--fw-body-strong);
}

.step__desc {
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--t-muted);
}

/* --- Note ------------------------------------------------------------------ */

.note {
  padding-block: var(--u-10);
}

.note__text {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-heading);
  line-height: 1.35;
  letter-spacing: var(--ls-heading);
  text-align: center;
}

/* --- Owners ---------------------------------------------------------------- */

.owners {
  padding-block: var(--u-10);
}

/* --- FAQ ------------------------------------------------------------------- */

.faq {
  padding-block: var(--u-10);
}

.faq__lead {
  margin-block-start: var(--u-4);
  color: var(--t-muted);
}

/* Matches the --w-text column every other section's paragraphs sit in — left
   at full container width, the questions ran edge to edge of the wider 1200px
   container while the prose beside it looked comparatively inset. */
.faq__list {
  max-inline-size: var(--w-text);
  margin-inline: auto;
  margin-block-start: var(--u-8);
  border-block-start: 1px solid var(--t-line);
}

.faq__item {
  border-block-end: 1px solid var(--t-line);
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--u-5);
  inline-size: 100%;
  padding-block: var(--u-4);
  font-family: var(--font-display);
  font-size: var(--fs-lead);
  font-weight: var(--fw-body-strong);
  letter-spacing: var(--ls-heading);
  line-height: 1.35;
  text-align: start;
  color: var(--t-fg);
  transition: color var(--dur-s) var(--ease-out);
}

.faq__q:hover {
  color: var(--field-ink);
}

.faq__mark {
  flex: 0 0 auto;
  inline-size: 20px;
  block-size: 20px;
  transition: transform var(--dur-m) var(--ease-out);
}

/* The plus loses its vertical bar when open, becoming a minus. */
.faq__item.is-open .faq__mark .icon__bar {
  opacity: 0;
}

.faq__item.is-open .faq__mark {
  transform: rotate(180deg);
}

.faq__a {
  overflow: hidden;
}

.faq__a p {
  max-inline-size: var(--w-text);
  padding-block-end: var(--u-6);
  color: var(--t-muted);
}

/* --- CTA — closing invitation, on an urban photo ---------------------------
   Full-bleed image with a scrim; the furrow clip needs the section's own top
   padding dropped, same as the other furrow-top text sections above. */
.cta {
  position: relative;
  display: grid;
  place-items: center;
  min-block-size: clamp(360px, 42vw, 560px);
  padding-block: var(--u-9);
  color: #fff;
  overflow: hidden;
}

.cta__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.cta__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  /* Anchored to the top of the frame. This band is much wider than the
     source is tall, so the crop has to give up one end; holding the top keeps
     the buildings' upper floors and roofline in shot instead of cutting them
     off at mid-height. */
  object-position: center top;
}
.cta__scrim {
  position: absolute;
  inset: 0;
  background: rgb(35 31 32 / 0.62);
}

.cta__inner {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: var(--u-6);
  max-inline-size: 640px;
  text-align: center;
}

.cta__title {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
  line-height: 1.3;
  text-wrap: normal;
}

/* Question, then the answer — each its own row regardless of how either
   sentence would otherwise wrap at this width. */
.cta__title-row {
  display: block;
}

.cta .btn {
  background: #fff;
  color: var(--ink);
  border-color: #fff;
}
.cta .btn:hover {
  background: var(--field);
  color: #fff;
  border-color: var(--field);
}

@media (min-width: 992px) {
  /* Four across at full width; they fade in together on entry. */
  .steps__list {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--u-4);
  }
}

/* ==========================================================================
   Contact page
   ========================================================================== */

.contact {
  min-block-size: 100vh;
}

.contact__grid {
  display: grid;
}

.contact__form-side {
  padding-block: calc(var(--u-9) + var(--u-6)) var(--u-9);
  padding-inline: var(--gutter);
}

.contact__inner {
  inline-size: min(100%, 620px);
  margin-inline: auto;
}

.contact__mark {
  display: block;
  inline-size: 64px;
  margin-block-end: var(--u-5);
}

.contact__head .lead {
  margin-block-start: var(--u-4);
  color: var(--t-muted);
}

/* --- Form ------------------------------------------------------------------ */

.form {
  display: grid;
  gap: var(--u-5);
  margin-block-start: var(--u-8);
}

.form__row {
  display: grid;
  gap: var(--u-5);
}

.field {
  display: grid;
  gap: var(--u-2);
}

.field label {
  font-size: var(--fs-small);
  font-weight: var(--fw-body-strong);
}

.field input,
.field select,
.field textarea {
  inline-size: 100%;
  min-block-size: 48px;
  padding: var(--u-3) var(--u-4);
  /* Not --surface: that token carries the alternating section shade, which is
     deep enough to read as a filled-in field rather than an empty one. */
  background: #fffdf7;
  border: 1px solid var(--ink-30);
  border-radius: var(--r-sm);
  color: var(--ink);
  transition: border-color var(--dur-s) var(--ease-out);
}

/* The native control drops its arrow hard against the inline-start edge in
   RTL. Own the chevron so it can sit in from the edge with the text clear
   of it. */
.field select {
  appearance: none;
  -webkit-appearance: none;
  padding-inline-end: var(--u-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23231f20' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  /* padding-inline-end follows the writing direction on its own, but
     background-position does not — so the chevron's side is set per
     direction, and the clearance above always lands under it. */
  background-position: right var(--u-4) center;
  background-size: 18px 18px;
}

[dir="rtl"] .field select {
  background-position: left var(--u-4) center;
}

.field textarea {
  min-block-size: 120px;
  resize: vertical;
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  border-color: var(--field);
  outline-color: var(--field);
}

/* Errors are text, never colour alone. */
.field__error {
  font-size: var(--fs-small);
  color: var(--error);
}

.field__error:empty {
  display: none;
}

.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea {
  border-color: var(--error);
}

.field--check {
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: var(--u-3);
}

.field--check input {
  inline-size: 24px;
  min-block-size: 24px;
  block-size: 24px;
  margin-block-start: 0;
  accent-color: var(--field);
}

.field--check label {
  font-weight: var(--fw-body);
  line-height: 1.5;
}

.form__summary {
  color: var(--error);
  font-size: var(--fs-small);
}

.form__summary:empty {
  display: none;
}

.form__summary.is-success {
  color: var(--success);
}

.form__notice {
  font-size: var(--fs-small);
  color: var(--t-muted);
}

.form__submit {
  justify-self: start;
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

.form__submit:hover {
  background: var(--field);
  border-color: var(--field);
  color: var(--paper);
}

/* --- Details aside --------------------------------------------------------- */

.contact__aside {
  position: relative;
  display: grid;
  align-content: center;
  min-block-size: clamp(360px, 50vh, 640px);
  padding: var(--u-9) var(--gutter);
  color: #fff;
  background: var(--ink);
  overflow: hidden;
}

.contact__aside-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.contact__aside-media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.contact__aside-scrim {
  position: absolute;
  inset: 0;
  background: rgb(35 31 32 / 0.68);
}

.contact__aside-inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--u-5);
}

.contact__list {
  display: grid;
  gap: var(--u-4);
}

.contact__list li {
  display: flex;
  align-items: center;
  gap: var(--u-3);
}

.contact__list .icon {
  flex: 0 0 auto;
  inline-size: 18px;
  block-size: 18px;
  opacity: 0.75;
}

.contact__list a {
  min-block-size: 24px;
  display: inline-flex;
  align-items: center;
  transition: color var(--dur-s) var(--ease-out);
}

.contact__list a:hover {
  color: var(--powder, #c8d6b4);
}

.contact__aside-note {
  font-size: var(--fs-small);
  color: rgb(255 255 255 / 0.75);
  line-height: 1.7;
}

@media (min-width: 768px) {
  .form__row {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 992px) {
  .contact__grid {
    grid-template-columns: 1.15fr 1fr;
    align-items: stretch;
  }

  .contact__aside {
    min-block-size: 100vh;
    position: sticky;
    inset-block-start: 0;
  }

  .contact__inner {
    margin-inline: 0 auto;
  }
}

/* ==========================================================================
   Legal pages (privacy, accessibility)
   Plain documents. They inherit the type and colour system so they do not look
   orphaned, but get none of the cinematic treatment — nobody wants a privacy
   policy that animates.
   ========================================================================== */

.legal {
  padding-block: calc(var(--u-9) + var(--u-6)) var(--u-9);
}

.legal .container {
  max-inline-size: var(--w-text);
}

.legal h1 {
  font-size: var(--fs-h2);
}

.legal h2 {
  margin-block-start: var(--u-7);
  margin-block-end: var(--u-3);
  font-size: var(--fs-h3);
}

/* One body size across the whole page — paragraphs, list items and the
   updated-on line all read at the same scale. */
.legal p,
.legal li {
  margin-block-start: var(--u-4);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--t-muted);
}

/* Marks the English legal pages as a courtesy translation — the Hebrew is the
   operative text, and a reader should not have to guess that. */
.legal__note {
  margin-block: var(--u-5);
  padding: var(--u-4) var(--u-5);
  border-inline-start: 3px solid var(--field);
  background: var(--ink-05);
  border-radius: var(--r-sm);
  color: var(--ink);
}

.legal__list {
  margin-block-start: var(--u-4);
}
.legal__list li {
  padding-inline-start: var(--u-4);
  position: relative;
}
.legal__list li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0.62em;
  inline-size: 5px;
  block-size: 5px;
  border-radius: 50%;
  background: var(--field);
}

.legal__back {
  display: inline-flex;
  align-items: center;
  gap: var(--u-2);
  margin-block-start: var(--u-8);
  color: var(--field-ink);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* ==========================================================================
   Projects — shared pieces (projects page, home section, rental page)
   ========================================================================== */

/* --- Hidden projects ---------------------------------------------------------
   A project marked data-project-hidden is built but not published. ?preview
   in the URL puts .is-preview on <html> (projects.js), which lets it show. */
html:not(.is-preview) [data-project-hidden] {
  display: none !important;
}

.preview-badge {
  display: none;
}

.is-preview .preview-badge {
  display: inline-flex;
  align-self: start;
  justify-self: start;
  padding: 2px var(--u-3);
  border: 1px dashed var(--earth-deep);
  border-radius: var(--r-pill);
  font-size: var(--fs-small);
  color: var(--earth-deep);
  background: var(--paper);
}

/* --- Status pill -------------------------------------------------------------
   The one piece of colour that answers "where does it stand?" at a glance:
   green while building, neutral while still in planning. */
.status {
  display: inline-flex;
  align-items: center;
  gap: var(--u-2);
  inline-size: fit-content;
  padding: var(--u-1) var(--u-3);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--stone-deep);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: var(--fw-label);
  line-height: 1.4;
  white-space: nowrap;
}

.status::before {
  content: "";
  inline-size: 7px;
  block-size: 7px;
  border-radius: 50%;
  background: currentColor;
}

.status--active {
  background: var(--success-bg);
  color: var(--success);
}

/* --- Cards ----------------------------------------------------------------- */

.pgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: var(--u-6);
}

.pcard {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr;
  block-size: 100%;
  overflow: hidden;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--ink-10);
  border-radius: var(--r-md);
  transition: box-shadow var(--dur-s) var(--ease-out),
    transform var(--dur-s) var(--ease-out);
}

.pcard:hover {
  box-shadow: 0 18px 40px -24px rgb(35 31 32 / 0.45);
  transform: translateY(-2px);
}

/* The title link stretches over the whole card, so the card still opens the
   project on a click anywhere — while a second link (the sign-up button) can
   sit on top of it without nesting one link inside another. */
.pcard__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

.pcard__link:focus-visible {
  outline: none;
}

.pcard:has(.pcard__link:focus-visible) {
  outline: 2px solid var(--field);
  outline-offset: 3px;
}

.pcard__media {
  position: relative;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: var(--surface);
}

.pcard__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform var(--dur-m) var(--ease-out);
}

.pcard:hover .pcard__media img {
  transform: scale(1.04);
}

.pcard__body > .status {
  position: absolute;
  inset-block-start: var(--u-4);
  inset-inline-start: var(--u-4);
  box-shadow: 0 2px 10px rgb(35 31 32 / 0.15);
}

.pcard__body > .status:not(.status--active) {
  background: var(--paper);
}

.pcard__body {
  display: flex;
  flex-direction: column;
  gap: var(--u-2);
  padding: var(--u-5);
}

.pcard__title {
  margin: 0;
  font-size: var(--fs-h3);
  color: var(--ink);
}

.pcard__place {
  color: var(--ink-60);
}

.pcard__type {
  font-weight: var(--fw-body-strong);
}

.pcard__scale {
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.pcard__more {
  display: inline-flex;
  align-items: center;
  gap: var(--u-2);
  margin-block-start: var(--u-3);
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: var(--fw-label);
  letter-spacing: 0.06em;
  color: var(--field-ink);
}

/* Pinned to the bottom of the card at one fixed height — the height of the
   sign-up button — so a card with only "learn more" lines up with one that
   has both. */
.pcard__actions {
  display: flex;
  align-items: center;
  gap: var(--u-5);
  min-block-size: calc(50px + var(--u-3));
  margin-block-start: auto;
  padding-block-start: var(--u-3);
}

.pcard__actions .pcard__more {
  margin-block-start: 0;
}

.pcard__cta {
  position: relative;
  z-index: 2;
  flex: none;
  padding: var(--u-3) var(--u-5);
  white-space: nowrap;
}

.pcard__more {
  flex: none;
  white-space: nowrap;
}

/* Keeps both on one row down to ~360px; below that they stack rather than
   overflow the card. */
@media (max-width: 640px) {
  .pcard__actions {
    flex-wrap: wrap;
    gap: var(--u-3) var(--u-4);
  }

  .pcard__cta {
    padding-inline: var(--u-4);
    letter-spacing: 0.04em;
  }
}

.pcard__more .icon {
  inline-size: 16px;
  block-size: 16px;
  transform: scaleX(var(--flip));
  transition: translate var(--dur-s) var(--ease-out);
}

.pcard:hover .pcard__more .icon {
  translate: calc(-4px * var(--flip)) 0;
}

/* --- Gallery ----------------------------------------------------------------
   A scroll-snap track: swipe is native on touch, the buttons and arrow keys
   step it (projects.js). Every image fills the frame — letterboxing read as
   a mistake — and 3:2 keeps the square renders from losing too much. */
.gallery {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--ink);
  color: #fff;
}

.gallery__track {
  display: flex;
  /* Width is pinned to the frame: with an auto width, aspect-ratio would
     carry the height cap across into a narrower track, leaving the dark
     .gallery background showing beside it on short screens. The cap then
     just makes the frame wider than 3:2, and cover crops to fit. */
  inline-size: 100%;
  aspect-ratio: 3 / 2;
  max-block-size: 76vh;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.gallery__track::-webkit-scrollbar {
  display: none;
}

.gallery__track:focus-visible {
  outline: 2px solid #fff;
  outline-offset: -4px;
}

.gallery__slide {
  position: relative;
  flex: 0 0 100%;
  margin: 0;
  scroll-snap-align: start;
}

.gallery__slide img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.gallery__btn {
  position: absolute;
  inset-block-start: 50%;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  inline-size: 56px;
  block-size: 56px;
  border-radius: var(--r-pill);
  background: rgb(255 252 244 / 0.92);
  color: var(--ink);
  box-shadow: 0 6px 20px rgb(35 31 32 / 0.28);
  transition: background var(--dur-s) var(--ease-out),
    transform var(--dur-s) var(--ease-out);
}

.gallery__btn:hover {
  background: var(--paper);
  transform: scale(1.06);
}

.gallery__btn .icon {
  inline-size: 26px;
  block-size: 26px;
  stroke-width: 2;
}

/* The chevron glyph points left. "Previous" sits at the inline-start and
   points toward it; "next" points toward the inline-end. */
.gallery__btn--prev {
  inset-inline-start: var(--u-4);
}

.gallery__btn--prev .icon {
  transform: scaleX(calc(-1 * var(--flip)));
}

.gallery__btn--next {
  inset-inline-end: var(--u-4);
}

.gallery__btn--next .icon {
  transform: scaleX(var(--flip));
}

/* direction: ltr keeps "2 / 5" in reading order, but it would also flip a
   logical inset onto the wrong side in RTL — so the corner is set
   physically, per page direction. */
.gallery__count {
  position: absolute;
  inset-block-end: var(--u-3);
  right: var(--u-3);
  padding: var(--u-1) var(--u-3);
  border-radius: var(--r-pill);
  background: rgb(35 31 32 / 0.55);
  font-size: var(--fs-small);
  direction: ltr;
  unicode-bidi: isolate;
}

[dir="rtl"] .gallery__count {
  right: auto;
  left: var(--u-3);
}

.gallery__play {
  position: absolute;
  inset-block-end: var(--u-3);
  inset-inline-start: var(--u-3);
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  border-radius: var(--r-pill);
  background: rgb(35 31 32 / 0.55);
  color: #fff;
  transition: background var(--dur-s) var(--ease-out);
}

.gallery__play:hover {
  background: rgb(35 31 32 / 0.85);
}

.gallery__play .icon {
  inline-size: 14px;
  block-size: 14px;
  fill: currentColor;
  stroke: none;
}

.gallery.is-single .gallery__btn,
.gallery.is-single .gallery__count,
.gallery.is-single .gallery__play {
  display: none;
}

@media (max-width: 640px) {
  .gallery__btn {
    inline-size: 44px;
    block-size: 44px;
  }

  .gallery__btn .icon {
    inline-size: 22px;
    block-size: 22px;
  }

  .gallery__btn--prev {
    inset-inline-start: var(--u-2);
  }

  .gallery__btn--next {
    inset-inline-end: var(--u-2);
  }
}

/* --- Facts list -------------------------------------------------------------
   A <dl>, read as label → value rows. Not a table: there's only ever one
   column of values, and rows stack cleanly on a phone. */
.facts {
  display: grid;
  border-block-end: 1px solid var(--t-line);
}

.facts > div {
  display: grid;
  gap: var(--u-1) var(--u-5);
  padding-block: var(--u-4);
  border-block-start: 1px solid var(--t-line);
}

.facts dt {
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: var(--fw-label);
  color: var(--t-muted);
}

@media (min-width: 640px) {
  .facts > div {
    grid-template-columns: 10rem 1fr;
  }
}

/* --- Solid button ------------------------------------------------------------ */

.btn--solid {
  background: var(--field);
  border-color: var(--field);
  color: var(--paper);
}

.btn--solid:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

/* Placeholder copy awaiting the real text. */
.tbd {
  color: var(--earth-deep);
}

/* ==========================================================================
   Projects page
   ========================================================================== */

.plist {
  padding-block: var(--u-10);
}

.plist__head {
  max-inline-size: var(--w-text);
  margin-block-end: var(--u-8);
}

.plist__head p {
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
}

html.has-dialog {
  overflow: hidden;
}

/* --- Popup -------------------------------------------------------------------
   Fullscreen <dialog>: a slim top bar, the scrolling project, and the bar
   that moves between projects. */
.pdialog {
  --t-bg: var(--paper);
  --t-fg: var(--ink);
  --t-muted: var(--ink-60);
  --t-line: var(--ink-10);

  position: fixed;
  inset: 0;
  inline-size: 100%;
  max-inline-size: none;
  block-size: 100dvh;
  max-block-size: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--paper);
  color: var(--ink);
}

.pdialog[open] {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
}

.pdialog::backdrop {
  background: var(--ink);
}

.pdialog__top,
.pdialog__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--u-4);
  padding: var(--u-2) var(--gutter);
  padding-block-start: max(var(--u-2), env(safe-area-inset-top, 0px));
}

.pdialog__top {
  border-block-end: 1px solid var(--ink-10);
}

.pdialog__close {
  display: grid;
  place-items: center;
  border-radius: var(--r-pill);
  transition: background var(--dur-s) var(--ease-out);
}

.pdialog__close:hover {
  background: var(--ink-05);
}

.pdialog__close .icon {
  inline-size: 24px;
  block-size: 24px;
}

.pdialog__body {
  overflow-y: auto;
  overscroll-behavior: contain;
}

.pdialog__nav {
  padding-block: var(--u-2) max(var(--u-2), env(safe-area-inset-bottom, 0px));
  border-block-start: 1px solid var(--ink-10);
  background: var(--surface);
}

.pdialog__step {
  display: inline-flex;
  align-items: center;
  gap: var(--u-3);
  max-inline-size: 48%;
  padding: var(--u-2) var(--u-3);
  border-radius: var(--r-sm);
  text-align: start;
  transition: background var(--dur-s) var(--ease-out);
}

.pdialog__step:hover {
  background: var(--ink-05);
}

.pdialog__step[hidden] {
  display: none;
}

.pdialog__step--next {
  margin-inline-start: auto;
  flex-direction: row-reverse;
  text-align: end;
}

.pdialog__step .icon {
  flex: none;
  inline-size: 20px;
  block-size: 20px;
}

.pdialog__step--prev .icon {
  transform: scaleX(calc(-1 * var(--flip)));
}

.pdialog__step--next .icon {
  transform: scaleX(var(--flip));
}

.pdialog__step-text {
  display: grid;
  gap: 2px;
  min-inline-size: 0;
}

.pdialog__dir {
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.pdialog__name {
  overflow: hidden;
  font-family: var(--font-display);
  font-weight: var(--fw-heading);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- One project ------------------------------------------------------------ */

.project {
  inline-size: min(100% - (2 * var(--gutter)), 1100px);
  margin-inline: auto;
  padding-block: var(--u-7) var(--u-9);
}

.project__head {
  display: grid;
  gap: var(--u-3);
}

.project__type {
  color: var(--field-ink);
}

.project__title {
  margin: 0;
  font-size: clamp(2rem, 1.4rem + 2.4vw, 3.25rem);
  font-weight: var(--fw-display);
  line-height: 1.05;
  color: var(--ink);
}

.project__tag {
  display: inline-block;
  margin-inline-start: var(--u-2);
  padding: 2px var(--u-3);
  border: 1px solid var(--ink-30);
  border-radius: var(--r-pill);
  font-size: var(--fs-small);
  font-weight: var(--fw-label);
  vertical-align: middle;
  color: var(--ink-60);
}

.project__sub {
  font-size: var(--fs-lead);
  color: var(--ink-60);
}

/* At a glance: location, size, status — and what the visitor can do. */
.glance {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--u-5) var(--u-7);
  margin-block: var(--u-6);
  padding-block: var(--u-5);
  border-block: 1px solid var(--ink-10);
}

.glance dl {
  display: flex;
  flex-wrap: wrap;
  gap: var(--u-4) var(--u-7);
}

.glance dt {
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.glance dd {
  font-family: var(--font-display);
  font-size: var(--fs-lead);
  font-weight: var(--fw-heading);
}

.glance .btn {
  margin-inline-start: auto;
}

/* The Shaviv announcement is an image of an official order; this is the same
   text as text, for screen readers and anyone who cannot read the image. */
.announce {
  margin-block-end: var(--u-6);
}

.announce summary {
  cursor: pointer;
  color: var(--field-ink);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.announce__text {
  margin-block-start: var(--u-4);
  font-size: var(--fs-small);
  line-height: 1.7;
}

.announce__text h3,
.announce__text h4 {
  margin-block: var(--u-4) var(--u-2);
  font-size: var(--fs-body);
  font-weight: var(--fw-body-strong);
}

.announce__text p {
  margin-block-end: var(--u-2);
}

.announce__text table {
  inline-size: 100%;
  border-collapse: collapse;
}

.announce__text th,
.announce__text td {
  padding: var(--u-2);
  border: 1px solid var(--ink-10);
  text-align: start;
  vertical-align: top;
}

.project__body {
  display: grid;
  gap: var(--u-7);
  margin-block-start: var(--u-7);
}

.project__text p {
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
}

.project__text p + p {
  margin-block-start: var(--u-4);
}

.project__facts-title {
  margin: 0 0 var(--u-4);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  color: var(--ink-60);
}

@media (min-width: 960px) {
  .project__body {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: var(--u-8);
  }
}

@media (max-width: 640px) {
  .glance .btn {
    margin-inline-start: 0;
  }

  .pdialog__dir {
    font-size: 0.75rem;
  }
}

/* ==========================================================================
   Home — projects section
   ========================================================================== */

.hprojects {
  padding-block: var(--u-10);
}

.hprojects__head {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: var(--u-4);
  margin-block-end: var(--u-7);
}

.hprojects__title {
  margin: 0;
  font-size: var(--fs-h2);
  color: var(--ink);
}

/* On a phone the "all projects" button follows the cards instead of sitting
   under the heading: the head dissolves (display: contents) so its button
   can be ordered after the grid. */
@media (max-width: 640px) {
  .hprojects .container {
    display: flex;
    flex-direction: column;
  }

  .hprojects__head {
    display: contents;
  }

  .hprojects__title {
    margin-block-end: var(--u-6);
  }

  .hprojects .pgrid {
    order: 1;
  }

  .hprojects__head .btn {
    order: 2;
    align-self: center;
    margin-block-start: var(--u-7);
  }
}

/* ==========================================================================
   Long-term rental page
   ========================================================================== */

.rsec {
  padding-block: var(--u-10);
}

.rsec p {
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
}

.rsec p + p {
  margin-block-start: var(--u-5);
}

.rsec__name {
  margin-block-end: var(--u-2);
  color: var(--field-ink);
}

.rsec__title {
  margin: 0 0 var(--u-6);
  font-size: var(--fs-h2);
  color: var(--ink);
}

.rsec__subtitle {
  margin: 0 0 var(--u-5);
  font-size: var(--fs-h3);
  color: var(--ink);
}

.rsec .gallery {
  margin-block: var(--u-7);
}

/* --- Updates band ------------------------------------------------------------ */

.updates {
  padding-block: var(--u-10);
  scroll-margin-block-start: var(--u-8);
}

.field--check .field__error {
  grid-column: 1 / -1;
}

.updates__grid {
  display: grid;
  gap: var(--u-7);
  align-items: start;
}

.updates__title {
  margin: 0;
  font-size: var(--fs-h2);
  color: var(--paper);
}

.updates__ask {
  margin-block-start: var(--u-4);
  font-size: var(--fs-lead);
  font-weight: var(--fw-body-strong);
}

/* The form sits on a paper card, so it reads with the site's standard field
   styling rather than being restyled for green. */
.updates__card {
  --t-fg: var(--ink);
  --t-muted: var(--ink-60);
  --t-line: var(--ink-10);

  padding: clamp(var(--u-5), 4vw, var(--u-7));
  border-radius: var(--r-md);
  background: var(--paper);
  color: var(--ink);
}

.updates__card .form {
  margin-block-start: 0;
}

.updates__note {
  margin-block-start: var(--u-5);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

@media (min-width: 960px) {
  .updates__grid {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    gap: var(--u-9);
  }
}

/* Replaces a form once it has been sent (form.js, data-success). */
.form__done {
  padding: var(--u-6);
  border-radius: var(--r-sm);
  background: var(--success-bg);
  color: var(--success);
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-heading);
  line-height: 1.35;
}

/* ==========================================================================
   Breadcrumbs — inner pages
   Desktop: the full trail above the page title. Phone: only the parent, as
   a back link, which is all a small screen needs.
   ========================================================================== */

.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--u-2);
  font-family: var(--font-display);
  font-size: var(--fs-label);
  font-weight: var(--fw-label);
  color: var(--t-muted);
}

.crumbs li {
  display: flex;
  align-items: center;
  gap: var(--u-2);
}

.crumbs li + li::before {
  content: "/";
  opacity: 0.6;
}

.crumbs a {
  display: inline-flex;
  align-items: center;
  gap: var(--u-1);
  min-inline-size: 0;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 0.25em;
  transition: color var(--dur-s) var(--ease-out),
    text-decoration-color var(--dur-s) var(--ease-out);
}

.crumbs a:hover {
  color: var(--t-fg);
  text-decoration-color: currentColor;
}

.crumbs [aria-current="page"] {
  color: var(--t-fg);
}

/* The back chevron points against the reading direction. */
.crumbs__back {
  display: none;
  inline-size: 18px;
  block-size: 18px;
  transform: scaleX(calc(-1 * var(--flip)));
}

@media (max-width: 640px) {
  .crumbs li:last-child {
    display: none;
  }

  .crumbs__back {
    display: block;
  }
}

/* ==========================================================================
   "For illustration only" tags
   On every image that depicts a project — renders, the marked aerial photo,
   the draft plan — so the notice is seen with the image itself (a footer
   line alone sits too far from it). White text on a dark translucent chip:
   a shadow alone measured 2.2-2.7:1 over sky and white façades, and small
   text needs 4.5:1 whatever the image behind it is.
   ========================================================================== */

.illus {
  position: absolute;
  z-index: 1;
  color: #fff;
  font-size: 0.8125rem;
  font-weight: var(--fw-body);
  line-height: 1.4;
  padding: 0.15em 0.5em;
  border-radius: 4px;
  background: rgb(35 31 32 / 0.7);
  pointer-events: none;
}

.gallery__slide .illus {
  inset-block-start: var(--u-3);
  inset-inline-start: var(--u-3);
}

/* Cards: opposite corner from the status pill. */
.pcard__media .illus {
  inset-block-start: var(--u-4);
  inset-inline-end: var(--u-4);
}

/* Full-bleed heroes and the home statement: high on the inline-end side,
   clear of the fixed nav and of the next section's furrow overlap. */
.phero .illus,
.statement .illus {
  inset-block-start: calc(var(--nav-logo-h) + var(--u-8));
  inset-inline-end: var(--gutter);
}

/* ==========================================================================
   About page — family & leadership
   ========================================================================== */

.team {
  padding-block: var(--u-10);
}

/* Founders: one large feature, photo beside the text. */
.founders {
  display: grid;
  gap: var(--u-6);
  align-items: center;
  margin-block-end: var(--u-9);
}

.founders__photo {
  margin: 0;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: var(--r-md);
  box-shadow: 0 24px 48px -32px rgb(35 31 32 / 0.45);
}

.founders__photo img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.founders__role {
  font-family: var(--font-display);
  font-size: var(--fs-label);
  font-weight: var(--fw-label);
  letter-spacing: var(--ls-label);
  color: var(--field-ink);
}

.founders__name {
  margin: var(--u-2) 0 0;
  font-size: var(--fs-act);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  line-height: 1.05;
  color: var(--ink);
}

.founders__line {
  max-inline-size: 34ch;
  margin-block-start: var(--u-5);
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  color: var(--ink-80);
}

@media (min-width: 860px) {
  .founders {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: var(--u-9);
  }
}

/* Leadership: one row of four in rank order; 2×2 on a phone. All four
   portraits share one 4:5 framing (see tools/build-images.py) on the same
   studio white, so they read as a set beside the founders' outdoor photo. */
.leaders {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--u-7) var(--u-4);
}

.leader {
  display: grid;
  align-content: start;
  gap: var(--u-1);
}

.leader__photo {
  margin-block-end: var(--u-3);
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: var(--r-md);
  background: #fff;
}

.leader__photo img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* Name above role: the name carries the weight; a professional title
   (עו״ד / רו״ח) follows the role after a bar. */
.leader__name {
  margin: 0;
  font-size: clamp(1.125rem, 1rem + 0.6vw, 1.5rem);
  font-weight: var(--fw-heading);
  line-height: 1.2;
  color: var(--ink);
}

.leader__role {
  font-size: var(--fs-small);
  line-height: 1.45;
  color: var(--stone-deep);
}

@media (min-width: 900px) {
  .leaders {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--u-6);
  }
}

/* ==========================================================================
   About page — one heading style for every section title
   Same size, weight, colour and centring, with the same space below, so the
   page reads as one rhythm instead of five different headings.
   ========================================================================== */

.section-title {
  margin: 0 0 var(--u-7);
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
  line-height: var(--lh-heading);
  color: var(--ink);
  text-align: center;
}

/* In the roots head the subtitle belongs to the heading group; the head's
   own gap spaces them. */
.roots__head .section-title {
  margin-block-end: 0;
}

/* --- About hero: the name itself ---------------------------------------------
   The About page opens on the roots composition (stone + earth) instead of a
   photograph. It fills the first screen: the head clears the fixed nav, the
   piles carry the lower half. */
.roots--hero {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-block-size: var(--svh);
  padding-block-start: calc(var(--nav-logo-h) + 2 * var(--u-4) + var(--u-8));
}

/* Breadcrumbs sit at the page edge just under the logo, out of the centred
   title group, so they read as navigation rather than as part of the title. */
/* The head is the positioned box (same width as the nav row), so the offset
   is measured back up from it: hero top padding minus the nav row. */
.roots--hero .crumbs {
  position: absolute;
  inset-block-start: calc(var(--u-2) - var(--u-4) - var(--u-8));
  inset-inline: 0;
  z-index: 3;
}

.roots--hero .roots__title {
  margin: 0;
  font-size: var(--fs-act);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  line-height: 1.05;
  color: var(--ink);
}

.roots--hero .crumbs ol {
  justify-content: flex-start;
}

/* Desktop: the cut-out at 80% of the frame, still large. The dark wash
   behind the white words shrinks with it (80% of its usual width) so it
   stays inside the dense body of the piles and never shows on the cream. */
@media (min-width: 992px) {
  .roots--hero .roots__pile--combined {
    inline-size: min(80%, 1126px);
    margin-inline: auto;
  }

  .roots--hero .roots__wash {
    inline-size: min(528px, 50%);
  }
}

.roots--hero {
  padding-block-end: clamp(var(--u-8), 8vw, 128px);
}

/* ==========================================================================
   About page — one system for the whole page
   Four text tiers only: the hero title, section titles (.section-title),
   item titles (founders, leaders, values — one size), and one body size.
   Roles share one small label style. Everything is centred, and the wide
   sections are held to one narrower width so the page doesn't swing
   between a reading column and a full-width grid.
   ========================================================================== */

.about {
  --about-wide: 1040px;
}

/* Same rhythm in every content section; tighter on a phone. */
.about .rsec,
.about .team,
.about .values {
  padding-block: var(--u-10);
}

@media (max-width: 640px) {
  .about .rsec,
  .about .team,
  .about .values {
    padding-block: var(--u-9);
  }
}

.about .team .container,
.about .values .container {
  inline-size: min(100% - (2 * var(--gutter)), var(--about-wide));
}

/* --- Tier: item titles ----------------------------------------------------- */
.about .founders__name,
.about .leader__name,
.about .value__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-heading);
  letter-spacing: var(--ls-heading);
  line-height: var(--lh-heading);
  color: var(--ink);
}

/* --- Tier: body ------------------------------------------------------------ */
.about .rsec p,
.about .founders__line,
.about .value__desc,
.about .roots__sub {
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  color: var(--ink-80);
}

/* --- Tier: role labels ----------------------------------------------------- */
.about .founders__role,
.about .leader__role {
  font-family: var(--font-display);
  font-size: var(--fs-label);
  font-weight: var(--fw-label);
  letter-spacing: var(--ls-label);
  line-height: 1.45;
  color: var(--field-ink);
}

/* --- Centred text sections ------------------------------------------------- */
.about .rsec .prose {
  text-align: center;
}

/* --- Team: founders as a centred feature, leaders below -------------------- */
.about .founders {
  grid-template-columns: 1fr;
  justify-items: center;
  gap: var(--u-5);
  margin-block-end: var(--u-9);
  text-align: center;
}

.about .founders__photo {
  inline-size: min(100%, 420px);
}

.about .founders__text {
  display: grid;
  justify-items: center;
  gap: var(--u-2);
}

.about .founders__line {
  max-inline-size: 40ch;
  margin-block-start: var(--u-2);
}

.about .leader {
  justify-items: center;
  text-align: center;
  gap: var(--u-1);
}

.about .leader__photo {
  inline-size: 100%;
}

/* --- Values: same tiers, centred cards, three over two --------------------- */
.about .values__grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--u-5);
}

.about .value {
  flex: 1 1 100%;
  justify-items: center;
  gap: var(--u-3);
  padding: var(--u-6) var(--u-5);
  text-align: center;
}

.about .value__icon {
  inline-size: 40px;
  block-size: 48px;
  object-fit: contain;
}

/* Optical balance: the line-drawn marks (telescope, columns) read smaller
   than the solid ones at the same size, so they're drawn larger and the
   mostly-filled marks smaller. Every icon keeps the same 48px-tall slot, so
   the card titles still line up across a row. */
.about .value__icon[src*="value-vision"],
.about .value__icon[src*="value-place"] {
  inline-size: 48px;
}

.about .value__icon[src*="value-trust"],
.about .value__icon[src*="value-expertise"],
.about .value__icon[src*="value-environment"] {
  inline-size: 36px;
}

@media (min-width: 620px) {
  .about .value {
    flex: 0 1 calc((100% - var(--u-5)) / 2);
  }
}

@media (min-width: 992px) {
  .about .value {
    flex: 0 1 calc((100% - 2 * var(--u-5)) / 3);
  }
}

/* --- English roots labels ----------------------------------------------------
   The name, then its translation on a second, lighter line. Both labels are
   laid out identically — centred text, titles sharing one top edge — at every
   width, so neither one floats higher because its description runs longer.
   Hebrew keeps its original layout. */
.roots__gloss {
  display: block;
  font-size: 0.6em;
  font-weight: var(--fw-body);
  letter-spacing: 0;
  line-height: 1.3;
}

[dir="ltr"] .roots__label {
  justify-items: center;
  text-align: center;
}

@media (min-width: 992px) {
  [dir="ltr"] .roots--combined .roots__labels {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 20rem));
    justify-content: center;
    align-content: center;
    align-items: start;
  }
}

/* --- Choice group (multi-select pills) -----------------------------------------
   Real checkboxes, visually carried by their pill: an outline when off, the
   field green fill when on (a fill change, not a colour-only cue). Same height,
   radius tone and border as the other fields. */
.field--choices {
  position: relative;
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.field--choices legend {
  padding: 0;
  font-size: var(--fs-small);
  font-weight: var(--fw-body-strong);
}

.choices__hint {
  font-size: var(--fs-small);
  color: var(--t-muted);
}

/* Tags, not full-width buttons: each pill is as wide as its words plus one
   fixed padding. Two groups — room counts, then apartment types — sit in a
   wrapping row: one line when everything fits, otherwise the break always
   falls between the groups, never leaving a lone pill. (A group may wrap
   inside itself only on the very narrowest screens.) */
.choices {
  display: flex;
  flex-wrap: wrap;
  gap: var(--u-2);
  margin-block-start: var(--u-1);
}

.choices__group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--u-2);
}

.field .choice {
  position: relative;
  display: flex;
  font-size: var(--fs-body);
  font-weight: var(--fw-body);
  cursor: pointer;
}

.choice input {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.choice span {
  display: flex;
  align-items: center;
  min-block-size: 38px;
  padding-inline: var(--u-4);
  white-space: nowrap;
  border: 1px solid var(--ink-30);
  border-radius: var(--r-pill);
  background: #fffdf7;
  color: var(--ink);
  transition: background var(--dur-s) var(--ease-out),
    border-color var(--dur-s) var(--ease-out), color var(--dur-s) var(--ease-out);
}

.choice:hover span {
  border-color: var(--field);
}

.choice input:checked + span {
  background: var(--field);
  border-color: var(--field);
  color: var(--paper);
}

.choice input:focus-visible + span {
  outline: 2px solid var(--field);
  outline-offset: 2px;
}

.choice input[aria-invalid="true"] + span {
  border-color: var(--error);
}

/* On the label's line, at the far end (left in Hebrew, right in English):
   attached to the question, but clearly not part of its wording. A
   fieldset's legend sits above its content box, so this is pulled up by the
   legend's line (~24px) plus half the gap between the 44px tap height and
   that line. */
.choices__actions {
  position: absolute;
  inset-block-start: -34px;
  inset-inline-end: 0;
  display: flex;
  gap: var(--u-4);
}

.choices__action {
  padding: 0;
  font-size: var(--fs-small);
  font-weight: var(--fw-body-strong);
  color: var(--field-ink);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.choices__action:hover {
  color: var(--ink);
}

/* --- Closing CTA copy (home statement + About) ---------------------------------
   "אנחנו מאמינים שפרויקטים טובים מתחילים בשיחה…" is two full sentences, so
   the title box widens enough for each to hold one line on desktop, and
   wraps balanced (no single dangling word) on smaller screens. */
.about .cta__inner,
.statement .statement__inner {
  max-inline-size: min(100% - (2 * var(--gutter)), 960px);
}

.cta__title-row {
  text-wrap: balance;
}

/* Hierarchy in the closing CTA: the belief is the headline (larger, the
   display weight), the invitation reads as its quieter answer (lead size,
   regular weight, softer white). Home statement + About only. */
.statement__cta-title .cta__title-row:first-child,
.about .cta__title .cta__title-row:first-child {
  font-size: clamp(1.875rem, 1.2rem + 2.6vw, 3.25rem);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  line-height: 1.15;
}

.statement__cta-title .cta__title-row:last-child,
.about .cta__title .cta__title-row:last-child {
  margin-block-start: var(--u-4);
  font-family: var(--font-body);
  font-size: var(--fs-lead);
  font-weight: var(--fw-body);
  letter-spacing: 0;
  line-height: var(--lh-lead);
  color: rgb(255 255 255 / 0.85);
}
