/* =====================================================================
   STORY CRAFT — /founder/
   ---------------------------------------------------------------------
   01  Route base
   02  Hero — desktop (asymmetric 12-col)
   03  Hero — mobile (full-bleed 3:4 + rising sheet)
   04  Sections, headings, body measures
   05  Origin + fact line
   06  Point of view
   07  On set — the visual essay
   08  Selected work
   09  Quote
   10  Contact ending
   11  Motion + reduced motion

   `projects/base.css` supplies the tokens, reset, header chrome,
   `.t-label`, `.vh`, `.skip`, `.cta` and the focus ring. Nothing here
   redefines them.

   No scroll-snap on this route. A profile is a reading surface: it
   scrolls natively, top to bottom, and nothing hijacks that.
   ===================================================================== */


/* =====================================================================
   01  ROUTE BASE
   ===================================================================== */
html{ -webkit-text-size-adjust:100%; }
body{
  background:var(--powder-white);
  color:var(--serene-navy);
  font-family:var(--font-ui);
  font-weight:400;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

/* This route's canvas is powder-white and the header sits directly on it,
   so a solid plane is invisible at rest — it only becomes a plane once
   the full-bleed mobile frames scroll under it, which is exactly when it
   is needed. base.css's `html[data-over-media="1"]` inversion is the
   site's other answer, and it is the wrong one here: on a phone it would
   flip the header light/dark five times on the way down the page, which
   is motion competing with the person for no legibility gain. It also
   keeps this route free of a scroll observer. */
.hdr{ background:var(--powder-white); }

/* The mobile header now lives in base.css and is shared by every route:
   Work stays, the language pair moves to the footer. This route used to
   carry its own copy of those three declarations — deleted, because two
   copies of one header is how they drift apart.

   The header is fixed, so an in-page jump would otherwise land the target
   heading underneath it. */
.fo [id], #main{ scroll-margin-top:calc(var(--hdr) + 1rem); }

.fo{
  --fo-r: clamp(14px, 1vw, 20px);          /* the one corner radius */
  /* Held as custom properties because the full-bleed frames below have to
     cancel them exactly. `100vw` is the usual trick and it is wrong here:
     it includes the scrollbar gutter, so a classic scrollbar turns every
     bleed into 15px of horizontal overflow. */
  --fo-padL:max(var(--pad), env(safe-area-inset-left));
  --fo-padR:max(var(--pad), env(safe-area-inset-right));
  padding-inline:var(--fo-padL) var(--fo-padR);
  padding-bottom:clamp(3rem, 10vh, 7rem);
}
.fo__wrap{ max-inline-size:74rem; margin-inline:auto; }


/* =====================================================================
   02  HERO — DESKTOP
   ---------------------------------------------------------------------
   Deliberately NOT a 50/50 marketing split. The text block sits left of
   centre on columns 1-6, the portrait is pushed right on 8-12, and
   column 7 is left empty — that gap is what makes the composition read
   as editorial rather than as a two-up.

   Text never crosses the image, so the face is never covered.
   ===================================================================== */
@media (min-width:861px){
  .fo__hero{
    display:grid;
    grid-template-columns:repeat(12, minmax(0,1fr));
    column-gap:var(--gap);
    align-items:center;
    padding-block:calc(var(--hdr) + clamp(2rem, 6vh, 4rem)) clamp(3rem, 9vh, 6rem);
  }
  /* Both on row 1 explicitly. The figure comes FIRST in the DOM (so the
     mobile sheet can simply rise under it with no `order` reshuffling),
     and without the explicit row auto-placement would push the text —
     which starts back at column 1 — down into a second row. */
  .fo__heroTxt{ grid-column:1 / span 6; grid-row:1; }
  .fo__heroFig{ grid-column:8 / span 5; grid-row:1; margin:0; }
}

.fo__eyebrow{
  display:flex; align-items:center; gap:.55rem;
  color:var(--navy-70);
}
/* The star appears ONCE on this page, at label size, as a registration
   mark beside the role. It is not the page's motif. */
.fo__star{
  inline-size:.62em; block-size:.62em;
  background:var(--caspian-blue);
  -webkit-mask:var(--star-mask) center/contain no-repeat;
  mask:var(--star-mask) center/contain no-repeat;
  flex:none;
}
.fo__h1{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(2.1rem, 5.2vw, 4.4rem);
  line-height:1.02; letter-spacing:-.022em;
  margin-block:clamp(.7rem, 1.8vh, 1.1rem) 0;
  text-wrap:balance;
  /* Lithuanian names and compounds are long; never let one push the
     page sideways. */
  overflow-wrap:break-word;
}
.fo__intro{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.05rem, 1.7vw, 1.45rem);
  line-height:1.34; letter-spacing:-.01em;
  color:var(--caspian-blue);
  max-inline-size:38ch;
  margin-block:clamp(.9rem, 2.4vh, 1.4rem) 0;
}
.fo__acts{
  display:flex; flex-wrap:wrap; align-items:center;
  gap:.7rem clamp(.9rem, 2vw, 1.4rem);
  margin-top:clamp(1.2rem, 3vh, 1.8rem);
}
/* base.css gives .cta `white-space:nowrap`, which is right everywhere it
   is a two-word label. Lithuanian runs ~15% longer, and at 200% text on a
   320px phone "Pradėkime projektą" is wider than the screen. Scoped to
   this route's action rows so the pill wraps to two lines instead of
   pushing the page sideways — the shape survives, the label stays whole. */
