/* ==========================================================================
   Greta Volungevičiūtė — About
   Design canvas: 1440 wide, free height. Requires css/base.css.

   This page keeps the dark ground of the hero rather than the white of the
   work index, so it inherits base.css's tokens untouched — the header, the
   nav and the strikethrough all come along for free.
   ========================================================================== */

:root {
  --pad-x: 48px;               /* matches the header's own gutter            */
  --col: 82px;                 /* 12 columns + 11 × 24px gutters             */
  --gut: 24px;
}

body {
  /* this page scrolls, unlike the hero */
  overflow-x: hidden;
  overflow-y: auto;
}

/* --------------------------------------------------------------------------
   1440 canvas that scales down but keeps scrolling

   Identical to the work index — see the note in js/about.js. #shell is given
   an explicit height from JS because a transform does not affect layout.
   -------------------------------------------------------------------------- */

#shell {
  position: relative;
  width: 100%;
  overflow: hidden;
}

#page {
  position: relative;
  width: var(--design-w);
  transform-origin: 0 0;
  padding: 0 var(--pad-x) 96px;
}

.rule {
  height: 1px;
  background: var(--hairline);
}

/* --------------------------------------------------------------------------
   Intro

   The statement and the portrait each take half the width and hold the same
   top line. The words are set to stop short of the photograph rather than
   running to it, so the gap between them is white space rather than a margin.
   -------------------------------------------------------------------------- */

/* Two halves would cap the composition at 617, and the composition is the page.
   So both children share one cell instead: the words hold the left, the stack
   the right, and together they overrun the 1344 the page actually has. They can,
   because the stack's whole upper left is empty — the dunes do not begin until
   47% down it, which is far below where the greeting ends. The cell takes the
   height of the taller of the two, so nothing here is a magic number. */
.intro {
  display: grid;
  grid-template-columns: 1fr;
  align-items: start;
  padding: 176px 0 104px;
}

.intro > * {
  grid-row: 1;
  grid-column: 1;
}

/* 620 because the greeting's longest line measures 597 — see .intro__title */
.intro__words {
  justify-self: start;
  width: 620px;
}

/* The size is set by the line breaks, not chosen and then lived with. The
   column is 617 wide, and "Hello, I'm Greta —" measures 661 at 62px, so at 62
   the greeting could never hold one line — it broke after "I'm" and the whole
   opening lost its shape. At 56 that line comes to 597 and just fits, while
   "Hello, I'm Greta — a" needs 657 and cannot, so the wrap lands exactly where
   it should. No max-width: the column already is the measure. */
.intro__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 56px;
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.01em;
}

/* --------------------------------------------------------------------------
   The photo stack

   Measured off Screenshot_66 and then written as percentages of one box, so
   the arrangement holds its shape at any width instead of drifting apart the
   way three absolutely-positioned pixel offsets would. The box carries the
   reference's own 629 : 510 proportion; everything inside is a share of it.

   Two of the three keep their source proportions exactly — the portrait and
   the cat are not cropped at all, which is why their heights are left to
   aspect-ratio rather than stated. Only the dunes frame is squared off, and
   from the left edge, because the bicycle sits left of centre.
   -------------------------------------------------------------------------- */

.intro__stack {
  position: relative;
  justify-self: end;
  /* 922 rather than the 617 a half-width column would allow: the portrait comes
     out at 427 instead of 286, which is the difference between a picture beside
     the text and a picture the page is built around */
  width: 922px;
  margin: 0;
  aspect-ratio: 629 / 510;
}

/* height: auto is not tidiness, it is required. The width and height
   attributes on an <img> become presentational hints, and with both of them
   definite the browser has no reason to consult aspect-ratio — every frame
   came out at its own natural height, three times too tall. Releasing the
   height is what hands the decision back to the ratios below. */
.intro__stack img {
  position: absolute;
  height: auto;
  object-fit: cover;
}

.stack__portrait {
  left: 42.8%;
  top: 5.3%;
  width: 46.3%;
  aspect-ratio: 1500 / 1903;
}

/* overlaps the portrait's left edge — the overlap is the composition */
.stack__scene {
  left: 12.1%;
  top: 47.1%;
  width: 34.2%;
  aspect-ratio: 1;
}

.stack__cat {
  left: 55.3%;
  top: 68.8%;
  width: 26.4%;
  aspect-ratio: 1806 / 871;
}

/* The only colour and the only handwriting on the page, pointing at the only
   photograph that is not work. It is sized in em off the stack so it shrinks
   with the composition rather than sitting at a fixed size beside it. */
.stack__note {
  position: absolute;
  /* sits a little right of the cat's centre, as in the reference — dead centre
     under it would read as a caption bar rather than as an aside */
  left: 62%;
  top: 86.5%;
  width: 30%;
  text-align: center;
  font-family: var(--font-nav);
  color: var(--ink-dim);
}

.stack__arrow {
  display: block;
  width: 16%;
  height: auto;
  margin: 0 auto 6px;
  color: var(--ink-dim);
}

