/* Migdalor — the brand system, applied.
   Migdalor_Brand_System_v1.pdf is the spec; this sheet is its only
   implementation. Four rules it keeps:

   1. FOUR COLOURS. Navy anchors and carries all text, lime is the beam,
      lavender softens, off-white breathes. Working ratio off-white 60 /
      navy 30 / lime 7 / lavender 3 — lime earns its impact by being scarce.
      Where a lighter tone is needed it is one of these at a fixed opacity,
      never a new hue and never grey.
   2. ONE TYPEFACE. DM Sans. Hierarchy comes from weight and scale, never
      from a second family.
   3. LIME IS A SURFACE, NEVER TEXT ON LIGHT. The brand book measures it at
      1.4:1 on white. It is a bar, a fill, a rule — never a word you read.
   4. ONE SPACING SCALE, one page gutter, so edges line up down the page.

   The three graphic devices — the beam rule, the light sweep, the soft
   chips — are the only decoration. Everything else is whitespace.
*/

@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;600;700;900&display=swap');

:root {
  --navy:     #1c194b;
  --lime:     #d6df44;
  --lavender: #cbb1d5;
  --cream:    #eeeeea;

  /* the navy tint scale from the brand book — used instead of grey/black */
  --navy-80: rgba(28, 25, 75, 0.80);
  --navy-60: rgba(28, 25, 75, 0.60);   /* caption colour, per spec */
  --navy-40: rgba(28, 25, 75, 0.40);
  --navy-20: rgba(28, 25, 75, 0.20);
  --navy-12: rgba(28, 25, 75, 0.12);   /* hairlines */
  --navy-08: rgba(28, 25, 75, 0.08);

  --lav-40:  rgba(203, 177, 213, 0.40); /* the chip / soft panel surface */
  --lav-18:  rgba(203, 177, 213, 0.18);
  --lime-18: rgba(214, 223, 68, 0.18);

  /*> ONE COLOUR PER PILLAR. Three of the four brand colours are spoken for as
      identities — culture lime, innovation navy, impact lavender — leaving
      off-white as the canvas they all sit on. Nothing new was invented: the
      palette already had exactly three colours and there are exactly three
      pillars. The wash values are the same hues at the low opacity a card
      needs to tint without swallowing a partner's logo. <*/
  --pillar-culture:    #d6df44;
  --pillar-innovation: #1c194b;
  --pillar-impact:     #cbb1d5;

  --wash-culture:    rgba(214, 223, 68, 0.38);
  --wash-innovation: rgba(28, 25, 75, 0.34);
  --wash-impact:     rgba(203, 177, 213, 0.62);

  /* one spacing scale */
  --s1: 0.4rem;
  --s2: 0.8rem;
  --s3: 1.4rem;
  --s4: 2.4rem;
  --s5: 4rem;
  --s6: 6.5rem;

  /*> WIDER, to match migdalor.de — measured live rather than guessed (24 Aug).
      The old site is fully fluid: 8% gutters either side, so its content
      column is 84% of the viewport with no cap at all. Measured 102px gutters
      / 1076px column at a 1280px viewport, and 144px / 1512px at 1800px.

      Ours was a 1180px column inside 6vw gutters, which worked out ~50px
      narrower at 1280 and dramatically narrower on a big screen (988px
      against their 1512px at 1800). `8vw` reproduces their gutter exactly, so
      from roughly 1000px up to `--shell` the two are the same width.

      `--shell` keeps a cap where they have none. Fully fluid is fine for THEM
      because Wix re-columns everything, but here it would run headings and
      the hero across a 2560px monitor in one line. Body prose is already
      protected by `--measure`; this protects everything that isn't prose.
      Raise it if a wider look is wanted on big displays — it is one number,
      used everywhere, on purpose. <*/
  /*> ONE SIZE FOR EVERY PARAGRAPH ON THE SITE (2 Sep). Yael: "in all pages
      the first text paragraph is not the same as the one after — make all
      text the same size and font", pointing at the Team page, where the
      opening paragraph and the ones following it had already been unified.

      The split it replaces was real, not accidental: an opening `.mg-lede`
      at 17-19px and `.mg-body` prose at a flat 16px. That is a normal
      editorial hierarchy, but across these pages it just read as two
      paragraphs that failed to match. Declared once here so lede, body,
      value copy and venture blurbs cannot drift apart again. <*/
  --body-size: clamp(1.0625rem, 1.6vw, 1.1875rem);   /* 17 → 19px */
  --body-lead: 1.55;

  --shell:  1600px;           /* content column cap — page, navbar, footer, bands */
  --gutter: clamp(1.5rem, 8vw, 8rem);

  /*> THE LOGO ASSET'S OWN LEFT PADDING, as a fraction of its box.
      logo-navy.png is a 340x340 canvas whose mark occupies x61..278 — so
      17.94% of any box drawn with it is empty space before the ink starts.
      Every place the wordmark sits at the page's left edge has to cancel
      that, or the MARK lands ~18px right of the text beneath it while the
      invisible box edge lines up perfectly. Yael caught exactly this after
      the shell widened. Declared once so the navbar and the footer correct
      by the same amount, and so a tightly-cropped asset one day means
      setting this to 0 rather than hunting negative margins. <*/
  --brand-ink-inset: 0.1794;
  --measure: 62ch;            /* body max width, per spec */
  --radius: 2px;              /* nearly square — calm, not friendly */
  --radius-card: 6px;         /* portfolio cards only: enough to soften, not to round */
  --beam: 44px;               /* the beam rule's length */

  /* point the framework's own tokens at the brand so components we never
     style by hand still land on-palette */
  --z-primary: #1c194b;
  --z-primary-contrast: #d6df44;
  --z-secondary: #cbb1d5;
  --z-bg: #eeeeea;
  --z-accent: #cbb1d5;
  --color-success: #d6df44;
  --color-info: #cbb1d5;
}

/* ── canvas ───────────────────────────────────────────────────────────── */

/*> the site has no dark theme — without this, a browser in system Dark Mode
    (confirmed: Safari on macOS) paints native form controls (inputs,
    selects, the scrollbar) with ITS OWN dark fill while our CSS still
    colours the text navy on what it thinks is a transparent background,
    so typed text in e.g. the newsletter email field becomes illegible
    navy-on-navy. `color-scheme: light` tells the browser this page is
    light-only, so it renders native controls in light appearance
    regardless of the OS/browser dark-mode setting. <*/
html { color-scheme: light; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--cream);
  color: var(--navy);
  font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif;
  font-weight: 400;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img, video, svg { max-width: 100%; height: auto; display: block; }

::selection { background: var(--lime); color: var(--navy); }

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 3px;
}

/* ── type scale, straight off the brand book ──────────────────────────── */

h1, h2, h3, h4, h5, h6 { margin: 0; color: var(--navy); }

/*> RECONCILED against Migdalor_Brand_System_v1.pdf §02 (24 Aug), after Itai
    read the site as "close, but not exactly" the brand book. Each level below
    now carries the book's own numbers. What was off:
      · H1 ran 36→52px at line-height 1.05 with Display's -1.5% tracking —
        it was doing DISPLAY's job and H1's job at once. The book separates
        them: Display is 52-64px/1.05/-1.5%, H1 is 36px/1.15 with no tracking.
      · H2 carried a -0.005em tracking the book never specifies, and bottomed
        out at 22.4px instead of its stated 26px.
      · Display topped out at 60px against the book's 64px.
    H3 (19px/1.35/600), Eyebrow (13px/caps/+22%/600) and Body (16px/1.6/62ch)
    were already exact and are untouched.

    The book is a print spec with single fixed sizes; a website still has to
    survive a 390px phone. So the MAXIMUM of every clamp is now the book's
    number exactly, and the minimum is the next size down its own scale —
    never an invented value. <*/
.mg-hero-title,
h1 {
  font-weight: 900;
  font-size: 2.25rem;                          /* H1 · 36px, per book */
  line-height: 1.15;                           /* per book (was 1.05) */
  text-wrap: balance;
}

/*> DISPLAY — the book's 52-64px tier, the only place -1.5% tracking belongs.
    Floors at H1's 36px so a phone gets the next size down the same scale
    rather than an arbitrary shrink. <*/
.mg-page-landing .mg-hero-title,
.mg-hero-title-over {
  font-size: clamp(2.25rem, 5.4vw, 4rem);      /* 36 → 64px */
  line-height: 1.05;
  letter-spacing: -0.015em;
}

.mg-section-title, h2 {
  font-weight: 700;
  font-size: clamp(1.5rem, 2.6vw, 1.625rem);   /* 24 → 26px, per book */
  line-height: 1.25;
}

.mg-card-title, h3 {
  font-weight: 600;
  font-size: 1.1875rem;                        /* 19px */
  line-height: 1.35;
}

.mg-eyebrow {
  font-weight: 600;
  font-size: 0.8125rem;                        /* 13px */
  line-height: 1.3;
  letter-spacing: 0.22em;                      /* +22%, per spec */
  text-transform: uppercase;
  color: var(--navy-60);
  margin: 0;
}

/*> NO WIDTH CAP — Yael, 26 Aug: the opening paragraph at the top of every
    page should run left to right like everything else, not sit in a column
    on the left with the right half empty. This used to stop at 54 characters.

    Same trade as the Team story, now applied site-wide: at the 1600px shell
    a full-width line is well past the 50-75 characters that read most
    comfortably, and the brand book's own body spec is 62. It is a look she
    has chosen deliberately after seeing both. The prose in the SECTIONS
    below still keeps `--measure` — only these opening paragraphs run wide,
    so the pages still have a reading width where the long copy lives. <*/
.mg-lede {
  font-size: var(--body-size);
  line-height: var(--body-lead);
  color: var(--navy-80);
  margin: 0;
}

/*> the landing lede is rendered by zMD now, so it arrives as `<p>` elements
    rather than bare text, and those carry a browser default margin. Same
    treatment `.mg-body` already gets: our own rhythm between paragraphs,
    nothing hanging off the last one. Also applies to Impact's lede since it
    switched to zMD too (15 Oct 2026, see zUI.impact.zolo); harmless on
    Culture/Innovation, where the lede is still a single zText and matches
    nothing here. <*/
.mg-lede p { margin: 0 0 var(--s3); }
.mg-lede p:last-child { margin-bottom: 0; }

/*> the lime highlight for a name/phrase inside a lede sentence — Yael asked
    to call out "Migdalor Manara for Peace" the first time it's named on the
    Impact page. Not a new idea: it's the same navy-on-lime pairing the
    brand's own `::selection` rule already uses, just made permanent instead
    of only-on-select. A literal highlighter-stroke look, which is what was
    actually asked for, rather than inventing a different emphasis style.
    `border-radius` keeps the block from reading as a harsh rectangle;
    `padding` on the inline x-axis only, so it doesn't disturb line-height. <*/
.mg-lede strong {
  background: var(--lime);
  color: var(--navy);
  font-weight: 700;
  padding: 0.05em 0.3em;
  border-radius: 3px;
}

/*> NO WIDTH CAP — Yael, 26 Aug, pointing at "Our approach" on the pillar
    pages: every text on every page should run left to right, not stop in a
    column on the left. This used to stop at `--measure` (62 characters, the
    brand book's body spec).

    That leaves ONE deliberate exception, `.mg-page-legal .mg-body` further
    down: the Impressum and the privacy policy are long, dense statutory
    text, and they keep the reading width. Flagged to Yael rather than
    decided quietly — it is one line to remove if she wants those wide too.

    `--measure` itself is left defined, still used by the legal override and
    still the right number to come back to if the wide look is ever undone. <*/
.mg-body {
  font-size: var(--body-size);
  line-height: var(--body-lead);
  color: var(--navy-80);
  margin: 0;
}

.mg-body p { margin: 0 0 var(--s3); }
.mg-body p:last-child { margin-bottom: 0; }

.mg-note {
  font-size: 0.8125rem;
  color: var(--navy-60);
}

/* the marker-pen highlight zMD's ==syntax== emits — used on the legal
   pages to mark what is still missing, so a gap is impossible to skim past */
.mg-body mark, .mg-note mark {
  background: var(--lime);
  color: var(--navy);
  padding: 0.1em 0.35em;
  border-radius: var(--radius);
  font-weight: 600;
}

/* ── the beam rule: a 4px lime bar opening every section ──────────────── */

.mg-section-title,
.mg-section-eyebrow,
.mg-legal-heading {
  position: relative;
  padding-top: var(--s3);
}

.mg-section-title::before,
.mg-section-eyebrow::before,
.mg-legal-heading::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: var(--beam);
  height: 4px;
  background: var(--lime);
}

/* ── page frame ───────────────────────────────────────────────────────── */

.mg-page {
  max-width: var(--shell);
  margin: 0 auto;
  padding: var(--s5) var(--gutter) 0;
  display: flex;
  flex-direction: column;
  /*> the space between sections, NAMED (2 Sep) because two other rules need
      to know it and both had it copied in by hand. It shrinks to `--s5` on
      narrow screens, and each hardcoded copy silently stopped matching:

        · the footer's cancelling margin still pulled up by `--s6`, 104px
          against a 64px gap, so on every phone the footer OVERLAPPED the
          section above it by 40px — the crowding Yael photographed;
        · the pillar cluster's top margin was tuned to sit level with a
          104px gap, so on a phone the space above the circles came out
          ~102px against ~64px below. Hence "too much space before the
          circles… situate them in the middle".

      One variable, inherited by both. Change the gap and they follow. <*/
  --page-gap: var(--s6);
  gap: var(--page-gap);
}

/*> the page's bottom padding is gone. Every page now ends in %SiteFooter, and
    that padding used to land AFTER it — a page-column-width gap of pure
    off-white below the footer's own already-off-white background, doing
    nothing visible except adding scroll height. The footer supplies its own
    bottom padding; the page does not need to add more. <*/

/*> no top padding where a full-bleed hero opens the page — the film should
    meet the bar with nothing between them. The breathing room moves inside
    the hero instead, between the film and the first line of type.

    `.mg-page-team` joined this list on 25 Aug, when the group photograph
    became that page's hero. These three page types are simply "pages that
    open on a full-bleed hero" — if a fourth ever does, it needs adding to
    each of the five groups that carry this trio (this one, the `.mg-hero`
    gap below, the media sizing, and the two mobile overrides). <*/
.mg-page-landing,
.mg-page-pillar,
.mg-page-team,
.mg-page-open-call { padding-top: 0; }

.mg-page-landing .mg-hero,
.mg-page-pillar .mg-hero,
.mg-page-team .mg-hero { gap: var(--s5); }

/* ── hero ─────────────────────────────────────────────────────────────── */

.mg-hero {
  display: flex;
  flex-direction: column;
  gap: var(--s4);
}

.mg-hero-media {
  width: 100%;
  border-radius: var(--radius);
  background: var(--navy);
}

/*> FULL BLEED. `.mg-page` is a centred `--shell` column with a gutter, so an
    image inside it can never reach the window edge on its own. `calc(50% -
    50vw)` measures from the container's own centre out to the viewport edge,
    which works whatever the gutter happens to be at that breakpoint — no
    magic numbers, nothing to keep in sync with the container width.

    It is the STAGE that bleeds, not the image, so the overlay can be
    positioned against the full-width frame. <*/
.mg-hero-stage {
  position: relative;
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  display: block;
  isolation: isolate;
}