.fo__acts .cta,
.fo__endActs .cta{
  white-space:normal; text-align:center; max-inline-size:100%;
  padding-block:.5rem; line-height:1.25;
}
/* The secondary route is a text link with a rule, not a second pill —
   two pills side by side would read as a form, not a choice. */
.fo__link{
  display:inline-flex; align-items:center; gap:.45rem;
  min-height:44px;
  color:var(--caspian-blue);
  border-bottom:1px solid color-mix(in srgb, var(--caspian-blue) 34%, transparent);
  /* At 200% text on a 320–390px phone the email address is wider than the
     column, and inline-flex will not wrap on its own. These three let it
     break instead of pushing the page sideways. */
  max-inline-size:100%;
  flex-wrap:wrap;
  overflow-wrap:anywhere;
}
.fo__link:hover{ border-bottom-color:var(--caspian-blue); }
.fo__link svg{ transition:transform .4s var(--ease-out-quart); }
.fo__link:hover svg{ transform:translateX(4px); }

/* The frame clips; the image drifts inside it (section 11). The radius
   therefore belongs to the FIGURE — left on the image it would drift with
   it and the corners would go soft. */
.fo__heroFig{
  margin:0; overflow:hidden;
  border-radius:var(--fo-r);
  background:color-mix(in srgb, var(--serene-navy) 6%, var(--powder-white));
}
.fo__heroImg{
  display:block; inline-size:100%; block-size:auto;
  aspect-ratio:4/5;
  object-fit:cover; object-position:50% 20%;
}


/* =====================================================================
   03  HERO — MOBILE
   ---------------------------------------------------------------------
   Art-directed independently, not the desktop composition shrunk: a
   full-bleed frame, then the light sheet rising ~26px over its lower edge
   so image and type read as one composition. Same device the /projects/
   gateway uses, so the two routes feel like one site.

   The frame WAS 3:4 against a 3:4 crop, which put the face across ~60% of
   the screen width — a passport photo at billboard scale. It is now 4:5
   against a 4:5 crop: 6.7% more of the original square in frame (more
   shoulder, more air round the head) and 6.3% shorter, so the role, name
   and intro all arrive sooner. Roughly 12% less dominant, without
   touching the composition's logic.

   No text sits over the face — the sheet starts below the frame.
   ===================================================================== */