.stack__note-line {
  display: block;
  font-size: 11px;
  letter-spacing: 0.06em;
}

.stack__note-name {
  display: block;
  margin-top: 2px;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Bio

   A lead and its body, not two equal columns: the lead is display type in the
   left third and the paragraphs run in the right two thirds. Splitting it this
   way is what stops five paragraphs from reading as a wall.
   -------------------------------------------------------------------------- */

.bio {
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: 96px;
  padding: 92px 0 96px;
}

/* The figure carries the whole left column now, so it is set at a size that
   can be read as a number rather than as the opening of a sentence — there is
   no point counting something up at body size. */
.bio__figure {
  margin: 0;
  font-family: var(--font-display);
  font-size: 76px;
  font-weight: 600;
  /* 1.1 rather than 1: the line mask below clips to the line box, and at 1 the
     top of the digits sits on that edge */
  line-height: 1.1;
  letter-spacing: -0.02em;
}

/* tabular figures so the + does not step sideways as the count runs */
.tally { font-variant-numeric: tabular-nums; }

.bio__lead {
  margin: 14px 0 0;
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 600;
  line-height: 1.32;
  letter-spacing: -0.005em;
}

/* --------------------------------------------------------------------------
   Line masks

   Each line of the bio sits in its own strip of clipped overflow and starts
   just below it, so it rises into place rather than fading. js/about.js splits
   the text into these — where a line breaks is something only layout knows —
   and writes each one's delay inline.

   The padding and the negative margin cancel: without the padding the mask
   clips descenders and the Lithuanian diacritics, and without the matching
   negative margin that padding would add up over every line and open the
   paragraph's leading.
   -------------------------------------------------------------------------- */

/* held back only for the moment between the script starting and the webfonts
   arriving, which is when the split can finally be measured */
.bio.is-splitting .bio__lead,
.bio.is-splitting .bio__body { visibility: hidden; }

.ln {
  display: block;
  overflow: hidden;
  padding-bottom: 0.09em;
  margin-bottom: -0.09em;
}

.ln__i {
  display: block;
  transform: translateY(106%);
  transition: transform 0.85s cubic-bezier(0.16, 1, 0.3, 1);
}

.bio.is-lines-in .ln__i { transform: none; }

.bio__body { max-width: 40em; }

.bio__body p {
  margin: 0 0 22px;
  font-size: 17px;
  line-height: 1.62;
  color: var(--ink-dim);
}

.bio__body p:last-child {
  margin-bottom: 0;
  /* the closing line is an offer, not more background — it comes forward */
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Disciplines
   -------------------------------------------------------------------------- */

.disciplines {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 72px;
  row-gap: 62px;
  padding: 88px 0 104px;
}

.discipline__no {
  display: block;
  font-family: var(--font-nav);
  font-size: 16px;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
}

.discipline__title {
  margin: 10px 0 0;
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 600;
  letter-spacing: -0.005em;
}

.discipline__note {
  margin: 12px 0 0;
  max-width: 30em;
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink-dim);
}

/* --------------------------------------------------------------------------
   Running strip

   Fourteen 35mm frames — her own photographs rather than a second showing of
   the work page. Full-bleed: negative margins cancel the page gutter so the
   frames reach both edges of the canvas. The track holds the set twice and
   travels by exactly one copy — at -50% the second copy sits precisely where
   the first started, so the loop restarts on an identical pixel and there is
   no seam to see.

   These are all the same 3:2 landscape, so unlike the mixed set before them
   the strip really is a row of tiles now. What varies is the picture, not the
   format.
   -------------------------------------------------------------------------- */

.strip {
  margin-left: calc(var(--pad-x) * -1);
  margin-right: calc(var(--pad-x) * -1);
  overflow: hidden;
}

/* 194s, not the 64s this ran at before, because the speed is what should stay
   the same and the track got three times longer. One copy is 16 056px of
   artwork, which at the 380px display height is 8 028px on screen; over 194s
   that is 41.4 px/s — the same crawl the nine-frame strip had. Set to 64s the
   frames would tear past at 125 px/s. */
.strip__track {
  display: flex;
  width: max-content;
  animation: strip-run 194s linear infinite;
}

.strip__set {
  display: flex;
  flex-shrink: 0;
}

.strip__img {
  height: 380px;
  width: auto;
  object-fit: cover;
}

@keyframes strip-run {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* Hovering one frame takes the rest down to a third, so the strip stops being
   a row of equal things and becomes one thing being looked at. The lift is small
   on purpose — at 1.02 a 380px frame grows about four pixels a side, which
   reads as attention rather than as a zoom.

   Pointer devices only: on a touch screen :hover sticks after a tap and the
   whole strip would stay dimmed around whichever frame was last touched.

   z-index needs the position to work, and it is needed because a lifted frame
   overlaps the two beside it — without it the growth is clipped by whichever
   neighbour happens to paint later. */
@media (hover: hover) {
  .strip__img {
    position: relative;
    transition: opacity 0.38s ease,
                transform 0.38s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .strip:hover .strip__img { opacity: 0.35; }

  .strip:hover .strip__img:hover {
    z-index: 2;
    opacity: 1;
    transform: scale(1.02);
  }
}

/* --------------------------------------------------------------------------
   Call to action
   -------------------------------------------------------------------------- */

.cta {
  padding: 108px 0 96px;
  text-align: center;
}

.cta__eyebrow {
  margin: 0;
  font-family: var(--font-nav);
  font-size: 16px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.cta__link {
  display: inline-block;
  margin-top: 22px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--hairline);
  font-family: var(--font-display);
  font-size: 46px;
  font-weight: 600;
  letter-spacing: -0.01em;
  transition: border-color 0.4s ease;
}

.cta__arrow {
  display: inline-block;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

.cta__link:hover { border-bottom-color: var(--ink); }
.cta__link:hover .cta__arrow { transform: translateX(10px); }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

/* the footer itself is in base.css — the same two lines on all four pages */
.site-foot { padding-top: 34px; }

/* --------------------------------------------------------------------------
   Phones

   Below this width the canvas is abandoned rather than scaled — 1440 inside
   390 would set the body copy at 4px. js/about.js clears the transform and the
   page becomes an ordinary fluid layout. Must match MOBILE_W in js/about.js.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {

  #shell {
    height: auto !important;
    overflow: visible;
  }

  #page {
    width: 100%;
    padding: 0 18px 64px;
    transform: none !important;
  }

  /* back into the flow: there is no fixed canvas to hang off any more */
  .header {
    position: relative;
    width: 100%;
    height: 64px;
    padding: 0;
  }

  .brand { font-size: 12px; }
  .nav { gap: 12px; }
  .nav a { font-size: 10px; }

  .intro {
    display: block;
    padding: 44px 0 56px;
  }

  /* Both children go back to full width — the desktop rule pins them to 620 and
     922, which is wider than the phone itself. justify-self has to go with them,
     and that is not housekeeping: Chrome honours it in block layout too, so
     `end` made the figure shrink-to-fit, and with every child inside it
     absolutely positioned there was nothing left to fit. It collapsed to 0 wide,
     took its aspect-ratio height down to 0 with it, and the whole composition
     vanished on phones while looking perfect on the desktop. */
  .intro__words,
  .intro__stack {
    width: auto;
    justify-self: auto;
  }

  /* the statement is the page's opening line — it keeps as much size as the
     screen will carry, which is what 8ch protects */
  .intro__title {
    max-width: 11ch;
    font-size: 38px;
  }

  /* the stack is percentages all the way down, so it survives the drop to one
     column untouched — only the caption needs help, because 11px was sized
     against a 617 box and this one is barely half that */
  .intro__stack { margin-top: 34px; }

  .stack__note-line { font-size: 9px; letter-spacing: 0.04em; }
  .stack__note-name { font-size: 13px; }

  .bio {
    display: block;
    padding: 48px 0 52px;
  }

  .bio__figure { font-size: 44px; }
  .bio__lead { font-size: 20px; }

  .bio__body { margin-top: 26px; }

  .bio__body p {
    font-size: 15px;
    margin-bottom: 18px;
  }

  .disciplines {
    grid-template-columns: 1fr;
    row-gap: 38px;
    padding: 48px 0 56px;
  }

  .discipline__no { font-size: 13px; }
  .discipline__title { font-size: 18px; }
  .discipline__note { font-size: 14px; }

  .strip {
    margin-left: -18px;
    margin-right: -18px;
  }

  .strip__img { height: 220px; }

  /* Same arithmetic as the desktop duration, at the phone's display height:
     16 056px of artwork shown 220px tall is 4 648px on screen, and the phone
     strip has always run a little quicker than the desktop one — 36.6 px/s
     rather than 41.4 — because the same distance at this scale would crawl.
     4 648 / 36.6 = 127s. */
  .strip__track { animation-duration: 127s; }

  .cta { padding: 56px 0 48px; }
  .cta__eyebrow { font-size: 13px; }
  .cta__link { font-size: 30px; }

  .site-foot { padding-top: 26px; }
}

/* --------------------------------------------------------------------------
   Scroll reveal — the is-in class is set by js/about.js
   -------------------------------------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}

.reveal.is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .reveal { transition: none; }

  /* the lines are already in place; js/about.js also skips the count */
  .ln__i {
    transform: none;
    transition: none;
  }

  .reveal {
    opacity: 1;
    transform: none;
  }

  /* a strip that never stops is the one thing on this page that would fight a
     reduced-motion setting, so it simply holds still */
  .strip__track { animation: none; }

  /* the dimming stays — it is what the hover is for — but nothing moves */
  .strip__img { transition: opacity 0.38s ease; }
  .strip:hover .strip__img:hover { transform: none; }

  .cta__arrow { transition: none; }
}