/*> height is capped rather than left to a 16:9 ratio: at 100vw a 16:9 film is
    over 700px tall on a laptop, which pushes everything else off the screen.
    `cover` crops instead, so the frame stays cinematic. <*/
.mg-page-landing .mg-hero-media,
.mg-page-pillar .mg-hero-media,
.mg-page-team .mg-hero-media {
  width: 100%;
  height: min(78vh, 760px);
  object-fit: cover;
  border-radius: 0;
  display: block;
}

/*> Itai's head sat close to the very top of `team-hero.jpg` (2400x1296 — a
    wider aspect than the hero box becomes on any screen over ~1408px wide),
    so the default center crop ate further into it as screens got wider.
    FIRST FIX (1 Oct 2026) anchored fully to the top (`object-position:
    center top`) — safe for Itai at literally any width, but that was
    solving for an unrealistic case: it moved ALL the vertical crop to the
    bottom, and Yael (seated, lower in the source photo, face around
    y=588-780 of 1296) is exactly what sits in that bottom margin. On a wide
    screen the visible window's bottom edge landed right at her chin, AND
    that's the same zone `.mg-hero-stage::after`'s gradient darkens hardest
    for text contrast — she reported herself as "low in the picture and
    darkened", correctly, the next day.
    REVISED to `center 15%` — computed, not guessed: at 1280x561(zRaven),
    1920x760, and 2560x760 (box heights capped at 760 beyond ~975px-tall
    viewports), 15% keeps a positive safety margin for BOTH Itai's head and
    Yael's face at every one of those widths (thinnest margin ~14-20px at
    2560, the widest realistic case checked). This is a CALIBRATED
    compromise, not a mathematical guarantee at arbitrary width the way pure
    top-anchor was — an uncommonly wide ultra-wide monitor (>2560px) could
    still pinch one side slightly, but that trade was deliberate: optimizing
    for literally unbounded width made the realistic, common case worse for
    a real person in the photo. Scoped to Team only. Below ~1408px wide the
    box is narrower than the photo and cover crops horizontally instead,
    where this Y-only change has no effect — tablet/mobile unaffected. <*/
.mg-page-team .mg-hero-media {
  object-position: center 15%;
}

/*> RETIRED 16 Sep, with the lighthouse placeholder it was written for. This
    rule used to anchor the crop near the top of frame because that photo's
    lighthouse tip sat only ~17% down — cropping at the default 50% cut it
    off against the navbar. The commissioned hero animation that replaced it
    is a different composition entirely (an illustrated scene, not a single
    tall subject with a predictable "important part"), so a hardcoded
    top-weighted crop has no reason to still apply and was actively likely to
    cut the new film oddly. Landing now defaults to plain center cropping,
    same as the pillar heroes below. If the new film ever needs its own
    anchor, compose it the same way this comment describes and re-add a rule
    scoped to `.mg-hero-video` specifically, not to the whole landing hero —
    a future poster-only image swap shouldn't inherit a crop tuned for video
    framing. <*/

/*> a scrim, not a guess. Neither the commissioned homepage animation nor
    Culture's film has a predictable brightness where the words land, and
    lime on a pale frame fails contrast badly. A gradient weighted to the
    bottom guarantees the type always has something dark beneath it, while
    leaving the top of the image untouched. <*/
.mg-hero-stage::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(28,25,75,0.78) 0%, rgba(28,25,75,0.35) 34%, rgba(28,25,75,0) 62%);
  pointer-events: none;
  z-index: 1;
}

.mg-hero-overlay {
  position: absolute;
  left: calc(max(0px, (100vw - var(--shell)) / 2) + var(--gutter));
  right: var(--gutter);
  bottom: clamp(2rem, 6vw, 4.5rem);
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  max-width: min(44rem, 62vw);
}

.mg-hero-mark {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--lavender);
  margin: 0;
}

/*> lime on navy — the brand book's SIGNATURE pairing, and the reason the
    scrim above is navy rather than plain black. <*/
/*> COLOUR ONLY. The size/leading/tracking for this Display tier live with the
    rest of the type scale at the top of this file — they used to be repeated
    here too, at a 60px max that silently beat the scale's own 64px because
    this rule is declared later. One home per decision. <*/
.mg-hero-title-over {
  color: var(--lime);
  margin: 0;
}

/*> the 46rem cap is gone with `.mg-lede`'s own — this is the block that
    HOLDS the opening paragraph, so leaving it capped would have kept the
    text short no matter what the lede itself said. Both had to go for the
    top of the page to actually run full width. <*/
.mg-hero-copy {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

/* ── the three pillar doors ───────────────────────────────────────────── */

/*> THE INTRO — eyebrow + lede only now. Used to be a 2-column grid holding
    the copy AND the pillar circles side by side; the circles moved out to
    their own full-width row below (second design pass, 19 Aug — Yael's own
    words: catch most of the frame, not just one side of it). Nothing left
    here that needs a grid, so this is a plain block. It no longer caps its
    width at all — `.mg-hero-copy`'s old `46rem` was removed on 26 Aug when
    Yael asked for the opening paragraph of every page to run left to right. <*/
.mg-intro {
  display: block;
}

/*> THE THREE LIGHT SPOTS — BACK TO A TRIANGLE (24 Aug, Itai via Yael: "let's
    try putting them in a triangle again, so they all overlap each other").

    This shape has now been round the loop twice, so the history matters. The
    ORIGINAL triangle sat squeezed into half of a 2-column split beside the
    copy, which is what made it feel cramped — so it became a flat row, full
    width, and then the row was grown twice more. The complaint was never the
    triangle itself; it was the half-column it was trapped in. So: the
    triangle returns, but into the full-width slot the row earned, at the
    larger size the row established.

    A row can only ever overlap its NEIGHBOURS — culture never touches impact
    at opposite ends. A triangle is the only arrangement where all three
    overlap all three, which is the point: where two beams cross the multiply
    blend compounds the colour, and the centre carries all three at once.

    ONE LAMP, THREE BEAMS (2 Sep). The third pass, and the one that named the
    actual problem: the discs blend with `multiply`, which is INK — every
    overlap gets DARKER, and lime over navy goes muddy brown. For a company
    named after a lighthouse that is backwards. Light adds. So the cluster now
    carries a `screen`-blended core (`::after`) exactly where all three cross,
    and a soft halo behind the whole group (`::before`): three beams landing on
    one lit spot, rather than three stickers someone overlapped.

    Two geometry changes came with it, both driven by Yael:
      · BIGGER, and the labels are why. Each word must sit at its own disc's
        centre in that disc's solid colour — "it looks bad otherwise" — so the
        size is set by the longest word, INNOVATION, not chosen for looks. See
        `--sep` below for the arithmetic that guarantees it.
      · Innovation and Impact SWAPPED sides. Navy on the right balances the
        lime top-left instead of stacking both heavy colours together, and it
        leaves lavender-to-lime on the left, a far softer seam than
        lavender-to-navy was. Positions only — the DOM order stays Culture →
        Innovation → Impact, matching the navbar, so tab order still follows
        the menu.

    Absolute placement inside a box measured in multiples of `--d`, so the
    whole cluster scales as ONE thing and the overlaps can never drift. <*/

/*> `--sep` is the distance between two disc CENTRES, as a fraction of one
    diameter. Every other number here derives from it — box width and height,
    all three offsets, and where the core and halo are centred — so the
    overlap is one edit, not six that must agree.

    Two bounds worth knowing before changing it:

    · ABOVE 0.866 the three discs no longer share a common point at all. The
      triangle's circumradius is `--sep / √3`, and the centre is only inside
      all three discs while that stays under 0.5. At the old 0.794 it was
      0.458 — a three-way region just 0.04d deep, which is precisely why the
      middle read as "barely touching". At 0.70 it is 0.404, giving a region
      ~0.1d deep: a real meeting point with something to light up.

    · BELOW roughly 0.68 the labels break. A disc's centre stays clear of its
      neighbour's edge by `(--sep - 0.5) × --d`; the widest label needs half
      its own width of that. INNOVATION at 13px is ~90px, so it needs ~45px,
      and `(0.70 - 0.5) × 230px` = 46px at the smallest disc this rule ever
      produces. That is the binding constraint on BOTH numbers — it is why
      `--d` has a 230px floor rather than the 150px it used to have, and why
      the phone breakpoint below opens `--sep` up instead of shrinking the
      discs further. The floor is high enough that everything from a small
      tablet upward shares one geometry, with no breakpoint mid-range where
      the overlap would visibly jump.

    Tighten one and the other has to give. <*/
.mg-pillars {
  /*> GROWN ~23% on 2 Sep to take over the footprint the halo used to fill.
      The halo was `2.1 × --d` across and the cluster is `1.7 × --d`, so
      matching the one to the other is exactly `2.1 / 1.7` — 300px became
      370px at the cap, and 20vw became 25vw so the middle of the range
      scales with it.

      The FLOOR went the other way, 230px down to 240px rather than up to
      284px, and that is deliberate: a 284px floor makes the cluster 483px
      wide, which overflows the ~471px a 561px-wide window leaves after its
      gutters — the narrow band just above the phone breakpoint. 240px keeps
      the widest cluster at 408px there, and still clears the label
      constraint (`(0.70 - 0.5) × 240` = 48px, against the ~46px INNOVATION
      needs). Between about 960px and 1480px the viewport drives it anyway,
      so the floor only matters on tablets. <*/
  --d: clamp(240px, 25vw, 370px);
  --sep: 0.70;
  /* triangle height per unit of side, i.e. √3/2 — spelled out so the vertical
     offset below is visibly the same equilateral triangle as the horizontal. */
  --tri: 0.866;
  /*> where the three discs actually cross — the triangle's centroid, which
      is NOT the middle of the bounding box. The box is taller below the top
      disc than above the bottom pair, so centring the light on the box put
      it visibly low; Yael caught that in the second sketch. Horizontally
      it IS the box centre; vertically it is the top disc's own centre plus
      the triangle's circumradius (`--sep / √3`). <*/
  --cx: calc(var(--d) * (1 + var(--sep)) / 2);
  --cy: calc(var(--d) * (0.5 + var(--sep) * 0.5774));
  position: relative;
  width:  calc(var(--d) * (1 + var(--sep)));
  height: calc(var(--d) * (1 + var(--tri) * var(--sep)));
  /*> CENTRED BETWEEN WHAT IS ABOVE AND BELOW IT, at every width. The space
      below the cluster is the page's own section gap; the space above is
      this margin PLUS `.mg-hero`'s `--s4` gap, since the circles are the
      hero's last child. Subtracting that `--s4` is what makes the two come
      out equal, rather than a flat value that only happened to balance at
      the desktop gap — which is why a phone showed ~102px above against
      ~64px below. <*/
  margin: calc(var(--page-gap) - var(--s4)) auto 0;
  isolation: isolate;
}

/*> culture on top, centred; impact lower-LEFT and innovation lower-RIGHT —
    every pair overlapping, all three meeting in the middle. Each `left` is a
    centre offset with the disc's own radius (0.5d) taken back off. <*/
.mg-pillars .mg-spot-culture {
  top: 0;
  left: calc(var(--d) * var(--sep) / 2);
}
.mg-pillars .mg-spot-impact {
  top: calc(var(--d) * var(--tri) * var(--sep));
  left: 0;
}
.mg-pillars .mg-spot-innovation {
  top: calc(var(--d) * var(--tri) * var(--sep));
  left: calc(var(--d) * var(--sep));
}

/*> THE LAYER STACK, and why each piece sits where it does. `isolation` on
    `.mg-pillars` makes this a self-contained stacking context, so all four
    layers blend against each other and never against the page:

      z -1   .mg-spot::before  the three discs (multiply)
      z -1   ::after    the lit core (screen), painted AFTER the discs
             .mg-spot   the labels, on top

    The core and the discs deliberately share z-index -1. A parent's ::after
    counts as its last child, so at equal z-index it paints above every disc —
    which is what the core needs — while both stay below the buttons' own text.
    That last part is the whole trick: give `.mg-spot` a positive z-index to
    lift the labels instead, and each button becomes its own stacking context,
    trapping its disc's `multiply` inside it. The discs would stop blending
    with each other entirely and the cluster would fall apart. Do not add a
    z-index to `.mg-spot`. <*/
.mg-pillars::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}

/*> THE HALO IS GONE, and this note is why there is no `::before` here.

    There was one: a wide, soft radial pool behind the whole cluster, meant
    to make the group sit IN light rather than flat on the canvas. It was
    softened once already, from three gradient stops to five, because its
    tail resolved into a visible rim. That fixed the hard edge but not the
    real problem — Yael, 2 Sep: "there is a very light grey circle around the
    3 circles. please get rid of it. no need — keep only the white background
    around."

    She is right, and the reason is worth keeping. Any tint spread that thin
    over off-white goes neutral: at 0.26 opacity the lime and lavender both
    collapse toward grey, so it read as a dull disc behind the discs rather
    than as light around them. The plain canvas gives the cluster more room
    to breathe than a faint wash ever did.

    What replaced it is size — the discs now occupy the space the halo used
    to, per the same note: "enlarge the 3 circles (so it reaches the same
    size of the light grey circle now)". See `--d` above. Do not reintroduce
    a background glow here; if the cluster ever needs more presence, it comes
    from the discs, not from something behind them. <*/

/*> the lit core — the point of the whole exercise. `screen` is the opposite
    of the discs' `multiply`: where they subtract, this adds, so the middle
    becomes the BRIGHTEST part of the cluster instead of the muddiest.

    It is wider than the three-way region on purpose (Yael, after the second
    sketch: "enlarge a bit the light in the middle"). Spilling onto the
    two-way overlaps is what makes it read as one pool of light rather than a
    dot in a gap.

    But only just wider — 0.40d, down from 0.634d in the first build, which
    was a mistake worth recording. Two things go wrong when this grows:

      · It stops looking like light. A bright centre with a fast falloff
        reads as glow; a broad one with a defined rim reads as a white BALL
        sitting on top of the discs. Peak opacity matters as much as size —
        this now tops out around 0.6, not 0.95.
      · It escapes the discs. Below the centroid, between the two lower
        circles, there is bare canvas, and `screen` against an empty backdrop
        returns the source unchanged — so the overspill showed up as a pale
        tongue hanging into the gap. Nothing clips it; staying small and
        fading to nothing before the union's edge is the only control.

    Size is also bounded by the labels, though less tightly than it looks:
    the element reaches 0.31d from the centre, further than the ~0.26d at
    which the nearest label edge sits — but by that radius the tail is down
    to a few percent alpha, far too faint to disturb INNOVATION's
    lime-on-navy, the lowest-contrast pairing in the cluster. It is the
    BRIGHT part that has to stay clear of the words, not the element box.

    One asymmetry to know about: `screen` lifts dark surfaces far more than
    light ones, so with navy now on the right the glow reads a touch stronger
    that side. It gives the light a direction and looks intentional. If it
    ever reads as lopsided, nudge `--cx` a few px left — do not desaturate the
    navy to compensate. <*/
