/* ==========================================================================
   Homepage intro overlay

   Measured off `Intro - Frame 1 (Lawn)` and its three siblings in the design
   file, all 1280x823:

     tagline   63,56    595x361   73.5px Inter, cream-light
     image     753,136  370x505
     mark      right edge at 1224, i.e. the 56px gutter

   Those are rebuilt as proportions rather than pinned coordinates. The frame
   is one fixed size and a browser window is not, so the composition is a
   two-column grid that holds its shape at any window instead of a scale()
   that would letterbox at every ratio but the designer's.
   ========================================================================== */

/* Hidden until the head script decides this visit gets it — see inc/intro.php.
   Default-off is what makes a returning visitor see nothing rather than a
   frame of overlay, and what makes JavaScript-off safe: no class, no overlay,
   no way to cover the page without being able to uncover it. */
.tg-intro{display:none;}

.tg-intro-on .tg-intro{
  display:block;position:fixed;inset:0;z-index:10000;
  background:var(--forest-dark);
  /* Fades out on dismissal; .is-done is set by intro.js. */
  opacity:1;transition:opacity .45s ease;}
.tg-intro-on .tg-intro.is-done{opacity:0;pointer-events:none;}

/* The page underneath must not scroll while it is covered — a wheel event that
   moves something invisible is how a visitor arrives at the hero already
   halfway down it. Scoped to the same class so it cannot outlive the overlay:
   intro.js drops .tg-intro-on, and the page scrolls again in the same frame. */
.tg-intro-on{overflow:hidden;}

.tg-intro-inner{
  display:grid;grid-template-columns:auto auto;
  justify-content:space-between;align-items:start;
  gap:clamp(32px,4vw,72px);
  height:100%;
  /* The frame's own horizontal insets. The tagline starts at 63, and — this is
     the one that matters — the picture's right edge lands at 1123, which is
     157 in from the frame edge and NOT on the gutter. The picture is
     deliberately held off that edge; pushing it out to the gutter is a
     different layout.

     min() rather than a flat percentage: the percentage resolves against the
     WINDOW, not this box, so on anything wider than the frame a bare 12.27%
     keeps growing after the frame has stopped. Taking the smaller of the two
     pins the design's exact pixels at 1280 and above, and scales them down in
     proportion below it. */
  padding:var(--gutter) min(157px,12.27%) var(--gutter) min(63px,4.92%);
  /* The design's content stops at 1280; past that the two columns would drift
     apart across the middle of a wide screen rather than reading as one
     composition.

     border-box is load-bearing. Everything outside .wpb-content-wrapper is
     content-box by default here, which measures max-width against the CONTENT
     and hangs the padding off it — the frame came out 1441 wide on a 1441
     window, i.e. not capped at all, and the picture drifted with it. */
  box-sizing:border-box;max-width:1280px;margin:0 auto;}

/* 73.5px at a 1280 frame is 5.74vw, and it stops THERE rather than carrying on
   up. The composition is capped at 1280, so type that kept scaling with the
   viewport would keep growing after the box around it had stopped — the line
   breaks drift and the tagline outgrows its own column on a wide screen. */
.tg-intro-tagline{
  font-family:var(--font);
  font-size:clamp(40px,5.74vw,73.5px);
  line-height:1.1;letter-spacing:-.02em;
  color:var(--cream-light);
  /* The frame's own 595, as a length and not a percentage. A percentage here
     resolves against the GRID COLUMN rather than the frame, which is narrower
     than 595 once the picture has taken its share — that read as the tagline
     breaking into five lines where the design has three. */
  max-width:595px;}
.tg-intro-tagline b{font-weight:700;}
/* Light, not a lighter shade: the two halves are the same colour and differ
   only in weight. That contrast IS the design. */
.tg-intro-tagline span{font-weight:300;}

/* 370/1280 of the frame, with the slot's own ratio so the box never disagrees
   with the pictures in it. */
.tg-intro-media{
  position:relative;
  width:clamp(240px,28.9vw,370px);
  aspect-ratio:370 / 505;
  overflow:hidden;
  /* The frame drops the picture 80px below the tagline's top edge, which is
     9.7% of its 823 height. Held in svh rather than a percentage because a
     percentage margin resolves against WIDTH, and this is a vertical offset. */
  margin-top:clamp(0px,9.7svh,120px);}

/* All four are stacked in the one box and cross-faded by opacity. Stacked
   rather than swapped: a src swap decodes mid-transition and shows a white
   flash on the first paint of each new file, and these are photographs over a
   dark panel, which is the worst case for that. */
.tg-intro-shot{
  position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover;display:block;
  opacity:0;transition:opacity .35s ease;}
.tg-intro-shot.is-on{opacity:1;}

/* Bottom-right, its right edge on the gutter, exactly as the frame has it.
   Masked rather than an <img>, reusing the wordmark the header and footer
   already load — same asset, same cache entry, and the colour stays a token
   instead of being baked into a second copy of the file. */