@media (max-width:860px){
  /* The header is position:fixed, so the frame starts BELOW it rather than
     under it. A nav bar sitting across someone's hair is worse than a hard
     edge, and it keeps this route free of the scroll observer that the
     `data-over-media` inversion would otherwise need. */
  .fo__hero{ display:block; padding-top:var(--hdr); }
  /* The bleed lives on the FIGURE, not the image: the figure now clips
     (it is the still frame for the drift), so an over-wide image inside
     it would simply be cut off. A block box with negative inline margins
     resolves its own width — no calc needed. */
  .fo__heroFig{
    margin-inline:calc(-1 * var(--fo-padL)) calc(-1 * var(--fo-padR));
    border-radius:0;
  }
  .fo__heroImg{
    inline-size:100%;
    aspect-ratio:4/5;
    /* Short phones would otherwise push every word below the fold. */
    max-block-size:62svh;
    object-fit:cover;
    object-position:50% 22%;
  }
  /* The sheet rises over the lower edge of the frame — the same join the
     /projects/ gateway makes, so the two routes read as one site. It is a
     sibling BELOW the image, never an overlay on top of it, so no text
     ever crosses the face. */
  .fo__heroTxt{
    position:relative; z-index:2;
    margin-top:-26px;
    padding-top:clamp(1.2rem, 3.4vh, 1.7rem);
    border-radius:var(--fo-r) var(--fo-r) 0 0;
    background:var(--powder-white);
  }
  .fo__intro{ max-inline-size:34ch; }
}
/* Landscape phone: a portrait band would eat the whole viewport. */
@media (max-width:860px) and (max-height:520px){
  /* A landscape phone has horizontal room but almost no vertical room.
     Use that room: the previous rule only narrowed the portrait and left
     the entire right side blank while every word began below the fold. */
  .fo__hero{
    display:grid;
    grid-template-columns:minmax(180px, min(34vw, 260px)) minmax(0,1fr);
    gap:clamp(1.2rem, 4vw, 2.5rem);
    align-items:center;
    min-block-size:100svh;
    padding-block:var(--hdr) clamp(1rem, 4vh, 2rem);
  }
  .fo__heroFig{
    margin-inline:0; inline-size:100%;
    border-radius:var(--fo-r);
  }
  .fo__heroImg{ max-block-size:none; }
  .fo__heroTxt{
    margin-top:0; padding-top:0;
    border-radius:0; background:none;
  }
}


/* =====================================================================
   04  SECTIONS
   ===================================================================== */
.fo__sec{
  margin-top:clamp(2.4rem, 8vh, 5rem);
  padding-top:clamp(1.2rem, 3vh, 2rem);
  border-top:1px solid var(--rule);
}
.fo__secH{ color:var(--navy-70); }
.fo__h2{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.5rem, 3vw, 2.4rem);
  line-height:1.06; letter-spacing:-.018em;
  margin-block:.5rem 0;
  text-wrap:balance;
}
.fo__body{
  font-size:clamp(.98rem, 1.15vw, 1.08rem);
  line-height:1.62;
  max-inline-size:60ch;
  margin-block:clamp(.8rem, 2vh, 1.1rem) 0;
}
.fo__body + .fo__body{ margin-top:.9rem; }
@media (max-width:860px){
  /* A compact measure reads far better on a phone than a full-width
     paragraph. Never justified. */
  .fo__body{ max-inline-size:38ch; }
}


/* =====================================================================
   05  ORIGIN — the fact line
   ---------------------------------------------------------------------
   Three plain facts on a hairline. Deliberately NOT a row of promotional
   statistics: no numbers, no counters, no icons.
   ===================================================================== */
.fo__facts{
  display:flex; flex-wrap:wrap; gap:.4rem clamp(1rem, 3vw, 2.2rem);
  margin-top:clamp(1.1rem, 3vh, 1.6rem);
  padding-top:clamp(.8rem, 2vh, 1.1rem);
  border-top:1px solid var(--rule);
  color:var(--navy-70);
}
/* Narrow: an explicit two-up with the long third fact spanning beneath,
   rather than three tracked-out labels flowing into a ragged three-line
   accident. Structural, so the longer Lithuanian labels inherit it. */
@media (max-width:36em){
  .fo__facts{
    display:grid; grid-template-columns:1fr 1fr;
    gap:.5rem 1rem;
  }
  .fo__facts > :last-child{ grid-column:1 / -1; }
}


/* =====================================================================
   06  POINT OF VIEW
   ---------------------------------------------------------------------
   Text-led. Three principles separated by hairlines — not three cards,
   not a grid of tiles with icons.
   ===================================================================== */
.fo__pov{ margin-top:clamp(1rem, 2.6vh, 1.5rem); }
.fo__povI{
  padding-block:clamp(1rem, 2.6vh, 1.5rem);
  border-top:1px solid var(--rule);
  display:grid; column-gap:clamp(1rem, 3vw, 2.4rem); row-gap:.4rem;
}
.fo__povI:first-child{ border-top:0; padding-top:0; }
@media (min-width:861px){
  .fo__povI{ grid-template-columns:auto minmax(0,1fr); align-items:baseline; }
  .fo__povN{ grid-row:span 2; }
}
.fo__povN{ color:var(--navy-45); font-variant-numeric:tabular-nums; }
.fo__povT{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.1rem, 1.9vw, 1.5rem);
  line-height:1.16; letter-spacing:-.012em;
}
.fo__povB{
  font-size:clamp(.95rem, 1.1vw, 1.02rem);
  line-height:1.6; color:var(--navy-70);
  max-inline-size:56ch;
}
@media (max-width:860px){ .fo__povB{ max-inline-size:38ch; } }