.mg-pillars::after {
  z-index: -1;
  /*> the tint is pale LIME, not white — the light in a lighthouse is warm,
      and a neutral white core reads as a hole punched in the discs. Derived
      from `--lime` rather than written as a hex so it follows the brand
      colour if that ever changes. Alpha is applied per-stop on top of it. <*/
  --core-tint: color-mix(in srgb, var(--lime) 20%, #fff);
  width:  calc(var(--d) * 0.62);
  height: calc(var(--d) * 0.62);
  left: calc(var(--cx) - var(--d) * 0.31);
  top:  calc(var(--cy) - var(--d) * 0.31);
  /*> FIVE stops, and the shape of the curve matters more than the size. The
      element is wider than the light looks — the visible glow is roughly the
      inner half, and the outer half is a long, near-invisible tail whose only
      job is to stop the edge existing.

      The previous version was 0.44d with a short falloff, and against the
      navy it read as a translucent BALL with a rim: `screen` lifts dark
      surfaces so hard that even a 22%-alpha stop stayed clearly visible, and
      the gradient then hit zero a short distance later, which the eye reads
      as a boundary. Stretching the same brightness over a longer tail fixes
      it without dimming the middle. <*/
  /*> TWO stacked gradients in one element, which is how the light got
      brighter without getting bigger (Yael, 2 Sep: "could you try making the
      light in the centre even more bright/glowing?").

      Real light does not fall off evenly — it has a small, near-white heart
      inside a much wider, gentler bloom. One gradient can only do one of
      those: push its peak up and the whole disc turns milky; keep it soft and
      the centre never reads as hot. So the first layer is the heart, burning
      out to nothing by a third of the radius, and the second is the bloom
      underneath it, carrying the long tail that keeps the edge from
      existing. Listed first paints on top.

      The tint also moved closer to white (20% lime, was 30%). `screen` adds
      channel by channel, so the whiter the source the more it lifts — and
      with the discs now at full strength, the overlaps beneath are much
      darker than before, which is what gives this its contrast. Brighter
      light and a deeper surround arrived together, and they flatter each
      other. <*/
  background:
    radial-gradient(circle,
              color-mix(in srgb, var(--core-tint) 100%, transparent) 0%,
              color-mix(in srgb, var(--core-tint)  70%, transparent) 14%,
              color-mix(in srgb, var(--core-tint)   0%, transparent) 34%),
    radial-gradient(circle,
              color-mix(in srgb, var(--core-tint)  78%, transparent) 0%,
              color-mix(in srgb, var(--core-tint)  56%, transparent) 28%,
              color-mix(in srgb, var(--core-tint)  28%, transparent) 55%,
              color-mix(in srgb, var(--core-tint)  10%, transparent) 78%,
              color-mix(in srgb, var(--core-tint)   0%, transparent) 100%);
  mix-blend-mode: screen;
}

.mg-pillars .mg-spot {
  position: absolute;
  width: var(--d);
  height: var(--d);
  border-radius: 50%;
  border: 0;
  background: transparent;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--navy);
  cursor: pointer;
  transition: transform 240ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

/*> TRUE BRAND COLOUR, FULL STRENGTH — and the reasoning here reverses an
    earlier decision, so it is worth being explicit.

    This disc used to be held at `opacity: 0.78` with a soft radial falloff at
    its rim, on the principle that a pillar is LIGHT thrown on a surface, not
    paint. It looked right, but it could not survive measurement. Yael, 2 Sep:
    "the green isn't exactly the same brand green (as the menu bar and other
    place)". She was right, and the numbers are unambiguous — the navbar and
    the portfolio tiles both render `rgb(214, 223, 68)`, exactly `--lime`,
    while the disc rendered `rgb(219, 226, 104)`.

    That gap is not a bug to hunt, it is arithmetic: ANY opacity below 1 mixes
    the off-white canvas into the result, and the blue channel is where it
    shows worst (68 against 104) because lime has so little blue to dilute.
    The same applied to the rim falloff, which faded to 82% alpha and so left
    a lighter ring. A brand colour cannot be both exact and translucent.

    So: full opacity, flat fill. `multiply` still does the interesting work —
    against the transparent backdrop of the isolated cluster it leaves a lone
    disc untouched, so each one reads as its exact brand colour, and only
    where two discs actually cross does the colour compound. Overlaps are
    deeper than they were, which is the honest consequence of full-strength
    ink, and it gives the lit core something to glow against.

    Do not reintroduce opacity here to soften the overlaps — it would silently
    take all three pillars off-brand again. <*/
.mg-pillars .mg-spot::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--spot);
  mix-blend-mode: multiply;
  z-index: -1;
  transition: opacity 260ms ease, filter 260ms ease;
}

.mg-pillars .mg-spot-culture    { --spot: var(--pillar-culture); }
.mg-pillars .mg-spot-innovation { --spot: var(--pillar-innovation); color: var(--lime); }
.mg-pillars .mg-spot-impact     { --spot: var(--pillar-impact); }

/*> hovering turns the lamp UP — more opacity and brightness in the disc's own
    colour. Nothing changes hue, so the palette stays the four brand colours in
    every state. The two `.zBtn-primary` overrides are load-order defence: that
    rule is declared later in this sheet and would otherwise repaint the navy
    disc lime and flip its label to navy. <*/
/*> hover no longer touches OPACITY — it used to lift it from 0.78 to 0.94,
    which is meaningless now that the disc rests at full strength, and would
    have meant the only moment the pillar showed its true brand colour was
    while the pointer was elsewhere. Brightness alone turns the lamp up, and
    because it applies only during hover the resting colour stays exact. <*/
.mg-pillars .mg-spot:hover { transform: scale(1.04); z-index: 3; }
.mg-pillars .mg-spot:hover::before { filter: brightness(1.08); }

.mg-pillars .mg-spot.zBtn-primary:hover,
.mg-pillars .mg-spot.zBtn-primary:focus { background: transparent; }

.mg-pillars .mg-spot-culture.zBtn-primary:hover,
.mg-pillars .mg-spot-impact.zBtn-primary:hover { color: var(--navy); }

.mg-pillars .mg-spot-innovation.zBtn-primary:hover { color: var(--lime); }

.mg-pillars .mg-spot:focus-visible { z-index: 3; }

/*> THE THREE FOUNDER PHOTOS, under "Our story"'s headline, above its prose —
    added the same design pass as the row above, so a first-time visitor
    landing straight on this page (not arriving via Team) knows who "Yael"
    and "Jan" are before the body text starts using their names.

    Was capped to `46rem`, matching the prose; Yael asked for both to stretch
    out to the Values section's own right edge instead — no explicit number
    here, `.mg-story` sets no width of its own, so removing the cap lets this
    fill the same `.mg-page` content column Values reads its own width from,
    landing on the same edge without the two needing to agree on a figure. <*/
.mg-story-people {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s4);
  margin-bottom: var(--s2);
}

.mg-story-person { display: flex; flex-direction: column; gap: var(--s2); }

.mg-story-person-photo {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--radius);
  background: var(--lav-40);
}

.mg-story-person-name { margin: 0; font-size: 0.9375rem; font-weight: 600; color: var(--navy); }
.mg-story-person-role { margin: 0; font-size: 0.8125rem; color: var(--navy-60); }

/*> the group shot is a PHONE-ONLY alternative to the three portraits — off
    by default, switched on at the phone breakpoint further down this file.
    Declared here, next to the portraits it replaces, so the pair is visible
    in one place. <*/
.mg-story-group { display: none; }

/* ── buttons ──────────────────────────────────────────────────────────── */

/*> given more presence than a default button: the three pillar doors are the
    main act of the landing page, and at 15px in a tight box they read as form
    controls rather than as the way into the site. Caps + tracking + real
    padding makes them deliberate. <*/
.zBtn {
  font-family: inherit;
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 1rem 2rem;
  border-radius: var(--radius);
  border: 1px solid var(--navy);
  cursor: pointer;
  transition: background 180ms ease, color 180ms ease;
}

/* navy on lime — the brand book's STRONG pairing, for calls to action */
.zBtn-primary {
  background: var(--navy);
  color: var(--lime);
}
.zBtn-primary:hover { background: var(--lime); color: var(--navy); }

.zBtn-secondary {
  background: transparent;
  color: var(--navy);
}
.zBtn-secondary:hover { background: var(--lav-40); }

/* ── navbar ───────────────────────────────────────────────────────────── */

/*> the bar is LIME with navy on it — the brand book's "STRONG" pairing, and
    the one Yael asked for. It is also the single biggest lime surface on the
    site, which is a deliberate departure from the book's 7% guidance: a
    header is the one place the signature colour earns being unmissable.
    Everything below it stays disciplined so this reads as the accent rather
    than as the theme.

    No light sweep here — that device is a lime glow FOR navy surfaces. On
    lime it would be invisible at best and muddy at worst. <*/
/*> the bar's padding has to reproduce where `.mg-page` actually starts, or
    the wordmark sits left of the headline beneath it and the whole page looks
    off its axis. `.mg-page` is a centred `--shell` column PLUS a gutter, so the
    content edge is (viewport − 1180)/2 + gutter once the window is wider than
    the column, and just the gutter below that. The max() expresses exactly
    that, with no breakpoint to keep in sync. <*/
/*> 120px to match migdalor.de's own header, measured live at 1280px (24 Aug).
    Raised from 96px together with the wordmark below — the mark could not
    reach its real size inside the shorter bar. <*/
.zNavbar {
  background: var(--lime);
  padding: 0 calc(max(0px, (100vw - var(--shell)) / 2) + var(--gutter));
  min-height: 120px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: nowrap;
  gap: var(--s4);
  position: sticky;
  top: 0;
  z-index: 100;
}

/*> the framework paints the bar with a `zNavbar-light` theme class, whose own
    rules out-specify a bare `.zNav-link`. That is what left the navigation
    navy-on-navy and effectively invisible in the first screenshot pass. These
    selectors carry the container class so they win on specificity rather than
    on !important. <*/
/*> caps with wide tracking, matching the live bar. It is the eyebrow style
    from the brand book used at navigation size — the same voice, so the bar
    belongs to the same system as the section headings below it. <*/
.zNavbar .zNavbar-nav .zNav-item,
.zNavbar .zNavbar-nav .zNav-link,
.zNavbar a {
  color: var(--navy);
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 600;          /* the book: navy on lime stays SemiBold+ */
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1;            /* one baseline for every item */
  padding: 0;
}

/*> the wordmark replaces the word. `zBrand: Migdalor` still supplies the text
    — it is what a screen reader announces and what the zCLI menu prints —
    so the text is pushed out of view rather than deleted. <*/
/*> SIZED FOR THE INK, NOT THE FILE — Itai read the mark as too small (24 Aug)
    and he was right, but the box was only half the story. logo-navy.png is a
    340x340 canvas whose actual mark occupies just 218x274 of it: 64% of the
    width, 81% of the height. With `background-size: contain`, a 64px box
    therefore drew a mark about 41x52 — while migdalor.de's own header,
    measured live at 1280px, renders its wordmark at 64x80.

    So the box is 100px, not 64: 100 x 0.64 = 64 wide, 100 x 0.81 = 80 tall.
    The mark now matches the live site exactly, and the 10px of canvas padding
    plus 10px of bar clearance reproduces its 20px breathing room too. Swap in
    a tightly-cropped asset one day and this number must come back down. <*/
.zNavbar .zNavbar-brand {
  --brand-box: 100px;
  display: block;
  width: var(--brand-box);
  height: var(--brand-box);
  flex: 0 0 auto;
  /*> absolute, not relative. This sheet is served from /styles/, so
      `../img/…` resolved to /img/… and 404'd — the mark simply never
      appeared. Static assets are mounted at /static/. <*/
  background: url('/static/img/logo-navy.png') left center / contain no-repeat;
  text-indent: -200vw;
  overflow: hidden;
  white-space: nowrap;
  /*> pulled left by the asset's own empty margin (see `--brand-ink-inset`),
      so the MARK sits on the gutter rather than the invisible box edge. Was
      measured at a real 17px out against the text below it once the shell
      widened. Derived from `--brand-box`, so the mobile size below corrects
      itself by the right amount without a second magic number. <*/
  margin: 0 0 0 calc(var(--brand-box) * var(--brand-ink-inset) * -1);
}

/*> nowrap is the fix for "Contact hanging low". It was never a vertical
    alignment problem — the bar ran out of room, Contact wrapped to a second
    flex line, and a centred bar dropped that line below the first. <*/
/*> `zNavBar .zNavbar .zNavbar-nav` is included alongside the plain class
    selector because zbase.css carries its OWN mobile breakpoint at 768px —
    `zNavBar .zNavbar .zNavbar-nav { gap: 0 }`, tag-qualified so it outranks a
    bare two-class selector on specificity. That rule fires in exactly the
    641–768px gap between this sheet's own 640px and 860px breakpoints, which
    is tablet width — the nav items collapsed onto one baseline with the gap
    silently zeroed, reading as "HOMECULTUREINNOVATION…". Matching the
    tag-qualified selector here wins the tie (later in source, equal
    specificity) without touching the phone behaviour below 640px, which
    already wins outright on a further, higher-specificity rule. <*/
zNavBar .zNavbar .zNavbar-nav,
.zNavbar .zNavbar-nav {
  display: flex;
  align-items: center;
  gap: var(--s4);
  flex-wrap: nowrap;
  list-style: none;
  margin: 0;
  padding: 0;
}

/*> THE "CONTACT HANGS LOW" BUG, and it was not Contact's fault. zbase.css
    gives every list item a 6.4px bottom margin and then resets it on
    :last-child. In a vertical list that is invisible. In a horizontal flex
    row with align-items:center, an item is centred INCLUDING its margin box,
    so the four items carrying a bottom margin float ~3.2px high and Contact,
    with none, sits where all five actually belong. Zeroing the margin puts
    every item on one baseline. <*/
.zNavbar .zNavbar-nav .zNav-item {
  display: flex;
  align-items: center;
  margin: 0;
}

/*> the underline grows from the left on hover rather than appearing at full
    width — the same gesture as the beam rule opening a section. <*/
.zNavbar .zNavbar-nav .zNav-link {
  position: relative;
  padding-bottom: 3px;
}

.zNavbar .zNavbar-nav .zNav-link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 2px;
  background: var(--navy);
  transition: width 180ms ease;
}

/*> NO UNDERLINE ANYWHERE IN THE BAR — not on hover, not on the current page.
    Yael ruled the underline out as a device on 26 Aug, and a hover underline
    is the same mark arriving a moment later. The `.active`/`[aria-current]`
    hooks that used to sit here went with it. (They never fired anyway: the
    framework's navbar renderer supports an `activeIndex` that would add
    `.active`, but nothing server-side ever passes one and no zolo key
    reaches it — the `:has()` block below is what actually marks the page.)

    THE DARK WASH ON HOVER IS THE FRAMEWORK'S, and it has to be switched off
    explicitly: zbase.css ships `.zNavbar .zNav-link:hover { background:
    var(--znav-link-hover-bg) }`, a neutral dark wash meant for its own
    default chrome. On a lime bar that reads as a muddy grey box appearing
    under the cursor. Overridden to `transparent` rather than removed — it
    lives in a CDN stylesheet this project does not own. <*/
.zNavbar .zNavbar-nav .zNav-link:hover,
.zNavbar .zNavbar-nav .zNav-link:focus,
.zNavbar .zNavbar-nav .zNav-link:focus-visible {
  background: transparent;
}

/*> hover feedback is a colour shift now, so the bar only ever changes by
    colour — the same language the current-page marker uses. <*/
.zNavbar .zNavbar-nav .zNav-link { transition: color 160ms ease; }
.zNavbar .zNavbar-nav .zNav-link:hover { color: var(--navy-60); }