.tg-intro-mark{
  position:absolute;bottom:40px;
  /* Measured against the SAME capped 1280 box the rest of the composition sits
     in, not against the window. The mark is a sibling of .tg-intro-inner
     rather than a child of it, so without this it would keep hugging the
     window edge while the picture stopped at the box — and the 101px the
     design leaves between the two would stretch with every extra pixel of
     screen.

     Two terms, because the two sides of the cap behave differently. The first
     re-centres on the frame once the window is wider than 1280 and is zero
     below it. The second is the gutter, taken proportionally under the cap so
     it shrinks with everything else rather than staying 56px while the frame
     around it scales — that is worth the parentheses, since a flat gutter put
     the mark 9 units adrift at 1100. */
  right:calc(max(0px,(100% - 1280px) / 2) + min(var(--gutter),4.375%));
  width:201px;height:24px;
  background:var(--white);
  -webkit-mask-image:url(assets/logo-wordmark.svg);
  mask-image:url(assets/logo-wordmark.svg);
  -webkit-mask-repeat:no-repeat;
  mask-repeat:no-repeat;
  -webkit-mask-size:contain;
  mask-size:contain;
  -webkit-mask-position:center;
  mask-position:center;}

/* ==========================================================================
   Phones and tablets — the same composition, stacked

   900px, which is the breakpoint the hero pin and the rest of pages.css
   already use, so the homepage still has ONE.

   NO VIEWPORT UNITS BELOW THIS LINE, and that is the whole trick to the
   height. `.tg-intro` is position:fixed/inset:0, which on iOS Safari and
   Chrome Android is already pinned to the VISIBLE window and reflows when the
   URL bar collapses — it is 100dvh behaviour for free, with no unit to pick
   and nothing for JavaScript to measure. Choosing between svh and dvh here
   would be answering a question this layout never asks. What DOES break a
   phone is a vh-derived length inside the box (the desktop rule's
   `margin-top:clamp(0px,9.7svh,120px)` is exactly it) sitting next to a locked
   aspect-ratio, because the two disagree and the loser overflows. So the
   vertical rhythm below is flexbox distribution only, which is intrinsically
   right at any height.
   ========================================================================== */
@media (max-width:900px){

  /* Column, not the desktop two-up: tagline, picture, and the mark — which is
     still an absolutely-positioned SIBLING, so the column reserves its height
     as bottom padding rather than laying it out. That is the gutter beneath
     the mark, the mark's own 19px, and 24px of air above it.

     `gap` rather than a margin on the picture, because the picture's block
     margins are about to be `auto` and auto margins would eat it. Gap is the
     MINIMUM air between the two; the auto margins take whatever is left. */
  .tg-intro-inner{
    display:flex;flex-direction:column;
    justify-content:flex-start;align-items:stretch;
    gap:24px;
    padding:var(--gutter) var(--gutter) calc(var(--gutter) + 43px);}

  /* Touch scroll needs its own brace. `overflow:hidden` on the root element is
     reliable in desktop browsers and historically has NOT been on iOS, where a
     touch-drag can still pan the document underneath a fixed overlay. The
     overlay is the touch target, so refusing the gesture there settles it —
     and touch-action:none stops pan and pinch WITHOUT stopping the tap, so
     click-to-dismiss is untouched. */
  .tg-intro-on .tg-intro{touch-action:none;overscroll-behavior:contain;}

  /* 5.74vw floors at 40px on a phone, which is the wrong floor — at 390px wide
     the design's three lines become five or six and eat the height the picture
     needs. 8.5vw is ~33px at 390 and ~27 at 320.

     The 595px cap goes: it is wider than the screen, so it never applied. In
     its place a cap in EM, which is the measure rather than a width — inert on
     a phone (16em at 33px is 528px, wider than the column) and the thing that
     stops a 44px line running the full width of a tablet. */
  .tg-intro-tagline{
    font-size:clamp(28px,8.5vw,44px);
    max-width:16em;flex:0 0 auto;}

  /* The picture keeps the design's 370x505 and never exceeds its 370 — but
     flex-shrink is live and min-height is 0, so when a short phone cannot
     afford that height the box shrinks past its own ratio and `object-fit:
     cover` on the shots absorbs the difference. That is the shock absorber:
     one rule covers a 568px iPhone SE and a 932px Pro Max with no height
     breakpoint and nothing measured.

     margin:auto is doing two jobs. Horizontally it centres the column.
     Vertically — and auto margins absorb free space BEFORE justify-content
     does — it centres the picture in whatever slack is left on a tall phone,
     and collapses to nothing on a short one where there is no slack to take.
     Both halves of that are why the desktop svh offset is overridden here
     rather than adjusted. */
  .tg-intro-media{
    width:100%;max-width:370px;
    aspect-ratio:370 / 505;
    max-height:100%;min-height:0;
    flex:0 1 auto;
    margin:auto;}

  /* The desktop `right` re-centres the mark on the capped 1280 box, which
     below 900 is always just the gutter. 201px is over half of a 320px screen,
     so it comes down proportionally — 201x24 is 8.375:1, and so is 160x19. */
  .tg-intro-mark{
    right:var(--gutter);bottom:var(--gutter);
    width:160px;height:19px;}
}

/* The one geometry left that gets refused rather than laid out. A 390x844
   phone turned sideways is 844 wide and 390 TALL — under the breakpoint above,
   with no room to stack: tagline, picture and mark do not fit in 390 points
   however they are scaled. Suppressed rather than designed for, because nobody
   rotates a phone to arrive at a homepage.

   Portrait is safely clear of it: the shortest phone worth naming is 568.

   Releasing `overflow` is the load-bearing half of both these blocks. The head
   script no longer declines on width, so this is the only thing standing
   between a hidden overlay and a page that cannot scroll. */
@media (max-width:900px) and (max-height:500px){
  .tg-intro-on .tg-intro{display:none;}
  .tg-intro-on{overflow:auto;}
}
@media (prefers-reduced-motion:reduce){
  .tg-intro-on .tg-intro{display:none;}
  .tg-intro-on{overflow:auto;}
}