/* =====================================================================
   07  ON SET
   ---------------------------------------------------------------------
   ONE composed unit, not three photographs placed on a canvas. A large
   primary frame of Simonas working, and two supporting production
   details stacked beside it. Outer edges and total height align on both
   sides, and a single gap value is used everywhere inside the block.

   The 2fr / 1fr split is arithmetic, not taste. With the lead frame at
   its native 3:2, each supporting frame resolves to ~1.56:1 — a 4% crop
   off the original 1.5:1. The photographs keep their own proportions
   rather than being squeezed into a layout.

   No captions. The photographs are the evidence; project names and links
   live in Selected work, one section below, and printing them twice was
   the thing making this read as a stock-photo grid.
   ===================================================================== */
.fo__set{
  /* The one gap. Between the columns, and between the stacked pair. */
  --fo-gap:clamp(10px, 1.3vw, 20px);
  margin-top:clamp(1.2rem, 3vh, 1.8rem);
}
/* The FIGURE is the frame: fixed ratio, clipped, never transformed. The
   image inside it is the only thing that moves (section 11). */
.fo__shot{
  margin:0; position:relative; overflow:hidden;
  border-radius:var(--fo-r);
  background:color-mix(in srgb, var(--serene-navy) 6%, var(--powder-white));
}
.fo__shot img{
  display:block; inline-size:100%; block-size:100%;
  object-fit:cover;
}
/* Focal points, set per frame rather than left to a centre crop.
   03 must keep the operator, the multiview and the mixer; 04 must keep
   Simonas AND both lights. Only bites where cover actually has excess to
   discard, so the same two rules are correct at every breakpoint. */
.fo__shot--side:nth-child(1) img{ object-position:65% 50%; }
.fo__shot--side:nth-child(2) img{ object-position:57% 50%; }

/* 700px, not the 861px the rest of the route turns on. The composition
   is what decides this, not the header: at 768 the phone layout gave a
   713x891 primary — one photograph taller than most laptop viewports —
   and a gallery 1252px deep. Two columns fit comfortably from ~700px. */
@media (min-width:700px){
  .fo__set{ display:grid; grid-template-columns:2fr 1fr; gap:var(--fo-gap); }
  .fo__shot--lead{ aspect-ratio:3/2; }
  /* The side column carries its own ratio so the two columns end on the
     same line, which is the one thing this composition has to get right.
     It falls out of the track sizes and is gap-independent: at 2fr / 1fr
     the lead is exactly twice the side column's width S, so the lead's
     3:2 makes it 4S/3 tall — and 3:4 is the ratio that gives the side
     column that same height. Without this, the column's intrinsic height
     (two images plus a gap) sized the row instead and ran ~20px long.

     minmax(0,1fr) for the rows, not a bare 1fr: `1fr` means
     `minmax(auto,1fr)`, so each row would floor at the image's own
     intrinsic height and overflow the column again. */
  .fo__setSide{
    aspect-ratio:3/4;
    display:grid; grid-template-rows:minmax(0,1fr) minmax(0,1fr);
    gap:var(--fo-gap); min-block-size:0;
  }
  .fo__shot--side{ min-block-size:0; }
}
/* Past ~1500px the 74rem reading measure is right for prose and wrong for
   photography — it left the gallery marooned in a field of empty canvas.
   Let the unit push back out toward the page gutters, up to 9rem a side,
   so it stays visually substantial on a large display. */
@media (min-width:1500px){
  .fo__set{
    --fo-out:min(9rem, max(0px, (100vw - 74rem) / 2 - var(--fo-padL)));
    margin-inline:calc(-1 * var(--fo-out));
    inline-size:calc(100% + 2 * var(--fo-out));
  }
}