/*> WHICH PILLAR AM I IN — Yael's own (much simpler) replacement for the
    sticky-hero idea that was tried and abandoned across c39-c46: just mark
    the current page in the bar that is already permanently on screen.

    `:has()` rather than a descendant selector, because the navbar is NOT
    inside the page element — both are siblings under `<zVaF>`, so
    `.mg-here-culture .zNav-link` would match nothing. `:root:has(...)`
    tests the document for the current page's marker class and then styles
    the matching link anywhere on the page, which is exactly the "style a
    thing based on something elsewhere in the DOM" job `:has()` exists for.
    Support is not a gamble here — verified in-browser, and this stylesheet
    already depends on `:has()` for the venture-link rules.

    Matching on `href` keeps this honest: the marker class says WHICH page
    the visitor is on, the href says which link points there, and the rule
    only fires when both agree. A renamed route drops the marker rather
    than silently marking the wrong item.

    The pillars need a per-page class at all because all three share
    `mg-page-pillar` — that class alone can't tell Culture from Impact.

    Home is deliberately NOT included: its href is `/`, and an attribute
    match on that would need care to avoid matching every link; the landing
    page is also the one page where "where am I" is least in doubt.

    A LAVENDER BLOCK BEHIND THE WORD, navy text on it — Yael's pick, 26 Aug,
    after trying two lighter options in sequence. First the underline (ruled
    out as a device), then lavender TEXT on the lime bar, which she judged
    "too soft" once she saw it live. That judgement matched the measurement:
    lavender on lime is 1.34:1, so the current page came out the faintest
    word in the bar and read as a disabled link rather than the active one.

    Inverting it fixes exactly that. Lavender becomes the surface instead of
    the ink, and the word on it goes navy — 8.4:1, comfortably legible, and
    it is the brand book's own "navy on lavender tint" pairing (§03, listed
    for panels and callouts). The marker is now the strongest thing in the
    bar rather than the weakest, which is what a "you are here" mark is for.

    `padding` plus a negative `margin` of the same size keeps the six items
    on their original spacing: the block grows outward from the word instead
    of pushing its neighbours along the bar. Without that, landing on a page
    would visibly nudge the whole menu sideways. <*/
/*> HOME is in this list too, as of 2 Sep. It was left out when the marker was
    built — the landing page felt like the neutral state you return to rather
    than a destination you are "at". Yael disagreed: "please have the lilac
    colour background on the chosen page to appear also when in Home". She is
    right that the exception was arbitrary; six links, six pages, one rule.

    `[href="/"]` is safe to match on because the rule is scoped inside
    `.zNavbar-nav`. The logo is also a link to `/`, but it lives outside that
    list and is not a `.zNav-link`, so it never picks up the block. <*/
:root:has(.mg-here-home)       .zNavbar .zNavbar-nav .zNav-link[href="/"],
:root:has(.mg-here-culture)    .zNavbar .zNavbar-nav .zNav-link[href="/culture"],
:root:has(.mg-here-innovation) .zNavbar .zNavbar-nav .zNav-link[href="/innovation"],
:root:has(.mg-here-impact)     .zNavbar .zNavbar-nav .zNav-link[href="/impact"],
:root:has(.mg-here-team)       .zNavbar .zNavbar-nav .zNav-link[href="/team"],
:root:has(.mg-here-contact)    .zNavbar .zNavbar-nav .zNav-link[href="/contact"] {
  color: var(--navy);
  background: var(--lavender);
  border-radius: 0;
  /*> DRAWN WITH BOX-SHADOW, NOT PADDING — and that is a bug fix, not a
      preference (Yael, 2 Sep, with a phone screenshot: "the lilac background
      on the menu isn't aligned with the text").

      The block used to be `padding: 0.45em 0.7em` cancelled by an equal
      negative margin, which kept the six items on their original spacing on
      desktop. On a phone the bar is a `repeat(3, 1fr)` grid, and there the
      padding pushed the marked item past the width of its 1fr column. The
      link carries `white-space: nowrap`, so instead of wrapping, the TEXT
      overflowed a background box that had been clamped to the column — the
      lavender ended mid-word while "CULTURE" ran on past it.

      A spread box-shadow paints outside the border box and contributes
      nothing to layout, so the item stays exactly as wide as its word and
      can never be clipped by a column. Three shadows rather than one because
      spread is uniform: the extra ±0.25em offsets widen it horizontally to
      the same 0.7em / 0.45em proportions the padding had, so the desktop bar
      looks unchanged.

      `border-radius: 0` because a spread shadow rounds by radius PLUS
      spread — the old 2px would have come out ~7px and turned a deliberately
      square marker into a pill. <*/
  box-shadow:
          0 0 0 0.45em var(--lavender),
     0.25em 0 0 0.45em var(--lavender),
    -0.25em 0 0 0.45em var(--lavender);
}

/*> the block must survive hover, on the current item only. The generic hover
    rule above fades a link toward navy-60 and clears its background — on the
    page you are already on that would make the marker flicker away under the
    cursor. <*/
:root:has(.mg-here-home)       .zNavbar .zNavbar-nav .zNav-link[href="/"]:hover,
:root:has(.mg-here-culture)    .zNavbar .zNavbar-nav .zNav-link[href="/culture"]:hover,
:root:has(.mg-here-innovation) .zNavbar .zNavbar-nav .zNav-link[href="/innovation"]:hover,
:root:has(.mg-here-impact)     .zNavbar .zNavbar-nav .zNav-link[href="/impact"]:hover,
:root:has(.mg-here-team)       .zNavbar .zNavbar-nav .zNav-link[href="/team"]:hover,
:root:has(.mg-here-contact)    .zNavbar .zNavbar-nav .zNav-link[href="/contact"]:hover {
  color: var(--navy);
  background: var(--lavender);
}

.zNavbar .zNavbar-collapse {
  display: flex !important;
  justify-content: flex-end;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
}

/*> five short words fit on two lines at 390px, so the bar never collapses.
    The framework's toggler rendered as an invisible smudge on the navy and
    left the whole site unnavigable on a phone — and a hamburger that needs
    JS to open is a worse bet than simply not needing one. <*/
/*> `.zNavbar .zNavbar-toggler` was NOT enough — the framework's own rule
    carries the theme class (`.zNavbar-light .zNavbar-toggler`), ties on
    specificity, and wins on load order, so the hamburger kept rendering
    above an already-open nav. Matching the theme class puts this at three
    classes, which wins outright without reaching for !important. <*/
.zNavbar.zNavbar-light .zNavbar-toggler,
.zNavbar.zNavbar-dark .zNavbar-toggler,
.zNavbar .zNavbar-toggler { display: none; }


/*> the framework stacks the nav into a column once it is uncollapsed, which
    turned a five-item bar into a 250px-tall wall above the fold on a phone.
    Five short words wrap onto two rows instead. <*/
.zNavbar .zNavbar-collapse .zNavbar-nav {
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
}

/*> tablet-width fix, second half. Restoring the gap above let all six items
    fit their own text again, but the rule directly above allows wrapping
    UNCONDITIONALLY, and at 641–768px six items plus a full var(--s4) gap
    (38.4px × 5 = 192px) genuinely do not fit the available width — "Contact"
    wrapped onto its own line, reintroducing the exact "hangs low" look this
    file already has one write-up for, just from a new cause.

    Forcing nowrap back needs to beat the SAME unconditional rule, which is
    also 3 classes — so this one adds the `zNavBar` tag qualifier zbase.css
    itself uses to win specificity fights, same trick as the gap fix above.
    Tightening the gap to `--s3` in this one band is what makes one row
    actually fit: six items + 5×22.4px = 531px against roughly 574px
    available at 768px, where the full `--s4` gap needed 611px. <*/
@media (min-width: 641px) and (max-width: 860px) {
  zNavBar .zNavbar .zNavbar-collapse .zNavbar-nav,
  .zNavbar .zNavbar-collapse .zNavbar-nav {
    flex-wrap: nowrap;
  }
  zNavBar .zNavbar .zNavbar-nav,
  .zNavbar .zNavbar-nav {
    gap: var(--s3);
  }
}

/*> below 640px five items cannot hold one line, so here — and only here —
    wrapping is allowed, and the bar stops being sticky so it does not eat a
    phone screen. <*/
@media (max-width: 640px) {
  .zNavbar {
    position: static;
    min-height: 0;
    padding: var(--s3) var(--gutter);
    flex-wrap: wrap;
    gap: var(--s2);
  }
  /*> the mark was clipping against the top of the bar: at 38px in a bar with
      only s2 of padding there was nothing left for it to sit in.
      Grown with the desktop mark (24 Aug) but deliberately NOT to the same
      proportion — the phone bar already wraps its six links onto two rows
      beneath the logo, so matching migdalor.de's mobile mark outright would
      push the bar past a third of the screen. 76px of box draws a ~49x61
      mark: a real step up from the old ~28x35, with the rows still fitting. <*/
  /*> only `--brand-box` changes; width, height AND the ink-inset pull are all
      derived from it, so the mark stays aligned at this size too. <*/
  .zNavbar .zNavbar-brand { --brand-box: 76px; }
  .zNavbar .zNavbar-collapse { flex: 1 1 100%; justify-content: flex-start; }
  .zNavbar .zNavbar-collapse .zNavbar-nav { flex-wrap: wrap; gap: var(--s2) var(--s3); }
}

/* ── portfolio: the landing logo grid ─────────────────────────────────── */

/*> every section is a flex column with its own internal rhythm. Without this
    the beam-ruled heading sat flush against its first line of body copy —
    the rule reads as decoration attached to the paragraph rather than as the
    opening of a section. <*/
.mg-approach, .mg-board, .mg-people {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.mg-portfolio { display: flex; flex-direction: column; gap: var(--s4); }

/*> "feels like it exists at the previous section" — Itai, 24 Aug, about the
    portfolio heading on the pillar pages. Promoting it from an eyebrow to an
    H2 (in the views) fixes the SIZE half of that. This fixes the GROUPING
    half.

    The page lays its sections out with a uniform `--s6` gap, so the space
    above this heading and the space below the previous section's last line
    were identical — nothing told the eye which side the heading belonged to.
    Pulling it up by a third of that gap, and letting `.mg-portfolio`'s own
    `--s4` hold it close to the bands underneath, makes the grouping explicit:
    clearly nearer to what it introduces than to what it follows. <*/
.mg-portfolio-title { margin-top: calc(var(--s6) / -3); }

/*> the hairline grid is drawn by each TILE's own outline, not by a coloured
    grid background showing through 1px gaps. Five ventures in a two-column
    mobile grid leave a sixth cell empty, and with the background trick that
    empty cell rendered as a solid grey block — a phantom sixth venture. <*/
/*> ONE SCROLLING ROW, from Yael's sketch: square cards running left to right
    across the whole screen, pillars interleaved rather than grouped, and more
    of them arriving off the right edge as the portfolio grows.
    
    It bleeds the full viewport width but its padding reproduces where the page
    column starts, so the first card lines up with "PORTFOLIO" above it while
    the row itself runs to the edges. That is what makes it read as a strip
    that continues rather than a grid that ended.

    Native horizontal scrolling — trackpad, touch, shift-wheel. The sketch's
    arrows would need a click handler, which means a plugin; the edge fade
    below is the CSS-only way to say "there is more this way". <*/
/*> EDGE TO EDGE, both sides. The row used to open with the same left inset as
    the page column, so the first card lined up under "PORTFOLIO" — but that
    meant a strip meant to feel boundless started behind a wall of margin
    identical to a normal paragraph's. Yael's sketch marks exactly that gap and
    asks for the row to claim it.
    
    "PORTFOLIO" keeps its normal column indent above — only the row of squares
    breaks out to the true edges, which is what makes it read as a gallery
    escaping the page rather than the whole section shifting. <*/
.mg-logo-grid {
  display: flex;
  gap: var(--s3);
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding: var(--s1) 0 var(--s3);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: var(--navy-20) transparent;
  -webkit-overflow-scrolling: touch;
}

/*> the first square still needs SOME clearance from the true edge — flush
    against it reads as a mis-crop, not a deliberate bleed. A spacer the width
    of the ordinary CARD gap (not the page gutter) keeps that clearance
    minimal, so the row reads as genuinely edge-to-edge rather than as the
    same inset in a smaller size. <*/
.mg-logo-grid::before {
  content: '';
  flex: 0 0 var(--s3);
}

/*> THE SWIPE AFFORDANCE — Yael caught this on her phone, 1 Oct 2026: the
    next tile already peeks in from the edge (the gallery was never actually
    fully hiding it), but a flat, fully-saturated square reads as "a finished
    tile", not "content that continues" — the only hint it could scroll was a
    6px scrollbar track, easy to never notice. Rather than add a markup
    element (which would mean touching the zShuttle block — a new sibling
    next to a `zShuttle:` key isn't a pattern used anywhere else in this
    codebase, and isn't worth the risk to test when CSS alone solves it), this
    uses the SAME technique already proven on the leading `::before` spacer
    two rules up: a flex container's `::after` generates as a genuine last
    flex item. `position: sticky; right: 0` keeps it pinned to the visible
    trailing edge of the scrollport AT ANY SCROLL POSITION, not just at rest,
    so the fade reads as "there's more past here" the whole time the user is
    mid-swipe, not only before they start. Fades to `--cream`, the page's own
    background, so it reads as the tile visually receding under the page
    rather than as a tinted overlay sitting on top of it. `pointer-events:
    none` so it never steals a tap meant for the tile underneath. <*/
.mg-logo-grid::after {
  content: '';
  flex: 0 0 56px;
  position: sticky;
  right: 0;
  align-self: stretch;
  background: linear-gradient(to right, transparent, var(--cream));
  pointer-events: none;
}

.mg-logo-grid::-webkit-scrollbar { height: 6px; }
.mg-logo-grid::-webkit-scrollbar-thumb { background: var(--navy-20); border-radius: 3px; }
.mg-logo-grid::-webkit-scrollbar-track { background: transparent; }

/*> SQUARE, per the sketch — and a square is the right shape for a logo wall
    anyway: it treats a wordmark and a monogram even-handedly. <*/
/*> the FLEX ITEM is zShuttle's per-row wrapper, not the tile inside it — which
    is why sizing the tile left the cards staggered at different heights. The
    wrapper carries the width and the snap point; the tile fills it. <*/
.mg-logo-grid > * {
  flex: 0 0 clamp(210px, 23vw, 290px);
  scroll-snap-align: start;
}

/*> the card now uses the SAME mechanism as the three light spots — the pillar
    colour at 72% under `mix-blend-mode: multiply` — rather than a hand-picked
    tint. Matching the technique rather than copying a hex means the two can
    never drift apart: change a disc and the squares follow. <*/
.mg-logo-tile {
  position: relative;
  isolation: isolate;
  background: transparent;
  width: 100%;
  aspect-ratio: 1;
  border-radius: var(--radius-card);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
  padding: var(--s4) var(--s3) var(--s3);
  transition: transform 200ms ease;
}

/*> THE REAL BRAND COLOUR, AT REST AND ON HOVER — Itai, 24 Aug: "get rid of
    the brighter filter, use the real brand colours only, so hover or not it's
    the same colour."

    Two things were making these tiles something other than the brand colour.
    `opacity: 0.72` let the off-white canvas through, and `mix-blend-mode:
    multiply` mixed the two — so a lime tile was never #d6df44, it was lime
    filtered through paper. And hovering lifted the opacity to 0.9, which is
    the brightening he means: the colour visibly shifted under the cursor.
    Both gone. The tile is now exactly `--spot`, in every state.

    The lift on hover stays — it is motion, not colour, and it is what tells
    you the square is clickable at all. <*/
.mg-logo-tile::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--spot);
  z-index: -1;
}