@media (max-width:699px){
  /* Inset to the same gutter as the text, not full-bleed. Four
     edge-to-edge frames in a row read as a slideshow you have to sit
     through; one inset primary over a supporting pair reads as an edit.
     The whole unit is now roughly two thirds of one phone screen. */
  .fo__set{ display:grid; gap:var(--fo-gap); }
  .fo__shot--lead{ aspect-ratio:4/5; }
  .fo__setSide{ display:grid; grid-template-columns:1fr 1fr; gap:var(--fo-gap); }
  .fo__shot--side{ aspect-ratio:1/1; }
}
/* Below ~350px a supporting frame is ~135px square and stops carrying
   information, so the pair becomes one column at the primary's width.
   Text zoom does NOT reach this rule — `em` in a media query resolves
   against the initial font size, not the user's root — and it does not
   need to: zooming text leaves the images at their physical size, so at
   200% on a 390px phone they are still ~150px and perfectly legible. */
@media (max-width:22em){
  .fo__setSide{ grid-template-columns:1fr; }
  .fo__shot--side{ aspect-ratio:3/2; }
}


/* =====================================================================
   08  SELECTED WORK
   ---------------------------------------------------------------------
   The same editorial row the All Work index uses, so a visitor who has
   seen /projects/ recognises it immediately.
   ===================================================================== */
.fo__work{ list-style:none; margin:clamp(1rem, 2.6vh, 1.5rem) 0 0; padding:0; }
.fo__workI{ border-top:1px solid var(--rule); }
.fo__workI:last-child{ border-bottom:1px solid var(--rule); }
.fo__workA{
  display:grid;
  grid-template-columns:clamp(96px, 12vw, 190px) minmax(0,1fr);
  align-items:center;
  column-gap:clamp(1rem, 2.4vw, 2rem);
  padding-block:clamp(.8rem, 2vh, 1.2rem);
  min-height:44px;
  position:relative;
}
.fo__workA::before{
  content:''; position:absolute; inset:0 calc(-1 * clamp(.5rem, 1vw, 1rem));
  background:color-mix(in srgb, var(--serene-navy) 4%, transparent);
  opacity:0; transition:opacity .35s var(--ease-out-quart);
}
.fo__workA:hover::before,
.fo__workA:focus-visible::before{ opacity:1; }
.fo__workT{ aspect-ratio:16/10; border-radius:8px; overflow:hidden; }
.fo__workT img{ inline-size:100%; block-size:100%; object-fit:cover; display:block;
  transition:transform .6s var(--ease-out-expo); }
.fo__workA:hover .fo__workT img{ transform:scale(1.04); }
.fo__workTx{ display:flex; flex-direction:column; gap:.2rem; min-inline-size:0; }
.fo__workC{ color:var(--navy-70); }
.fo__workN{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.05rem, 1.8vw, 1.55rem); line-height:1.14;
  letter-spacing:-.012em;
  transition:transform .5s var(--ease-out-expo); transform-origin:left;
}
.fo__workA:hover .fo__workN{ transform:translateX(5px); }
.fo__workR{ color:var(--navy-70); font-size:clamp(.85rem, 1vw, .95rem); line-height:1.45; }
@media (max-width:860px){
  /* Summaries run to three lines here, and a vertically-centred thumb
     floats away from the title it belongs to. Top-align instead. */
  .fo__workA{ align-items:start; }
}
/* The credit line. Rendered only when the record actually states a scope,
   printed in the record's own words, never inferred from the picture. */
.fo__workS{ color:var(--navy-45); margin-top:.2rem; }
.fo__all{ margin-top:clamp(.9rem, 2.4vh, 1.3rem); }

/* Narrow phones: the row was carrying a client, a title, a full sentence
   and a four-term uppercase scope string — four type sizes in ~130px of
   height. Keep what identifies the project (thumbnail, client, name) plus
   ONE supporting identifier, the year, in the same label style the scope
   used. The full record is one tap away; it does not belong here twice.
   Desktop keeps everything. */
@media (max-width:560px){
  .fo__workA{
    grid-template-columns:clamp(88px, 26vw, 104px) minmax(0,1fr);
    column-gap:.9rem;
    padding-block:.9rem;
  }
  .fo__workR,
  .fo__workScope{ display:none; }
  .fo__workN{ font-size:1.06rem; }
  .fo__workS{ margin-top:.3rem; }
}


/* =====================================================================
   09  QUOTE
   ---------------------------------------------------------------------
   One quote, set as type. No stars, no rating card, no avatar.
   ===================================================================== */