.mg-logo-tile:hover { transform: translateY(-2px); }

/*> THE PILLAR WASH, restored — my rewrite of the grid above deleted it along
    with the layout it was sitting next to. Each card is tinted with its
    pillar's colour, so the row doubles as a legend: you learn the code from
    the three spots and read it along the strip.
    
    Pushed well past the first attempt's opacity. At 16% none of them read as
    a brand colour — lime looked like paper and navy looked like grey. Lime
    and lavender are light enough to take a strong tint; navy needs the most
    before the purple in it shows at all, and it is still the quietest of the
    three. <*/
/*> each pillar just names its colour; the ::before above does the mixing, so
    these are the very same values the discs use. <*/
.mg-pillar-culture    { --spot: var(--pillar-culture); }
.mg-pillar-innovation { --spot: var(--pillar-innovation); }
.mg-pillar-impact     { --spot: var(--pillar-impact); }

/*> EVERY logo and caption in white, on every card. The partner marks arrive
    in their own colours — black, blue — and side by side that reads as five
    unrelated brands rather than one portfolio.
    
    `brightness(0) invert(1)` is what forces a mark of ANY colour to flat
    white: brightness(0) crushes it to black first, whatever hue it started
    as, and invert flips that to white. A bare invert() would only have turned
    FRAMED's blue into its opposite. <*/
/*> MARK COLOUR NOW FOLLOWS THE SURFACE, which is the brand book's own default
    rule (§05): "navy mark on light surfaces, beige mark on navy surfaces."

    This had to change the moment the tiles went to full-strength colour above.
    Uniform white was a defensible call against a 72%-opacity wash; against
    true #d6df44 it is not — the note further down this file already measured
    that pairing at about 1.5:1 and called the caption "decorative rather than
    comfortably legible". Full-strength lime only sharpens that.

    So: navy on the two light pillars (lime, lavender), off-white on the navy
    one. `brightness(0)` crushes each partner's own ink — black, blue —
    to a flat base first, so the chain that follows lands on the same colour
    whatever the mark started as. The `.93` on the inverse is what turns pure
    white into the book's off-white (255 × .93 ≈ 238 = #eeeeea) rather than
    leaving it brighter than any colour in the palette. <*/
.mg-logo-tile .mg-logo-mark {
  filter: brightness(0) saturate(100%) invert(11%) sepia(29%) saturate(3684%)
          hue-rotate(230deg) brightness(94%) contrast(101%);
}

.mg-logo-tile .mg-logo-link { color: var(--navy); }

.mg-pillar-innovation .mg-logo-mark {
  filter: brightness(0) invert(1) brightness(0.93);
}

.mg-pillar-innovation .mg-logo-link { color: var(--cream); }

/*> a FIXED logo box, not a max-height. The marks differ wildly in proportion,
    so sizing each to its own content left every caption at a different height
    down the row. Giving every logo the same box puts all five captions on one
    line — the misalignment Yael spotted. <*/
.mg-logo-mark {
  width: 78%;
  height: 84px;
  object-fit: contain;
  margin: 0;
}

.mg-logo-link {
  order: 2;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--navy-40);
  text-align: center;
  margin: 0;
  transition: color 200ms ease;
}

/*> the "stretched link" trick: the visible caption stays exactly where it
    was — small, centred, below the mark — while an invisible ::after
    covers the WHOLE tile (`.mg-logo-tile` is already `position: relative`
    for the colour-wash ::before) and carries the actual click target. That
    makes the logo mark clickable too, without the caption needing to grow
    or the mark needing its own separate link. <*/
.mg-logo-link::after {
  content: '';
  position: absolute;
  inset: 0;
}

/*> HOVER, per pillar. A single navy rule used to sit here — a leftover from
    when the captions were navy on a pale card — and being later in this sheet
    it beat the white rule above on every card. On lime that read fine; on the
    navy card it turned the caption navy-on-navy and it vanished.
    
    So the hover colour now follows the card: navy on the light ones, lime on
    the dark one. That is the book's signature pairing, and it means the label
    brightens on hover everywhere instead of disappearing on a third of the
    row. <*/
/*> NO COLOUR CHANGE ON HOVER — the rules that used to live here forced every
    mark and caption to white on hover, which was the last thing still shifting
    colour under the cursor after the tile itself was fixed. Removed 24 Aug.

    The history is worth keeping, because it went back and forth: an early pass
    flipped the light cards to navy on hover purely to win contrast, and Yael
    read that as "the text becomes black". The answer then was to make
    everything uniformly white in both states. The answer NOW is better than
    both — the colour is decided by the surface it sits on (see the block
    above) and simply never changes, so there is no hover character shift AND
    no contrast problem to trade against. <*/

/* ── cards: ventures and people ───────────────────────────────────────── */

/*> auto-FILL, not auto-fit. With auto-fit the Impact board's two cards
    stretched to half the page each and their portraits became 700px tall
    columns of lavender. auto-fill keeps the track count set by the page
    width, so two cards and five cards are the same size. <*/
.mg-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: var(--s4);
}

/*> THE TEAM'S THREE PEOPLE GET THREE COLUMNS, ALWAYS. The shared `auto-fill`
    rule above sizes tracks by page width, not by how many cards there are —
    once the shell widened, a big monitor had room for FOUR 250px tracks, so
    three portraits sat left and ~290px of nothing sat on the right. That is
    the empty space Yael saw in full screen.

    Fixed by counting, not by measuring: there are exactly three people, so
    three equal columns fill the row at any width. Deliberately scoped to
    `.mg-people` and NOT applied to `.mg-card-grid` generally — the Impact
    board is the reason `auto-fill` exists here (with `auto-fit` its TWO
    cards stretched to half the page each and their portraits became 700px
    columns of lavender), and it keeps that behaviour untouched.

    Wider cards are the point: the same three faces across the full column
    means more room between them, which is the other half of what was asked
    for. Two columns at tablet, one on a phone — three 250px cards cannot
    share a 342px screen. <*/
.mg-people .mg-card-grid {
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(2rem, 4vw, 4rem);
}

@media (max-width: 860px) {
  .mg-people .mg-card-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 560px) {
  .mg-people .mg-card-grid { grid-template-columns: 1fr; }
}

.mg-card {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  padding-top: var(--s3);
  border-top: 1px solid var(--navy-12);
}

.mg-card-logo {
  width: auto;
  max-width: 70%;
  max-height: 52px;
  object-fit: contain;
  object-position: left center;
  margin-bottom: var(--s1);
}

.mg-card-portrait {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  background: var(--lav-40);
  margin-bottom: var(--s1);
}

/*> the advisory board's photos only — `PersonCard` is shared with the Team
    page, so this is scoped to `.mg-board` rather than to the portrait class
    itself, which would have desaturated Yael, Itai and Jan too. A quieter
    treatment for two placeholder photos on a page that names them as advisors
    rather than staff. <*/
.mg-board .mg-card-portrait {
  filter: grayscale(1);
}

.mg-card-role {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--navy-60);
  margin: 0;
}

.mg-card-blurb, .mg-card-bio {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--navy-80);
  margin: 0;
}

.mg-card-link {
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid var(--navy-40);
  align-self: flex-start;
  padding-bottom: 1px;
}
.mg-card-link:hover { border-bottom-color: var(--navy); }

/*> no venture URLs have been supplied yet, and a zURL with an empty href
    still renders — as a live-looking "Visit Altneuland Press" that goes
    nowhere. A dead link is worse than no link, so the card hides its own
    when there is nothing to point at. Fill the `url` column and the link
    appears on its own. <*/
.mg-card-link:not([href]),
.mg-card-link[href=''],
.mg-card-link[href='#'] { display: none; }

/*> THE TEAM STORY/PHOTO GRID IS GONE (25 Aug). It was a two-column layout —
    headline and story left, group portrait right — plus a set of `order`
    rules so the photo could land under the headline when it stacked on a
    phone. The group photograph became a full-bleed hero instead, so the
    whole grid, its three placement rules and its mobile reordering had
    nothing left to lay out. Removed rather than left dead: `.mg-story-split`,
    `.mg-story-intro`, `.mg-story-copy` and `.mg-story-photo` are now used by
    no view, pattern or test. `.mg-story` below is a different thing and is
    still in use by the landing page. <*/

.mg-story { display: flex; flex-direction: column; gap: var(--s3); align-items: flex-start; }

/*> THE TEAM STORY IS ONE PIECE OF PROSE, FULL WIDTH, ALL ONE SIZE — and there
    is no longer any rule here doing that, which is the point.

    This page was the first to unify its opening paragraph with the ones that
    follow, because its story is one continuous piece rather than a summary
    above a separate section. It needed a local override to fight three caps
    (`.mg-lede`'s 54ch, `.mg-hero-copy`'s 46rem, `.mg-body`'s `--measure`) and
    a type-size override on top.

    All four are gone at source now. The caps were removed when Yael asked for
    full-width opening prose on every page, and on 2 Sep she asked for the
    Team page's single type size site-wide too — "make all text the same size
    and font, like we did in team page". That is `--body-size` up in `:root`.
    The override survived a while as dead weight before this was noticed;
    deleting it changes nothing visually, on this page or any other.

    Worth keeping the trade on record, since full-width prose reverses the
    brand book: this page carries the longest text on the site, and at the
    1600px shell that is roughly 150 characters a line, well past the 50-75
    that reads comfortably. Yael has seen both and prefers this. If it ever
    reads as hard work, the middle option is a raised cap (~90ch) rather than
    none, or two columns. <*/

/*> the prose was pinned to `--measure` (62ch), the same readability cap the
    legal pages use — sensible on its own, but Yael wants THIS paragraph to
    stretch out to the Values section's own right edge, which is wider.
    `.mg-story` sets `align-items: flex-start`, not `stretch`, so a flex item
    with no width of its own already sizes to fill the available column once
    nothing is capping it — removing the cap is the whole fix, no explicit
    width to add or keep in sync with anything. Scoped to `.mg-story` only:
    the legal pages' own `.mg-page-legal .mg-body` override is untouched. <*/
.mg-story .mg-body { max-width: none; }

/* ── forms ────────────────────────────────────────────────────────────── */

.mg-form { max-width: 34rem; }

.mg-form .zDialog-container,
.mg-form .zDialog-form { display: flex; flex-direction: column; gap: var(--s3); }

.mg-form .zDialog-title,
.mg-form .zH {
  font-weight: 700;
  font-size: 1.625rem;
  line-height: 1.25;
}

.zForm-label, .mg-form label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--navy-60);
  margin-bottom: var(--s1);
}

.zForm-control,
.mg-form input, .mg-form textarea {
  width: 100%;
  box-sizing: border-box;
  font-family: inherit;
  font-size: 1rem;
  color: var(--navy);
  background: transparent;
  /*> `color-scheme: light` (above, on html) alone did NOT fix the Safari
      dark-navy-input bug when tested for real (1 Oct) — appearance:none is
      the actual fix: it stops WebKit painting its OWN native control chrome
      (a dark fill, in system Dark Mode) ON TOP of our `background:
      transparent`, which is what was happening. Without it, color-scheme
      changes which native theme WebKit reaches for but doesn't stop it
      reaching for one at all. <*/
  -webkit-appearance: none;
  appearance: none;
  border: 0;
  border-bottom: 1px solid var(--navy-40);
  border-radius: 0;
  padding: 0.6rem 0;
  transition: border-color 140ms ease;
}

.mg-form input:focus, .mg-form textarea:focus {
  outline: none;
  border-bottom-color: var(--navy);
}

/*> THE ACTUAL DARK-FIELD BUG, found 3 Oct 2026 after two wrong diagnoses
    (first "dark mode", then "browser autofill" — both plausible, both
    wrong, because the field is unconditionally transparent EXCEPT once
    FOCUSED, which neither theory explains and both screenshots clearly
    showed). The real cause: zbase.css (the vendor base theme) sets its own
    `background` specifically on `.zForm-control:focus` — not on the base
    state, which is why our earlier `background: transparent` above looked
    completely correct until someone actually clicked into the field.
    zbase.css's whole root palette is a DARK theme by default
    (`--surface-field-focus: #2d2d46`, meant to be overridden per-app, which
    this project never did for the focus state specifically — only the base
    state got a `background` override). Confirmed identical in Safari AND
    Chrome because this is plain CSS cascade, not native browser theming —
    the giveaway that should have been caught sooner. Scoped to the
    universal `.zForm-control` class, not `.mg-form`, so this also protects
    any OTHER zDialog field sitewide that doesn't happen to sit inside a
    `.mg-form`-classed container (the admin editors' own dialogs, for
    instance, never got the `.mg-form` scoping at all). <*/
.zForm-control:focus {
  background: transparent;
}

/*> THE AUTOFILL-SPECIFIC VARIANT, fixed 3 Oct 2026 earlier the same day and
    kept — a genuinely real, separate bug (browser autofill paints its own
    background via a shadow-DOM layer that `background: transparent` above
    cannot reach), just not the one actually being reported. Both fixes are
    needed; neither one alone was sufficient. <*/
.zForm-control:-webkit-autofill,
.zForm-control:-webkit-autofill:hover,
.zForm-control:-webkit-autofill:focus,
.zForm-control:-webkit-autofill:active {
  -webkit-text-fill-color: var(--navy);
  caret-color: var(--navy);
  transition: background-color 600000s ease-in-out 0s;
}

/*> the default placeholder sat at near-white on the cream canvas — legible
    on a monitor at full brightness and nowhere else. navy-40 is the lightest
    tint the brand scale allows for something a person has to read. <*/
.mg-form ::placeholder { color: var(--navy-40); opacity: 1; }

/*> the framework marks required fields with a red asterisk. Red is not in the
    palette — the brand book allows four colours and this is not one of them. <*/
.mg-form .zForm-label span,
.mg-form label span,
.mg-form abbr,
.mg-form [class*='required'] {
  color: var(--navy-40);
  text-decoration: none;
}

.mg-form textarea { min-height: 7rem; resize: vertical; }

/*> the rule sits UNDER the newsletter, not over it: the newsletter now comes
    first on the page (the zDialog gate below it would otherwise swallow it),
    so the divider's job is to separate it from the form that follows. <*/
.mg-form-newsletter {
  border-bottom: 1px solid var(--navy-12);
  padding-bottom: var(--s4);
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  align-items: flex-start;
}
.mg-form-newsletter .zBtn { margin-top: var(--s2); }

/* ── signals ──────────────────────────────────────────────────────────── */

.zSignal, .zAlert, .zToast {
  border-radius: var(--radius);
  padding: var(--s2) var(--s3);
  font-size: 0.9375rem;
  border: 1px solid var(--navy-12);
}
.zSignal-success, .zAlert-success, .zToast-success { background: var(--lime-18); color: var(--navy); }
.zSignal-error, .zAlert-error, .zToast-error { background: var(--lav-40); color: var(--navy); }

/* ── legal pages ──────────────────────────────────────────────────────── */

.mg-page-legal { gap: var(--s4); }
.mg-page-legal .mg-body { max-width: var(--measure); }
.mg-legal-heading { font-size: 1.1875rem; font-weight: 600; margin-top: var(--s3); }

/* ── responsive ───────────────────────────────────────────────────────── */