.fo__quote{ margin:clamp(1rem, 2.6vh, 1.5rem) 0 0; }
.fo__quoteT{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.35rem, 2.8vw, 2.15rem);
  line-height:1.22; letter-spacing:-.016em;
  max-inline-size:30ch;
  text-wrap:balance;
}
.fo__quoteC{
  color:var(--navy-70); margin-top:1rem; font-style:normal;
  display:flex; flex-wrap:wrap; gap:.2rem .55rem;
}


/* =====================================================================
   10  CONTACT ENDING
   ===================================================================== */
.fo__end{
  margin-top:clamp(2.4rem, 8vh, 5rem);
  padding-top:clamp(1.4rem, 4vh, 2.4rem);
  border-top:1px solid var(--rule);
}
.fo__endH{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(1.5rem, 3.2vw, 2.4rem); line-height:1.08; letter-spacing:-.018em;
  text-wrap:balance;
}
.fo__endB{ margin-top:.8rem; }
.fo__endActs{
  display:flex; flex-wrap:wrap; align-items:center;
  gap:.7rem clamp(.9rem, 2vw, 1.4rem);
  margin-top:clamp(1.2rem, 3vh, 1.8rem);
}
/* On a phone the flex row put a pill, two links and a 25-character email
   address on one line, which either shrank the type or wrapped into a
   dense hedge with sub-40px targets. Three explicit rows instead:
   primary alone, the two secondary links as a pair, the address last on
   its own where it has room to break. */
@media (max-width:560px){
  .fo__endActs{
    display:grid; grid-template-columns:1fr 1fr;
    gap:.9rem 1rem; align-items:center;
  }
  .fo__endActs .cta{
    grid-column:1 / -1; justify-self:start;
    min-height:48px; padding-inline:1.5rem;
  }
  .fo__endActs .fo__link{ min-height:48px; }
  .fo__endActs .fo__link--mail{ grid-column:1 / -1; }
}
/* The hero pair gets the same treatment one step narrower — two items,
   so it only needs stacking when they genuinely stop fitting. */
@media (max-width:24em){
  .fo__acts{ display:grid; justify-items:start; gap:.75rem; }
  .fo__acts .cta{ justify-self:start; }
}


/* =====================================================================
   11  MOTION
   ---------------------------------------------------------------------
   One gesture only: sections rise a few pixels as they arrive. It is
   applied by JS adding `is-in`, so without JS everything is simply
   visible — content is never gated behind an animation.
   ===================================================================== */
@media (prefers-reduced-motion: no-preference){
  .js .fo__rise{
    opacity:0; transform:translate3d(0, 14px, 0);
    transition:opacity .6s var(--ease-out-quart), transform .7s var(--ease-out-expo);
  }
  .js .fo__rise.is-in{ opacity:1; transform:none; }
}

/* -- 11.1  Ambient hero -----------------------------------------------
   The frame never moves. Only the pixels inside it drift, and barely:
   scale travels 1.014 → 1.032 (1.8% total) and translation peaks at
   0.35%. The floor of 1.014 is the point — the image always overflows
   its frame by at least 0.7% a side, which is twice the furthest it ever
   translates, so no bare edge can appear at the turn.

   36s and `alternate`, so it runs back along its own path and there is
   no reset seam. No rotation. No pointer tracking: a face that follows
   the cursor is a toy, and this one is a person.

   The transform lives on the IMG and nothing else transforms it, so
   there is no second animation to overwrite. */
@media (prefers-reduced-motion: no-preference){
  .fo__heroImg{
    animation:fo-drift 36s ease-in-out infinite alternate;
    will-change:transform;
  }
}
@keyframes fo-drift{
  from{ transform:scale(1.014) translate3d(-.35%,  .2%, 0); }
  to  { transform:scale(1.032) translate3d( .35%, -.2%, 0); }
}

/* -- 11.2  Gallery depth ----------------------------------------------
   Scroll-linked, not looping: each frame stays still while the image
   inside it moves against the page, in the same direction and by the
   same proportion everywhere, so it reads as one behaviour rather than
   four decorations.

   Amplitude is a proportion of each frame's own height, which is what
   keeps it systematic across three different frame sizes. Desktop 1.3%
   total — inside the 1–1.5% brief. Mobile 3%, which on the 4:5 primary
   is ~13px. scale(1.04) leaves 2% of overflow a side, comfortably more
   than the 1.5% peak travel, so nothing ever exposes an edge.

   Transform only. `view()` where the browser has it; everywhere else the
   images are simply static, which is a perfectly good outcome. */
.fo__shot img{ --fo-depth:.65%; }
@media (max-width:860px){ .fo__shot img{ --fo-depth:1.5%; } }

@supports (animation-timeline: view()){
  @media (prefers-reduced-motion: no-preference){
    /* A NAMED timeline, declared on the frame and consumed by the image
       inside it. `animation-timeline: view()` looks the subject up
       against its nearest scroll container — and the frame is
       `overflow:hidden`, which makes the frame itself that container. It
       never scrolls, so the timeline pinned at 50% and the images sat
       perfectly still. Naming it on the frame makes the FRAME the subject,
       tracked against the page, and the image resolves `--fo-shot` by
       walking up to it. */
    .fo__shot{ view-timeline:--fo-shot block; }
    .fo__shot img{
      animation:fo-depth linear both;
      animation-timeline:--fo-shot;
      animation-range:entry 0% exit 100%;
      will-change:transform;
    }
  }
}
@keyframes fo-depth{
  from{ transform:scale(1.04) translate3d(0, calc(-1 * var(--fo-depth)), 0); }
  to  { transform:scale(1.04) translate3d(0, var(--fo-depth), 0); }
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important; scroll-behavior:auto !important;
  }
  .fo__rise{ opacity:1 !important; transform:none !important; }
  /* Not merely stopped — returned to a neutral transform, so every image
     sits in its final, fully-visible position rather than frozen at
     whichever keyframe it happened to reach. */
  .fo__heroImg, .fo__shot img{
    animation:none !important; transform:none !important; will-change:auto;
  }
}

/* =====================================================================
   12  MOBILE RHYTHM
   ---------------------------------------------------------------------
   Every major gap above was `clamp(x, Nvh, y)`. On a 844px-tall phone
   8vh is 67px, so section breaks resolved near their ceiling and the page
   grew dead zones — a hairline, then half a screen of nothing, then the
   next heading. Viewport height is also the one axis that moves under you
   as the browser chrome collapses.

   Below 861px the rhythm is a fixed rem scale instead: 2.4rem between
   sections, ~1.2rem inside them, ~1rem before a block of content. Air is
   preserved; the vacuums are not. Placed last so it wins on source order
   without needing specificity games.
   ===================================================================== */
@media (max-width:860px){
  .fo{ padding-bottom:3rem; }
  .fo__sec{ margin-top:2.4rem; padding-top:1.25rem; }
  .fo__end{ margin-top:2.4rem; padding-top:1.5rem; }

  .fo__h1{ margin-top:.65rem; }
  .fo__intro{ margin-top:.9rem; }
  .fo__acts{ margin-top:1.25rem; }
  .fo__heroTxt{ padding-top:1.2rem; }

  .fo__body{ margin-top:.85rem; }
  .fo__facts{ margin-top:1.05rem; padding-top:.85rem; }

  .fo__pov{ margin-top:.9rem; }
  .fo__povI{ padding-block:1.05rem; }

  /* Tighter into the gallery and out of it again — these were the two
     largest gaps on the page. */
  .fo__set{ margin-top:1rem; }
  .fo__work{ margin-top:.9rem; }
  .fo__all{ margin-top:1rem; }

  /* The testimonial sat in the middle of two full section breaks with
     nothing else in its section to fill them. */
  .fo__quote{ margin-top:.9rem; }
  .fo__quoteC{ margin-top:.85rem; }

  .fo__endB{ margin-top:.7rem; }
  .fo__endActs{ margin-top:1.3rem; }
}

/* =====================================================================
   13  LARGE-SCREEN TRIM
   ---------------------------------------------------------------------
   The mirror of section 12, and here for the same reason: source order.
   Both the hero's bottom padding and the section break are viewport-
   height clamps, so on a big display they sit at their ceilings and
   stacked 176px of empty canvas under the portrait. Trimmed to ~128px.

   Deliberately nothing else. The desktop hero composition is not the
   problem and is not being touched — only the air around it.
   ===================================================================== */
@media (min-width:1600px){
  .fo__hero{ padding-block:calc(var(--hdr) + 3rem) 4rem; }
  .fo__sec, .fo__end{ margin-top:4rem; }
}

@media (forced-colors: active){
  .fo__heroImg, .fo__shot img{ border:1px solid CanvasText; }
  .fo__workI, .fo__povI, .fo__sec{ border-color:CanvasText; }
}