@media (max-width: 860px) {
  /*> the Team story/photo reordering that lived here is gone with the grid it
      belonged to — the photograph is a full-bleed hero now, which stacks the
      same way at every width and needs no `order` rules to sit under the
      headline. See the note where `.mg-story-split` used to be defined. <*/
  /*> setting the VARIABLE, not `gap` — the footer's cancelling margin and the
      pillar cluster's top margin both derive from it, so they shrink in step
      instead of staying tuned to the desktop value. <*/
  .mg-page { --page-gap: var(--s5); padding-top: var(--s4); }

  /*> THE MOBILE HERO GAP. This rule sets padding-top on .mg-page with no
      exception for the classes carrying it, so it silently overwrote the
      desktop rule at line ~220 that zeroes it for exactly these two page
      types — reopening a gap between the navbar and the full-bleed hero
      image that desktop deliberately closes. Contact and the legal pages
      have no top hero and still want this padding; these three don't.
      (Team joined them on 25 Aug — it used to be in the "no hero" group.) <*/
  .mg-page-landing,
  .mg-page-pillar,
  .mg-page-team,
  .mg-page-open-call { padding-top: 0; }
}

@media (max-width: 560px) {
  /*> a phone cannot afford the desktop disc, and the labels are what break
      first — at 116px a disc was barely wider than the word "INNOVATION",
      so the three words ran into each other across the overlaps. Smaller
      type with less tracking keeps each word inside its own beam.

      `--sep` has to OPEN UP as the discs shrink, not stay put. Clearance at
      a disc's centre is `(--sep - 0.5) × --d`, so halving `--d` halves the
      room the label has; 0.82 buys back what 160px gives away, landing at
      ~52px of clearance for a ~63px word.

      The `min()` is a hard guard against horizontal scroll, not a taste
      call. The cluster is `1.82 × --d` wide and the gutters take 8vw a side,
      leaving 84vw — so the widest disc that can ever fit is `84 / 1.82`, or
      46vw. Below ~348px the vw term wins and the cluster shrinks to stay
      inside; above it the flat 160px caps growth. A fixed px value alone
      would overflow a 360px Android by a few pixels, and on WebKit that
      shows up as the whole PAGE scrolling sideways — the same failure mode
      as the sticky-hero bug in August, which was invisible in Chromium and
      obvious on Yael's iPhone.

      The trade is a shallower meeting point — 0.82 is close to the 0.866
      ceiling where the three stop sharing a point at all, so the lit core
      is thinner here than on desktop. Correct priority: an unreadable
      label is a broken button, while a subtler glow is just a subtler
      glow. <*/
  .mg-pillars {
    --d: min(160px, 46vw);
    --sep: 0.82;
  }
  .mg-pillars .mg-spot {
    font-size: 0.625rem;
    letter-spacing: 0.03em;
  }

  .mg-card-grid { gap: var(--s3); }
}

/* ── values ───────────────────────────────────────────────────────────── */

/*> a full-bleed lavender band, as on the live site. This is the one place the
    brand book's "lavender only as a small accent" guidance is set aside, and
    deliberately: it is the existing design, and navy on full lavender measures
    about 8:1, so the caution is aesthetic rather than a legibility problem.

    Bleeding it edge to edge is what makes it work — as a boxed panel the same
    colour would read as a callout stuck onto the page instead of a change of
    register between two off-white sections. <*/
.mg-values,
.mg-opencall {
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  background: var(--lavender);
  padding: clamp(3.5rem, 8vw, 6rem) 0;
}

.mg-values-inner,
.mg-opencall-inner {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: flex;
  flex-direction: column;
  gap: var(--s5);
}

/*> the beam rule is BACK on this heading. It was dropped when the heading was
    a small eyebrow — a lime bar felt like a third colour on the lavender. As a
    full section title it reads as the same gesture that opens "Our story",
    which is exactly the match Yael asked for. <*/
.mg-values-title { color: var(--navy); }

.mg-value-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(2.5rem, 5vw, 4.5rem) clamp(2.5rem, 6vw, 6rem);
}

.mg-value {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

/*> caps with wide tracking, matching the live site — and it keeps the four
    headings distinct from the H3s used on venture and people cards, which are
    sentence case. Same size, different voice, different job. <*/
.mg-value-title,
.mg-opencall-heading {
  font-size: clamp(1.125rem, 2vw, 1.375rem);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--navy);
  line-height: 1.2;
}

/*> cap removed with the rest (26 Aug). These sit in a two-column grid, so
    "full width" here means filling their own column — the old 42ch stopped
    them well short of it, which read as the same left-hugging problem in
    miniature. <*/
/*> on the shared body size too — "all text in same size". Colour stays full
    navy rather than the navy-80 the other paragraphs use: these sit on the
    lavender band, not on off-white, and the softer ink loses too much
    contrast against it. <*/
.mg-value-body {
  font-size: var(--body-size);
  line-height: var(--body-lead);
  color: var(--navy);
  margin: 0;
}

@media (max-width: 760px) {
  .mg-value-grid { grid-template-columns: 1fr; }
}

/* ── open call (Culture) ──────────────────────────────────────────────── */

/*> AN ANNOUNCEMENT BAND, NAVY. Same edge-to-edge bleed and inner column as
    the homepage values band (the two selectors share those rules above) —
    only the surface differs. Navy rather than lavender because this is the
    one block on the page that should stop the eye, and lime-on-navy is the
    hero's own pairing, so it reads as part of the same voice. Lime on navy
    and cream on navy both clear 10:1, comfortably past what body copy
    needs.

    Colours are set on the classes, not inherited from the band: global `h2`
    and paragraph rules would otherwise win and put navy text on navy. <*/
.mg-opencall { background: var(--navy); }

.mg-opencall .mg-opencall-title { color: var(--lime); }

/*> the intro is the lede's size and leading (`--body-size`, the one shared
    paragraph size) — an announcement is not a place to introduce a third
    type scale. <*/
.mg-opencall .mg-opencall-intro,
.mg-opencall .mg-opencall-lead {
  font-size: var(--body-size);
  line-height: var(--body-lead);
  color: var(--cream);
  margin: 0;
}

.mg-opencall .mg-opencall-heading { color: var(--lime); }

/*> THE ONE BUTTON: lime with navy type, the inverse of the site's usual navy
    button, because a navy button on a navy band would simply vanish. Hover
    swaps to cream instead of brightening — portfolio tiles had a brightening
    hover removed on Itai's review (26 Aug), and the same reasoning applies:
    a state change should be a clear swap, not a subtle tint. `width:
    fit-content` keeps the anchor its natural width when its wrapper is a
    stretched flex child. <*/
.mg-opencall .mg-opencall-cta {
  display: inline-block;
  width: fit-content;
  padding: 0.95em 1.6em;
  background: var(--lime);
  color: var(--navy);
  border-radius: var(--radius);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  transition: background-color 160ms ease;
}
.mg-opencall .mg-opencall-cta:hover,
.mg-opencall .mg-opencall-cta:focus-visible {
  background: var(--cream);
  color: var(--navy);
}

/*> the two buttons sit in a row and wrap on a narrow screen rather than
    shrinking; on the details page the row holds only the apply button. <*/
.mg-opencall-actions { display: flex; flex-wrap: wrap; gap: var(--s2); }

/*> THE SECONDARY BUTTON — "All information & FAQ". Same shape, outline
    instead of fill, so the page has one obvious primary action (apply) and a
    clearly quieter second one. Three classes deep on purpose: it has to beat
    the filled `.mg-opencall .mg-opencall-cta` rule above it, which is two.
    Hover mirrors the primary's (swap to cream, never brighten). <*/
.mg-opencall .mg-opencall-cta.mg-opencall-cta-quiet {
  background: transparent;
  color: var(--lime);
  box-shadow: inset 0 0 0 1.5px var(--lime);
}
.mg-opencall .mg-opencall-cta.mg-opencall-cta-quiet:hover,
.mg-opencall .mg-opencall-cta.mg-opencall-cta-quiet:focus-visible {
  background: var(--cream);
  color: var(--navy);
  box-shadow: inset 0 0 0 1.5px var(--cream);
}

/*> the way back, on the details page. Small, quiet, lime — a text link, not
    a button, so it doesn't compete with the apply button below the headline. <*/
.mg-opencall .mg-opencall-back {
  align-self: flex-start;
  color: var(--lime);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
}
.mg-opencall .mg-opencall-back:hover { color: var(--cream); }

.mg-opencall-process { display: flex; flex-direction: column; gap: var(--s2); }

/*> lists carry no styling of their own anywhere else on the site (the privacy
    policy uses the framework defaults), so everything here is scoped to the
    band. Descendant selectors on `li` rather than on the list element, since
    where `_zClass` lands — the list itself or a wrapper around it — is the
    framework's business, not this stylesheet's. <*/
.mg-opencall .mg-opencall-list,
.mg-opencall .mg-opencall-list li {
  font-size: var(--body-size);
  line-height: var(--body-lead);
  color: var(--cream);
}
.mg-opencall .mg-opencall-list li { margin-bottom: 0.45em; }
.mg-opencall .mg-opencall-list li::marker { color: var(--lime); }

.mg-opencall .mg-opencall-list a {
  color: var(--lime);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}
.mg-opencall .mg-opencall-list a:hover { color: var(--cream); }

.mg-opencall-block { display: flex; flex-direction: column; gap: var(--s2); }

/*> five blocks in two columns leaves one orphan; letting the last — "When
    can I apply?", the block with the dates — run the full width completes
    the grid and gives the deadline its own row instead of a corner. <*/
.mg-opencall-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(2.5rem, 5vw, 4rem) clamp(2.5rem, 6vw, 6rem);
}
.mg-opencall-grid > :last-child { grid-column: 1 / -1; }

@media (max-width: 760px) {
  .mg-opencall-grid { grid-template-columns: 1fr; }
}

/* ── pillar hero: full bleed, same as the landing film ────────────────── */

/*> the landing page bleeds via `.mg-hero-stage`, which wraps the film so an
    overlay can be positioned against it. The pillar pages carry no overlay
    and so have no stage, which left their video boxed inside the shell's
    column while the landing film ran edge to edge. Same measurement, applied
    to the media itself. <*/
.mg-page-pillar .mg-hero-media {
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

/* ── pillar portfolio: full-width venture bands ───────────────────────── */

/*> REBUILT from the live site's treatment. A card grid was making two or
    three ventures look like a thin directory; each one now gets the full
    width of the page.

    The band is one layer: the photograph covers it entirely, and the colour
    panel sits over it clipped on a diagonal, so the two meet on an angle
    rather than a straight seam. Alternate bands mirror — panel left, then
    panel right — which is what stops a page of three reading as a repeated
    template. <*/
.mg-venture-rows {
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  display: flex;
  flex-direction: column;
}

/*> SHORTER BANDS — Itai, 24 Aug: too much empty space above and below the
    text in each venture. Measured against migdalor.de rather than guessed:
    consecutive ventures there sit ~400-440px apart at a 1280px viewport.
    Ours were a flat 580px (46vw, capped), so every band carried ~150px of
    space its content never used.

    This min-height IS the band height, which is the thing worth knowing:
    both the photograph and the panel are absolutely positioned, so neither
    contributes any height of its own — the row would collapse to nothing
    without it. That is also why it cannot simply be deleted in favour of
    letting content size the band.

    ~420px at 1280 now, which lands inside the old site's range. The floor is
    320px so the diagonal still reads on a narrow window, and the content
    (name + blurb + logo ≈ 230px including padding) has clearance at every
    size — checked against FRAMED's blurb, the longest of the five. <*/
.mg-venture-row {
  position: relative;
  min-height: clamp(320px, 33vw, 440px);
  display: block;
  isolation: isolate;
  background: var(--navy);
}

.mg-venture-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

/*> panels alternate lime and lavender down the page rather than following the
    pillar's own colour. That is what the live site does, and it is the right
    call here too: navy is doing the work behind the photograph, and a navy
    panel would need cream type, breaking the one rule the brand book is
    absolute about — navy carries the text. Pillar identity is already carried
    by the three spots and the card washes on the landing page. <*/
/*> every panel came out lime on the first pass. zShuttle wraps each repeat in
    its own element, so `.mg-venture-row:nth-child(even)` never matched — each
    row is an only child and therefore always :nth-child(1). Counting is done
    on the ROW LIST's children instead, and both shapes are written out so the
    alternation holds whether or not the wrapper is there. <*/
.mg-venture-rows > :nth-child(odd) .mg-venture-panel,
.mg-venture-rows > .mg-venture-row:nth-child(odd) .mg-venture-panel {
  background: var(--lime);
}

.mg-venture-rows > :nth-child(even) .mg-venture-panel,
.mg-venture-rows > .mg-venture-row:nth-child(even) .mg-venture-panel {
  background: var(--lavender);
}

/*> ONE CONTINUOUS LINE, not a zigzag. The previous version alternated the
    slant — 54%→46% down one band, then 46%→54% back down the next — so the
    edge reversed direction at every seam. The seams met, but the result read
    as a stack of opposed wedges rather than as a single idea, which is what
    Yael saw as messy.

    Now the line never turns. It starts a little right of centre, leans left
    by three points per band, and crosses exactly 50% in the middle of the
    stack; the COLOUR flips from one side of it to the other, but the line
    itself carries straight on down the page. That is what the live site does
    and why its meeting points sit in the middle of the screen.

    To make that expressible, the panel is now full-width and absolutely
    placed, with the clip cutting it to the left or right of the line. The
    edge positions are therefore plain percentages OF THE ROW — the same
    number means the same place on every band, whichever side its colour is
    on — instead of percentages of a half-width panel that had to be
    converted each time. <*/
.mg-venture-panel {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  clip-path: polygon(0 0, var(--edge-top) 0, var(--edge-bot) 100%, 0 100%);
}

.mg-venture-rows > :nth-child(even) .mg-venture-panel,
.mg-venture-rows > .mg-venture-row:nth-child(even) .mg-venture-panel {
  clip-path: polygon(var(--edge-top) 0, 100% 0, 100% 100%, var(--edge-bot) 100%);
}

/*> A WIDE ARROW. Every seam now lands on exactly 50% — dead centre of the
    screen — and the edge leans back the other way through each band, so two
    neighbouring bands form one shallow chevron pointing at the middle.
    That is the live site's shape.
    
    It is worth being precise about why this is not the zigzag from two
    revisions ago. That one alternated between 46% and 54% AT THE SEAMS, so
    the meeting points swung from side to side and never settled. Here the
    meeting point is fixed at the centre and it is the band MIDDLES that
    alternate — the eye locks onto the constant point instead of chasing it.

    Because every band runs 54%→50% or 50%→54%, this needs no per-position
    values and works for a portfolio of two, three or ten. <*/
.mg-venture-rows > :nth-child(odd),
.mg-venture-rows > .mg-venture-row:nth-child(odd) { --edge-top: 54%; --edge-bot: 50%; }

.mg-venture-rows > :nth-child(even),
.mg-venture-rows > .mg-venture-row:nth-child(even) { --edge-top: 50%; --edge-bot: 54%; }

/*> the text column sits inside whichever side its colour occupies, held off
    the diagonal so a line of type never runs into the angle. <*/
/*> padding trimmed with the band height above — it was sized for a 580px
    band, and left inside a ~420px one it would have eaten most of the space
    the shorter band was meant to save. Horizontal padding is untouched: it
    holds the text off the diagonal, which has not changed. <*/
.mg-venture-panel-inner {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  width: 50%;
  padding: clamp(1.75rem, 3.2vw, 3rem) clamp(2.5rem, 5vw, 4.5rem);
  padding-right: clamp(3rem, 6vw, 5rem);
  margin: 0;
}

.mg-venture-rows > :nth-child(even) .mg-venture-panel-inner,
.mg-venture-rows > .mg-venture-row:nth-child(even) .mg-venture-panel-inner {
  margin-left: auto;
  padding-right: clamp(2.5rem, 5vw, 4.5rem);
  padding-left: clamp(3rem, 6vw, 5rem);
}

.mg-venture-name {
  font-size: 0.9375rem;
  font-weight: 400;
  color: var(--navy-80);
  margin: 0;
}

/*> THE LOGO IS THE LINK. There used to be a big underlined venture name here
    directly under the plain one — the same words twice, which read as a bug.
    The mark now carries the outbound link: this box is the positioning
    context, and `.mg-venture-link` stretches an invisible anchor across it. <*/
.mg-venture-mark {
  position: relative;
  display: inline-block;
  align-self: flex-start;
  margin-top: var(--s2);
  line-height: 0;
  transition: opacity 200ms ease, transform 200ms ease;
}

/*> the anchor covers the mark and its label is pushed out of view rather than
    deleted — a bare linked image would leave screen readers reading the file,
    so the accessible name stays "Visit <venture>". text-indent (not
    display:none, not width:0) is what keeps it both reachable and unseen.

    CHILD selector, deliberately. Written flat as `.mg-venture-link` this rule
    caught the anchor even when the mark wrapper had not rendered — and then
    `inset: 0` resolved against `.mg-venture-panel` instead, quietly turning
    the ENTIRE 1280x580 band into one click target that still looked correct.
    Scoping it to the wrapper means a missing wrapper degrades to a plain
    visible link rather than an invisible page-wide one. <*/
.mg-venture-mark > .mg-venture-link {
  position: absolute;
  inset: 0;
  text-indent: -200vw;
  overflow: hidden;
  white-space: nowrap;
}

.mg-venture-mark:hover { opacity: 0.72; transform: translateY(-2px); }

/* a venture with no URL yet keeps its logo, minus the pretence of a link */
.mg-venture-link:not([href]),
.mg-venture-link[href=''],
.mg-venture-link[href='#'] { pointer-events: none; }

.mg-venture-mark:has(.mg-venture-link:not([href])):hover,
.mg-venture-mark:has(.mg-venture-link[href='']):hover,
.mg-venture-mark:has(.mg-venture-link[href='#']):hover {
  opacity: 1;
  transform: none;
}

/*> on the shared body size too, but full navy rather than navy-80: this sits
    on a lime or lavender panel, not on off-white.

    Worth watching — the venture band's height is a fixed `min-height` and
    the panel is absolutely positioned, so this text cannot push the band
    taller if it needs another line. Checked against FRAMED, the longest of
    the five, with room to spare at the current ~420px band. A materially
    longer blurb would need the band height revisited, not the type. <*/
.mg-venture-blurb {
  font-size: var(--body-size);
  line-height: var(--body-lead);
  color: var(--navy);
  max-width: 44ch;
  margin: 0;
}

/*> the band logos are forced to brand NAVY, not left in each partner's own
    ink. Five marks in five different colours — black, blue — read as five
    unrelated brands stacked down the page; in navy they match the venture
    name directly above them and the panel becomes one object.
    
    `brightness(0)` crushes any hue to black first, then the sepia→saturate→
    hue-rotate chain tints that black to #1c194b. A plain `invert` or a colour
    overlay could not do this: only this chain works on an arbitrary source
    colour without knowing what it started as. <*/
.mg-venture-logo {
  width: auto;
  max-width: 190px;
  max-height: 84px;
  object-fit: contain;
  object-position: left center;
  margin-top: 0;
  display: block;
  filter: brightness(0) saturate(100%) invert(11%) sepia(29%) saturate(3684%) hue-rotate(230deg) brightness(94%) contrast(101%);
}

/*> below 860px the diagonal stops working: at that width the angle eats most
    of the panel and the text column collapses. The band becomes a stack —
    photograph, then panel, square edges. <*/
@media (max-width: 860px) {
  .mg-venture-row {
    display: block;
    min-height: 0;
    justify-content: flex-start;
  }
  .mg-venture-photo {
    position: relative;
    height: clamp(220px, 52vw, 340px);
  }
  /*> the panel is absolutely placed over the photo on desktop; stacked, it
      has to come back into flow or it would sit on top of the image with no
      height of its own. <*/
  .mg-venture-rows .mg-venture-panel,
  .mg-venture-rows > :nth-child(even) .mg-venture-panel {
    position: static;
    width: 100%;
    clip-path: none;
  }
  .mg-venture-rows .mg-venture-panel-inner,
  .mg-venture-rows > :nth-child(even) .mg-venture-panel-inner {
    width: 100%;
    padding: clamp(2rem, 7vw, 3rem) var(--gutter);
    margin: 0;
  }

  /*> THE NAVY SLAB BESIDE THE STACKED PHOTOS, and it is not a CSS bug — it is
      painted INTO these four source files. Each is 1760x800 with a flat navy
      block filling 43.2% of its width, so that on desktop the diagonal panel
      lands on top of it and the seam between panel and photograph is exact.
      Stacked, the panel moves below the image and that slab is left showing.
      Inspecting computed styles finds nothing wrong, which is why an earlier
      pass here wrongly blamed a stale cache.

      Measured, not guessed: the photograph is exactly 1000x800 in all four
      (aspect 1.250) and the navy is on the LEFT where the row is odd, on the
      RIGHT where it is even — matching the side the desktop panel covers.
      Giving the box that same 1.250 aspect makes `object-fit: cover` discard
      precisely 43.2% of the width, and `object-position` picks which end goes,
      so what survives is the photograph alone, full-bleed, nothing scaled or
      squashed.

      Written at the STACKING breakpoint (860px), not a phone-only one: the
      slab is exposed the moment the row stacks, which includes tablet.
      Desktop is above this query and is not touched.

      Targeted by filename rather than by :nth-child parity on purpose —
      `altneuland-wide-c.jpg` carries NO navy block (it was exported without
      one) and needs no CROP. A new venture image following the 1760x800
      convention needs adding to the matching list below.

      It DOES still need the shared height, though — Yael caught this as a
      follow-up: leaving it on the old `clamp(220px, 52vw, 340px)` floor
      while these four moved to a fixed 1.25 aspect made Altneuland's row
      render at 220px against the others' 312px, an inconsistency this fix
      itself introduced. It's listed here for the shared box shape even
      though it needs none of the cropping below — `object-position` stays
      at its default centre, evenly trimming its wider 2.2 aspect mosaic
      rather than favouring an edge that (unlike the other four) isn't
      hiding anything. <*/
  .mg-venture-photo[src*="framed-wide-c"],
  .mg-venture-photo[src*="malebeing-wide-c"],
  .mg-venture-photo[src*="lowswing-wide-c"],
  .mg-venture-photo[src*="musicalbeings-wide-c"],
  .mg-venture-photo[src*="altneuland-wide-c"] {
    height: auto;
    aspect-ratio: 1000 / 800;
  }

  /* navy on the LEFT — keep the right end */
  .mg-venture-photo[src*="framed-wide-c"],
  .mg-venture-photo[src*="malebeing-wide-c"] { object-position: right center; }

  /* navy on the RIGHT — keep the left end */
  .mg-venture-photo[src*="lowswing-wide-c"],
  .mg-venture-photo[src*="musicalbeings-wide-c"] { object-position: left center; }
}


/*> STICKY HERO — TRIED AND ABANDONED. Three passes lived here across
    zRaven c39-c45: a separate strip on a flat tint, then on a slice of the
    hero photo, then finally the hero itself (`.mg-hero-pin`, wrapping Stage)
    pinned while the rest of the page scrolled underneath it. Yael tried the
    last version live and asked to drop the idea entirely — the pillar hero
    is back to a plain, non-sticky block that scrolls away with the page,
    same as every other section. Left as a note rather than silence, since
    the next person to feel like "the hero should stay while you scroll" is
    one screenshot away from redoing this whole exploration from scratch. <*/

/* ── pillar hero overlay + ambient film ───────────────────────────────── */

/*> the eyebrow on a pillar hero sits on the scrim, not on off-white, so it
    takes the lavender the landing page's MIGDALOR mark uses rather than the
    navy-60 it has on a light background. <*/
.mg-hero-overlay .mg-hero-mark-eyebrow { color: var(--lavender); }

/*> ONE RULE FOR BOTH HERO FILMS, since 16 Sep — Culture and the homepage used
    to be treated differently, and the story of why they're now the same is
    worth keeping.

    Both films hit the identical iOS Safari limitation: no `playsinline`, so
    no silent autoplay on an iPhone (zVideo's CDN renderer hardcodes
    `controls = true` and never sets it — confirmed against the actual
    renderer source, not assumed). Culture's ORIGINAL fix, when it was the
    only hero film on the site, hid the video entirely below 640px and
    showed a plain photo instead. That solved the symptom but cost a real
    feature — a phone visitor never saw the film at all, autoplay or not.

    `plugins/ios_inline_video.js` fixes the actual cause instead of routing
    around it: it sets `playsinline` on any autoplaying video the moment it
    lands in the DOM, which is the one thing zVideo's own renderer can't do.
    Once that exists, hiding the video on phones stops being necessary —
    `<video controls poster="...">` is a normal, working player on iPhone
    even in the rare case the plugin's autoplay kick loses the race, exactly
    like any other video on the web (one tap, per Apple's own policy, not a
    bug). Culture's Poster/Film swap-by-width was retired the same day this
    plugin landed, and its old mobile photo (`culture-hero-mobile.jpg`) was
    repointed to zVideo's own `poster:` key instead of deleted — same asset,
    new job: the frame shown before the plugin's play() call resolves,
    rather than a permanent stand-in for a video that never played.

    Hiding native controls and disabling pointer events is what makes the
    film read as ambient set dressing, not a thing to operate — and until
    22 Sep that only happened at desktop width, ON PURPOSE: below 640px the
    controls were left visible as a safety net, in case the plugin's
    autoplay kick lost the race on some phone and a visitor needed something
    to tap. That hedge is gone now, not because the risk stopped existing,
    but because Yael tested this on her own real iPhone and reported the
    opposite problem — the video autoplays correctly, and the leftover play
    icon just sits uselessly on top of a film that is already playing. A
    visible control for a decision nobody needs to make is worse than the
    small residual risk of a phone somewhere hitting the rare case with
    nothing to tap. Unconditional now, every width, both pages. <*/
.mg-page-landing .mg-hero-media[autoplay],
.mg-page-pillar .mg-hero-media[autoplay] {
  pointer-events: none;
}

/*> DEMOTED TO A SAFETY NET, 22 Sep — this used to be the primary fix, and
    it kept losing: `-start-playback-button` hid the control bar's play
    button, so `-overlay-play-button` was added for the separate bigger
    circular icon WebKit centers on the video, and iOS STILL showed a
    control neither name reached (confirmed — Yael tested on her own
    iPhone twice, after each round). Enumerating shadow-DOM pieces one at a
    time is chasing symptoms of a cause CSS was never going to reach.

    The actual fix now lives in `plugins/ios_inline_video.js`: it sets the
    video's `controls` PROPERTY back to `false`, so the browser never
    builds native playback UI in the first place — nothing left for any of
    these selectors to find. They stay here as a below-the-JS fallback
    (in case the plugin script is blocked, or hasn't run yet on a slow
    connection) rather than as the thing actually doing the work. <*/
.mg-page-landing .mg-hero-media::-webkit-media-controls,
.mg-page-landing .mg-hero-media::-webkit-media-controls-enclosure,
.mg-page-landing .mg-hero-media::-webkit-media-controls-panel,
.mg-page-landing .mg-hero-media::-webkit-media-controls-play-button,
.mg-page-landing .mg-hero-media::-webkit-media-controls-start-playback-button,
.mg-page-landing .mg-hero-media::-webkit-media-controls-overlay-play-button,
.mg-page-pillar .mg-hero-media::-webkit-media-controls,
.mg-page-pillar .mg-hero-media::-webkit-media-controls-enclosure,
.mg-page-pillar .mg-hero-media::-webkit-media-controls-panel,
.mg-page-pillar .mg-hero-media::-webkit-media-controls-play-button,
.mg-page-pillar .mg-hero-media::-webkit-media-controls-start-playback-button,
.mg-page-pillar .mg-hero-media::-webkit-media-controls-overlay-play-button {
  display: none !important;
  -webkit-appearance: none;
}

/* ── footer ───────────────────────────────────────────────────────────── */

/*> laid out from the live site's footer: wordmark alone at the top, three
    labelled columns on ONE baseline, then socials and copyright closing it.
    
    The gap above it was crossed out in review and it was genuinely too big —
    the page already ends with a full-bleed band, so it was carrying both the
    section gap AND the footer's own top margin. The margin goes. <*/
.mg-footer {
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  /*> no margin-top. The footer is the last flex child of `.mg-page`, so
      `.mg-page`'s own `gap: var(--s6)` (104px) already opens a normal
      section-sized space above it — the SAME gap every other pair of
      sections gets. Adding a further margin-top here was stacking a SECOND
      gap on top of that one, which is what produced the oversized blank
      band between the values section and the footer that Yael flagged. <*/
  background: var(--cream);
  color: var(--navy);
  border-top: 1px solid var(--navy-12);
  padding: clamp(3rem, 5vw, 4.5rem) 0 clamp(2rem, 3vw, 3rem);
}

.mg-footer-inner {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: flex;
  flex-direction: column;
  gap: clamp(2.5rem, 4vw, 3.5rem);
}

/*> same asset, same correction as the navbar brand: the wordmark sat ~17px
    right of "MORE INFO" and the hairline beneath it, because the PNG carries
    its own empty margin. `object-fit: contain` on a square box reproduces
    that padding exactly, so the pull is the same fraction of the same box. <*/
.mg-footer-mark {
  --brand-box: 92px;
  width: var(--brand-box);
  height: var(--brand-box);
  object-fit: contain;
  margin-left: calc(var(--brand-box) * var(--brand-ink-inset) * -1);
}

/*> equal columns, all starting at the same height. `align-items: start` is
    what actually holds the three headings on one line — without it a taller
    column stretches its neighbours and the baselines drift. <*/
.mg-footer-cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s5);
  align-items: start;
}

.mg-footer-col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s2);
}

/*> the short rule under each heading is the live footer's own device, and it
    is the same gesture as the beam rule opening a section — just navy here,
    because three lime bars in a quiet footer would shout. <*/
.mg-footer-heading {
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--navy);
  margin: 0 0 var(--s2);
  padding-bottom: var(--s2);
  position: relative;
  width: 100%;
}

.mg-footer-heading::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 56px;
  height: 1px;
  background: var(--navy-40);
}

.mg-footer-link {
  font-size: 0.9375rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--navy);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 160ms ease;
}

.mg-footer-link:hover { border-bottom-color: var(--navy); }

.mg-footer-address {
  font-size: 0.9375rem;
  line-height: 1.8;
  color: var(--navy-80);
  margin: 0;
  max-width: 34ch;
}

.mg-footer-address strong {
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 0.8125rem;
  color: var(--navy);
}

.mg-footer-address a { color: var(--navy); text-decoration: none; border-bottom: 1px solid var(--navy-40); }
.mg-footer-address a:hover { border-bottom-color: var(--navy); }

.mg-footer-blurb {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--navy-80);
  max-width: 32ch;
  margin: 0;
}

/*> kept exactly as it was — navy ground, lime type. Yael asked for this one
    not to change. <*/
.mg-footer-subscribe { margin-top: var(--s2); }

/* ── closing row ── */

.mg-footer-base {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  padding-top: var(--s4);
  border-top: 1px solid var(--navy-12);
}

/*> real glyphs, not words. zMD renders `<bi-instagram>` as a Bootstrap icon
    and the surrounding markdown link makes it clickable — so these are icons
    that are genuinely links, with no image asset and no external request. <*/
.mg-footer-social {
  display: flex;
  gap: var(--s3);
  font-size: 1.375rem;
  line-height: 1;
  margin: 0;
}

/*> the glyph replaces the label. The text is pushed out of the box rather
    than deleted, so "Instagram" is still the anchor's accessible name while
    the eye gets the mark. Codepoints read straight out of bootstrap-icons
    1.11.3 rather than guessed — the font is already loaded by the framework,
    so this costs no asset and no extra request. <*/
.mg-social-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  color: var(--navy);
  text-decoration: none;
  overflow: hidden;
  text-indent: -100vw;
  transition: color 160ms ease, transform 160ms ease;
}

.mg-social-link::before {
  font-family: 'bootstrap-icons';
  font-style: normal;
  font-weight: normal;
  font-size: 1.375rem;
  line-height: 1;
  text-indent: 0;
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mg-social-instagram::before { content: "\f437"; }
.mg-social-linkedin::before  { content: "\f472"; }

.mg-social-link:hover { color: var(--navy-60); transform: translateY(-1px); }

.mg-footer-copy {
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--navy-60);
  margin: 0;
}

@media (max-width: 860px) {
  .mg-footer-cols { grid-template-columns: 1fr; gap: var(--s4); }
  .mg-footer-base { flex-direction: column; align-items: flex-start; gap: var(--s3); }
}




/* ── contact rows ─────────────────────────────────────────────────────── */

/*> replaces the enquiry form: one row per destination, label beside address.
    A grid rather than a paragraph of links, so the labels form a column you
    can scan for the one you want. <*/
.mg-contact-rows {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  border-top: 1px solid var(--navy-12);
  padding-top: var(--s4);
  max-width: 34rem;
}

.mg-contact-row {
  display: grid;
  grid-template-columns: 9rem 1fr;
  gap: var(--s3);
  align-items: baseline;
}

.mg-contact-label {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--navy-60);
  margin: 0;
}

.mg-contact-address {
  font-size: clamp(1.0625rem, 1.6vw, 1.1875rem);
  margin: 0;
}

.mg-contact-address a {
  color: var(--navy);
  text-decoration: none;
  border-bottom: 1px solid var(--navy-40);
  transition: border-color 160ms ease;
}

.mg-contact-address a:hover { border-bottom-color: var(--navy); }

@media (max-width: 560px) {
  .mg-contact-row { grid-template-columns: 1fr; gap: var(--s1); }
}

/* ── the empty band above the footer ──────────────────────────────────── */

/*> THE EMPTY BAND ABOVE THE FOOTER. A full-bleed section already ends on its
    own hard colour edge, so `.mg-page`'s section gap after it rendered as a
    slab of blank off-white between that edge and the footer's hairline —
    visible on nearly every page.

    A negative margin equal to the gap is what cancels it: flex `gap` cannot
    be overridden per-child, so the child pulls itself back up by exactly the
    distance the gap pushed it down. Only where the footer FOLLOWS a bled
    section — elsewhere the normal gap is still wanted.

    `.mg-venture-rows + .mg-footer` never actually matched anything — on
    Culture/Innovation the venture bands are nested INSIDE `.mg-portfolio`
    (Heading, then Rows), so `.mg-portfolio`, not `.mg-venture-rows`, is the
    element that is actually adjacent to `.mg-footer` in the flex column.
    The selector was targeting a grandchild instead of the real sibling —
    still true, still zero effect, exactly the gap Yael kept seeing. <*/
.mg-values + .mg-footer,
.mg-opencall + .mg-footer,
.mg-portfolio:has(.mg-venture-rows) + .mg-footer {
  margin-top: calc(var(--page-gap) * -1);
}

/* ── phone: the bar and the film ──────────────────────────────────────── */

/*> THE NAVBAR HAD NO PHONE TREATMENT AT ALL. Six items at desktop tracking
    cannot sit on a 390px line, so they broke to two ragged rows under the
    wordmark and read as something half-finished rather than a menu.

    Kept as ONE row rather than introducing a hamburger: six short words fit
    once the tracking and size come down, and a visible bar beats a hidden
    one on a site this shallow — every destination stays one tap away. The
    row may still scroll on the narrowest phones, which is a graceful last
    resort rather than the layout. <*/
@media (max-width: 640px) {
  /*> BESIDE THE LOGO, NOT UNDER IT (Yael, 2 Sep: "maybe we could try putting
      the 6 titles on the right side of the logo instead of under").

      `nowrap` is the whole change at this level — the bar was wrapping
      because the rule at the 860px breakpoint gives `.zNavbar-collapse`
      `flex: 1 1 100%`, which forces it onto its own line. Overridden just
      below. <*/
  .zNavbar {
    min-height: 0;
    padding-top: var(--s2);
    padding-bottom: var(--s2);
    flex-wrap: nowrap;
    align-items: center;
    gap: var(--s3);
  }

  .zNavbar .zNavbar-brand { flex: 0 0 auto; }

  /*> `min-width: 0` matters: a flex item defaults to `min-width: auto`, which
      refuses to shrink below its content — and since every link carries
      `white-space: nowrap`, without this the menu would push the bar wider
      than the screen rather than staying inside it. <*/
  .zNavbar .zNavbar-collapse {
    flex: 1 1 auto;
    min-width: 0;
    justify-content: flex-end;
  }

  /*> THE SELECTOR MUST CARRY `.zNavbar-collapse`. The wrapping rule above in
      this file is `.zNavbar .zNavbar-collapse .zNavbar-nav` — three classes,
      which beats a two-class selector no matter how far down the file it
      sits. Two earlier attempts here (plain `.zNavbar .zNavbar-nav`, then
      adding `display: flex !important`) changed nothing for exactly that
      reason; display was never the problem, specificity was.

      That older rule deliberately let the bar run to two lines instead of
      collapsing to a hamburger — a good call when the bar held FIVE items.
      A sixth (Home) was added since, and six broke 4+2, which reads as an
      accident rather than a choice.

      Forcing one row was tried and rejected: six items measure ~312px of
      type against ~327px of bar, so the line only fits by shrinking to ~10px
      or letting CONTACT scroll off half-clipped — and Contact is the last
      link that should be hard to reach. Hamburger still avoided, per the
      original reasoning — a menu that needs JS to open is a worse bet.

      TWO columns now, not three, because the menu moved up beside the logo
      (2 Sep) and no longer has the full width to spend. The arithmetic: a
      390px screen leaves ~328px inside the gutters, the logo takes 76px and
      the gap 22px, so the menu has ~230px. Three columns would need ~255px
      of type before gaps — INNOVATION alone is ~83px — so it does not fit.
      Two columns of three rows do, and they come out ~74px tall against a
      76px logo, which is why the bar now reads as one block rather than a
      logo with something stacked beneath it.

      Columns are `auto`, not `1fr`, so each is only as wide as its own
      longest word and the pair hugs the right edge instead of stretching
      into even halves with a gap down the middle. Row-major order keeps the
      reading sequence intact: Home / Culture, then Innovation / Impact, then
      Team / Contact. <*/
  .zNavbar .zNavbar-collapse .zNavbar-nav {
    display: grid;
    grid-template-columns: repeat(2, auto);
    width: auto;
    gap: var(--s2) var(--s3);
    justify-items: start;
    /*> BOTH of these are needed, because the wrapper's display type is the
        framework's to decide, not ours. If `.zNavbar-collapse` is a flex
        container the grid is a flex item sized to its content, and only
        `margin-left: auto` pushes it over; if it is a plain block the grid
        fills the width instead, and only `justify-content` moves the tracks.
        The first attempt set just `justify-content` and the menu sat
        stranded mid-bar. Together they land it on the right gutter either
        way — logo left, menu right, same shape as desktop. <*/
    margin-left: auto;
    justify-content: end;
  }

  .zNavbar .zNavbar-nav::-webkit-scrollbar { display: none; }

  /*> two rows buy back the room a single line didn't have, so the type stays
      readable rather than shrinking to fit. <*/
  .zNavbar .zNavbar-collapse .zNavbar-nav .zNav-link {
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    white-space: nowrap;
  }

  /*> ONE GROUP PHOTO INSTEAD OF THREE PORTRAITS (Yael, 2 Sep, phone only).
      Three columns on a 390px screen leave each face ~110px — small enough
      that they stop reading as people. The joint shot takes the full column
      instead, and the names become a plain list beneath it.

      The names stack rather than sitting in a row of three: "Yael Nachshon
      Levin / Co-founder / Managing Director" cannot fit a 110px column
      without wrapping to four lines. Stacking also sidesteps a mismatch —
      the reel runs Yael, Itai, Jan, while the photograph reads Jan, Itai,
      Yael left to right, so a horizontal row would invite the eye to pair
      them up wrongly. A vertical list makes no such promise. <*/
  .mg-story-group {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    border-radius: var(--radius);
    margin-bottom: var(--s3);
  }

  .mg-story-people { grid-template-columns: 1fr; gap: var(--s2); }
  .mg-story-person-photo { display: none; }

  /*> JAN, YAEL, ITAI under the group shot — Yael's order, 2 Sep, and only
      here. The desktop three-up keeps the reel's own order (Yael, Itai,
      Jan), so this is a presentation change on phones rather than a change
      to the data.

      `order` on the grid children rather than a re-sorted reel, because the
      reel feeds both layouts and the Team page as well; re-sorting it to fix
      this list would silently reorder all three.

      The catch: this addresses people by POSITION, so it is only correct
      while the reel returns Yael, Itai, Jan. A future edit to the team could
      leave the names in a meaningless order with nothing visibly broken.
      `Home_Story_People_Order` in the raven asserts that DOM order, so the
      assumption fails loudly and points back here. <*/
  .mg-story-people > *:nth-child(3) { order: 1; }   /* Jan   */
  .mg-story-people > *:nth-child(1) { order: 2; }   /* Yael  */
  .mg-story-people > *:nth-child(2) { order: 3; }   /* Itai  */

  /*> name and role on one line now that there is no portrait above them —
      `baseline` so the smaller role type sits on the name's baseline rather
      than floating, and `wrap` so a long pairing breaks cleanly instead of
      overflowing. <*/
  .mg-story-person {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.15em 0.5em;
  }

  /*> RETIRED 22 Sep, with the second half of the lighthouse placeholder's
      crop tuning — the first half (`center 22%`, desktop) was retired when
      the new hero video landed on 16 Sep; this mobile-only twin was missed
      in that pass, which is exactly what its own comment warned about
      ("revisit this number whenever the landing film changes"). Yael
      reported the new video "somehow not centered" on her phone — this
      72%-right bias, tuned for the OLD lighthouse tower sitting off to one
      side, is why: it was pushing an unrelated video's crop off-center.
      Landing now defaults to plain center cropping on phones too, matching
      desktop and the pillar heroes. <*/

  /*> a full-height film on a phone is a screen and a half of sky before any
      words appear. Shorter here, so the headline and the first line of copy
      arrive together. <*/
  .mg-page-landing .mg-hero-media,
  .mg-page-pillar .mg-hero-media,
  .mg-page-team .mg-hero-media { height: min(62vh, 520px); }
}

/* ── the narrowest phones ─────────────────────────────────────────────── */

/*> A 320px SCREEN OVERFLOWS BY 3px, and with the bar now `nowrap` that is
    not a cosmetic problem — it widens the page and WebKit scrolls the whole
    document sideways. Same failure as the sticky hero in August: invisible
    in Chromium, immediately obvious on a real iPhone.

    The arithmetic, using the real tokens: a 320px screen keeps 268.8px
    inside its gutters, while logo (76) + gap (22.4) + INNOVATION column
    (84) + gap (22.4) + CONTACT column (67) needs 271.8. Three pixels.

    Buying them back from the GAPS and the logo rather than the type — the
    links are already at 12px and shrinking them further to rescue a layout
    is how a menu becomes unreadable. At these values the same bar needs
    ~241px and clears with ~28px to spare, so it also survives the 300px
    edge cases and any future word longer than INNOVATION.

    Scoped to 360px rather than 320px so there is real headroom above the
    failure point, not a fix that is itself borderline. <*/
@media (max-width: 360px) {
  .zNavbar { gap: var(--s2); }
  .zNavbar .zNavbar-brand { --brand-box: 64px; }
  .zNavbar .zNavbar-collapse .zNavbar-nav { gap: var(--s2); }
}

/* ── the editor family: a plain, functional internal tool ────────────────── */

/*> NO STYLING PASS HAS TOUCHED THESE PAGES, and that is deliberate — they are
    an internal tool for two people, not part of the public site, and every
    hour spent polishing an admin form is an hour not spent on what visitors
    see. The one rule below exists only so `%EditorNav:`'s six links don't
    render as a single unreadable column; everything else here rides the
    site's ordinary `.mg-page`/`zBtn`/`zDialog` defaults untouched. <*/
.mg-editor-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin: var(--s4) 0;
  padding-top: var(--s3);
  border-top: 1px solid var(--navy-12);
}

/*> an entity-index page's own grouped link lists (Ventures' Culture/
    Innovation groups, now People's Team/Board groups too) — same flex-wrap
    shape as `.mg-editor-nav` above, deliberately a SEPARATE class (not a
    shared one) so a selector counting one group's links can never
    accidentally pick up the other's, or another index page's. No top
    border/margin here: these sit directly under their own "Culture"/
    "Team"/etc. heading, not at the foot of the page like the shared nav. <*/
.mg-editor-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-bottom: var(--s4);
}

/* ── connection badge ─────────────────────────────────────────────────── */

/*> Yael spotted this, 2 Oct 2026: a small "● Connected" chip, fixed to the
    bottom corner of every page. It's `<zbifrostbadge>` — the Bifrost client
    JS's own live WebSocket-status indicator, injected globally by the
    vendor script itself (confirmed via `window.bifrostClient._zConnectionBadge`
    on the live site), not anything in this app's own .zolo files. Checked
    the client's resolved `options` object for a documented way to turn it
    off (`debug`, `zIcons`, etc. are all real options) — no
    `showConnectionBadge`/`hideBadge`-shaped key exists among them, so there
    is no supported switch for this, only CSS.
    It's a developer/debug affordance (did the WS connect, is it retrying) —
    not something a visitor to an investment/cultural platform needs to see,
    and this site has no feature where watching connection state matters to
    them. The one real trade-off: if someone's connection genuinely drops
    mid-visit, they won't get this chip's visual cue — acceptable here since
    nothing on the site depends on a live socket in a way a visitor would
    need to actively monitor (worst case, something like the newsletter
    dialog briefly lags until the client's own `autoReconnect` kicks back
    in, same as it would with the chip showing). <*/
.zConnection {
  display: none !important;
}
