/* ============================================================
   THE FIRST SCREEN, THE BAR AND THE HELD PANELS (17 September 2026).

   The client sent wearecollins.com's code and asked for three things:

     1. THE PAGE THAT LOADS FIRST, in their language — a screen that is
        almost empty, one line held in the middle, small type along the
        foot. Their own numbers, read off the code they sent: a grid
        90svh tall in three rows, the title in the middle row, the meta
        row under it, both rising 8rem and fading in on an expo-out curve
        over a second and a half.
     2. IN OUR FACES. "i dont want u to change the font" — so no serif is
        borrowed with the layout; this is the site's own display and UI
        faces at their own sizes.
     3. THE FOOT KEPT. The three things that sat along the bottom of the
        old opening stay exactly where they were.

   THE BAR, ALSO THEIRS: it is fixed, it slides away as you go down and
   comes straight back the moment you go up (transform + .45s). The one
   change the client asked for: the name never leaves — only the rest of
   the bar travels.

   THE PANELS: the scroll the opening used to have, carrying how-it-works,
   the niches and the questions instead. See fs.js.
   ============================================================ */

.leo{
  --fs-mid:color-mix(in srgb, var(--ink) 58%, var(--ground));
  --fs-pad:max(2.4rem, calc((100vw - 132rem) / 2));
  --fs-ease:cubic-bezier(.19,1,.22,1);
}

/* ---------- THE BAR ---------- */
/* it keeps its place in the layout; only what is inside it travels */
.leo .bar{background:var(--ground); transition:background .4s var(--fs-ease)}
.leo .bar.is-top{background:transparent}
.leo .bar-left,.leo .bar-actions{
  transition:transform .45s var(--ease-in-out-cubic, cubic-bezier(.645,.045,.355,1)),
             opacity .3s var(--fs-ease);
}
/* going down: everything but the name leaves upward. Going up: it is back
   before the reader has finished the gesture — no delay, no fade-in wait. */
.leo .bar.is-hid .bar-left,.leo .bar.is-hid .bar-actions{
  transform:translateY(-140%); opacity:0; pointer-events:none;
}
.leo .bar .bar-brand{transition:none}

/* ---------- THE FIRST SCREEN ---------- */
.fs{
  display:grid; grid-template-rows:1fr auto 1fr; align-items:center; justify-items:center;
  min-height:100svh; padding:0 var(--fs-pad); position:relative; text-align:center;
  /* the campaigns start their own screen, not this one's last inch */
  margin-bottom:8svh;
}
/* NO BLANKET GAP. The three children join differently: the second sentence
   is part of the statement and sets its own margin in ems so it tracks the
   type, and the rule stands well clear of both. One gap for all three put the
   tagline as close to the statement as the statement's own second line. */
.fs-mid{grid-row:2/3; display:grid; justify-items:center; gap:0}
/* THE UPPERCASE STATEMENT WAS DELETED HERE on 20 September 2026, and with it
   the fit that sized it: --lead-ratio 23.339 (measured), --lead-fill 0.84,
   .fs-h1, .fs-h1_lead, .fs-h1_sub, the old .fs-say Rail setting and the
   container-type the fit needed. The client: "i like the cosmos simplicity".

   Five revisions of that setting are in _bak/pre-cinema-2026-09-20/ if the
   loud opening is ever wanted back. It is not reachable from anything here —
   the markup it styled is gone from index.html.

   WHAT REPLACES IT is below: one quiet sentence-case line on the first
   screen, and the statement moved into a held sequence that the scroll steps
   through. */



/* ---------- THE HELD SEQUENCE ---------- */
/* the track's height IS the length of the sequence: three states, one window
   of scroll each, plus one to leave on. */
.cin{position:relative; height:320svh; margin-bottom:8svh}
.cin-in{
  position:sticky; top:0; min-height:100svh;
  display:grid; align-items:center; justify-items:center;
  padding:0 var(--fs-pad); text-align:center;
}
/* the foot and the hairline are absolute children of this frame, so they hold
   their place at the foot of the window for the whole sequence instead of
   scrolling away with the first line */
.cin-in > .fs-foot,.cin-in > .fs-drip{position:absolute}
.cin-s{
  grid-area:1/1; margin:0; max-width:22ch;
  font-family:var(--face); font-weight:500;
  
  font-size:clamp(2.2rem, 3.2vw, 4.4rem); line-height:1.22; letter-spacing:-0.02em;
  color:var(--ink);
  opacity:0; transform:translateY(2.4rem);
  transition:opacity var(--speed-slow) var(--power3-out),
             transform var(--speed-slow) var(--power3-out);
}
.cin-s.is-on{opacity:1; transform:none}
.cin-s.is-before{transform:translateY(-2.4rem)}
/* no script, or less motion: the three simply stand one after the other */
.cin:not(.is-run){height:auto; margin-bottom:var(--s6)}
.cin:not(.is-run) .cin-in{position:static; display:block; min-height:0; padding:var(--s6) var(--fs-pad)}
.cin:not(.is-run) .cin-s{opacity:1; transform:none; margin:0 auto var(--s5)}
/* WITH SCRIPT, NOT YET RUN. fs.js is deferred, so for a moment on every load
   the page is in the no-script state above and all three lines stood at once
   over the name. html.js is set in the head; the lines wait for fs.js. Under
   reduced motion fs.js never runs the opening, so they are left alone. */
@media (prefers-reduced-motion:no-preference){
  html.js .cin:not(.is-run) .cin-s{opacity:0}
}


@keyframes fs-rise{ to { opacity:1; transform:none } }

/* the foot the client kept */
.fs-foot{
  position:absolute; left:0; right:0; bottom:0;
  display:grid; grid-template-columns:1fr auto 1fr; align-items:end; gap:2rem;
  padding:0 var(--fs-pad) 3.2rem;
  opacity:0; animation:fs-rise 1.5s var(--fs-ease) .5s forwards;
}
.fs-corner{
  margin:0; font-family:var(--face-ui); font-size:1.2rem; font-weight:600; line-height:1.35;
  letter-spacing:.08em; text-transform:uppercase; color:var(--fs-mid); text-decoration:none;
}
.fs-corner--l{justify-self:start; text-align:left}
.fs-corner--c{justify-self:center; color:var(--ink); font-family:var(--face); font-weight:900;
   letter-spacing:.01em; font-size:1.6rem}
.fs-corner--r{justify-self:end; color:var(--ink); transition:opacity var(--speed) var(--easing)}
/* the corner is already ink at 600; the counted number inside it should not
   jump to the browser's bold the way the meta row's deliberately does */
.fs-corner--r b{font-weight:inherit}
.fs-corner--r:hover,.fs-corner--r:focus-visible{opacity:.6}

/* the hairline that says the page scrolls, as the old opening had */
.fs-drip{
  position:absolute; left:50%; bottom:9.6rem; width:1px; height:4.8rem; overflow:hidden;
  background:color-mix(in srgb, var(--ink) 20%, transparent); transform:translateX(-50%);
  opacity:0; animation:fs-rise 1.5s var(--fs-ease) .7s forwards;
}
/* THE FALLING DASH TAKES THE SPARK (23 September 2026). It is the only
   thing on the first screen that moves, and --spark is the colour for what
   is alive — see the list in tokens.css. Its TRACK stays ink at 20%: a
   coloured track would read as a bar with a value, which this is not. */
.fs-drip i{position:absolute; inset:0; background:var(--spark); animation:fs-drip 2.4s var(--fs-ease) infinite}
@keyframes fs-drip{ 0%{transform:translateY(-100%)} 60%,100%{transform:translateY(100%)} }
/* Stopped, not paused, once the page scrolls: a paused animation keeps its
   compositing layer, and that layer inside the sticky frame is the shake.
   animation:none takes the layer away with it. See fs.js, block 1c. */
.is-past-top .fs-drip{visibility:hidden}
.is-past-top .fs-drip i{animation:none}

/* THE LOCK. While the opening has the input, the document cannot scroll at
   all — not by the wheel, not by momentum left over from a flick, not by a
   bounce off the top. overscroll-behavior stops the bounce and a phone's
   pull-to-refresh; fs.js stops the finger. */
html.is-cin-lock,html.is-cin-lock body{overflow:hidden; overscroll-behavior:none}

/* ---------- THE THREE HELD PANELS ---------- */
.pan{position:relative; height:300svh}
.pan-in{
  position:sticky; top:0; min-height:100svh;
  display:grid; align-items:center; padding:10svh 0 12svh;
}
.pan-in > .lp-panel{
  grid-area:1/1; width:100%;
  /* --pan-k is written by fs.js: a panel taller than the held frame (the
     questions are) is brought down to fit rather than cropped by it */
  opacity:0; transform:translateY(3rem) scale(var(--pan-k, 1)); transform-origin:center;
  pointer-events:none;
  transition:opacity .4s var(--power2-in-out, ease), transform .6s var(--fs-ease);
}
.pan-in > .lp-panel.is-on{opacity:1; transform:scale(var(--pan-k, 1)); pointer-events:auto}
.pan-in > .lp-panel.is-before{transform:translateY(-3rem) scale(var(--pan-k, 1))}
.pan-count{
  grid-area:1/1; align-self:start; justify-self:center; margin:0;
  font-family:var(--face-data); font-size:1.1rem; letter-spacing:.12em;
  color:var(--fs-mid);
}
/* no script, or less motion: they simply stand one after the other */
.pan:not(.is-run){height:auto}
.pan:not(.is-run) .pan-in{position:static; display:block; padding:0}
.pan:not(.is-run) .pan-in > .lp-panel{opacity:1; transform:none; pointer-events:auto; margin-bottom:var(--s5, 6rem)}
.pan:not(.is-run) .pan-count{display:none}

@media (max-width:768px){
  .leo{--fs-pad:1.6rem}
  .fs-foot{grid-template-columns:1fr 1fr; grid-template-areas:"c c" "l r"; row-gap:1.6rem; padding-bottom:2.4rem}
  .fs-corner--l{grid-area:l}
  .fs-corner--c{grid-area:c}
  .fs-corner--r{grid-area:r; text-align:right}
  .fs-drip{bottom:14rem; height:3.2rem}
  .pan{height:280svh}
  .pan-in{padding:8svh 0 10svh}
}

@media (prefers-reduced-motion:reduce){
  .fs-foot,.fs-drip{animation:none; opacity:1; transform:none}
  .fs-drip i{animation:none}
  .leo .bar-left,.leo .bar-actions,.pan-in > .lp-panel{transition:none}
}


/* ==============================================================
   THE FLYING WORDMARK (20 September 2026)
   ==============================================================
   leo.css still carries .leo-mark itself — fixed, full width, transform-origin
   at the TOP CENTRE, which is what lets a scale read as the word receding
   rather than shrinking in place. Only what drives it is here.

   ONE ELEMENT, NOT A HAND-OFF. fs.js writes a single transform per frame and
   never touches layout, so the whole flight is on the compositor. The bar's
   own copy of the name is hidden on this page for the same reason the old
   opening hid it: two names, one of them travelling, is the bug that version
   had. It comes back the moment the script is not running. */
/* gated on .is-flying, which fs.js adds only once it has actually taken the
   mark over. Without scripts, or under reduced motion, the bar keeps its own
   name and the travelling one is never shown — no flash either way. */
.leo-mark{display:none}
html.is-flying .leo-mark{display:block}
/* one rasterisation, then the compositor scales it: without this the glyphs
   re-snap to a different subpixel grid on every frame of the flight and the
   word shimmers as it shrinks */
.leo-mark{will-change:transform; backface-visibility:hidden}
html.is-flying .leo .bar-brand{visibility:hidden}
/* landed: it stops being a passenger and becomes the bar's link again */
.leo-mark.is-locked{pointer-events:auto}


/* DEAD RULES REMOVED (20 September 2026). is-seq-js and is-seq-css belonged
   to the scroll-driven version of the statements and nothing sets either class
   any more. They are gone rather than left dormant because one of them carried
   will-change:transform on .cin-s — a composited layer inside the sticky
   frame, which is the very thing that makes the whole first screen shake. A
   dead rule that would reintroduce the bug the day someone revives the class
   is worse than no rule. */

/* ============================================================
   THE OPENING (20 September 2026)

   The client, on the name: "mynichefund je ale free roam, nema 3 lokacie kde
   sa zastavi presne, on sa stale hybe zmensuje, mozes zastavit hocikde a
   vratit sa bud dozadu co ho zvacsuje znova alebo dopredu co ho zmensuje."

   So the name is not stepped. Its position and size are a function of how
   far into the opening you are (fs.js, block 2c) — stop anywhere and it
   stops there; go back and it grows again. The three statements still change one at a time, because
   two of them lit at once draws two different texts through each other, and
   that ghosting is what read as shaking on 20 September.
   ============================================================ */

/* ONE SCREEN, NOT A TRACK (21 September 2026). With the page locked for the
   whole opening there is no scroll to spend, so the section is exactly one
   window tall and the frame in it is not sticky — nothing is pinned, because
   nothing moves. The 320svh track and position:sticky are what the page used
   to scroll underneath, and the re-pinning on every frame was the shake.
   fs.js, block 2c, has the lock. */
.cin.is-run{
  height:100svh; min-height:0; margin-bottom:4svh; padding:0;
  display:block; position:relative;
}
.cin.is-run .cin-in{
  position:relative; height:100svh; min-height:0;
  display:grid; grid-template-rows:1fr auto 1fr;
  align-items:center; justify-items:center;
  padding:var(--fs-toproom) var(--fs-pad) var(--fs-footroom);
  text-align:center;
}

/* THE STATEMENTS ARE THE HEADLINE, one at a time, sharing one cell so the
   screen does not reflow as they trade places. */
.cin.is-run .cin-s{
  grid-row:2; grid-column:1; margin:0; max-width:16ch;
  font-family:var(--face); font-weight:900;
  
  font-size:clamp(3.2rem, 5.6vw, 7.2rem); line-height:.98; letter-spacing:-0.02em;
  text-transform:uppercase; color:var(--ink);
  /* the base .cin-s still carries translateY(2.4rem) from the version that
     slid them into place; without this they sit 24px low */
  transform:none; animation:none;
  opacity:0; transition:opacity .26s var(--easing);

  /* THE ANTIALIASING IS PINNED, AND NO LAYER IS MADE (20 September 2026).

     Two faults meet on this element and the cure for one is the cause of the
     other. Left alone, the browser makes a compositing layer the moment a
     statement's opacity leaves 1 and destroys it when it reaches 0; making one
     switches the text from subpixel antialiasing to grey, destroying it
     switches back, and every glyph changes weight across that switch — twice
     per hand-over, which is where the client first saw it shake.

     The obvious answer, holding the layer permanently, was tried and was
     worse: a composited layer INSIDE a position:sticky frame has to be kept in
     step with the frame's offset on every scrolled frame, and when it is not,
     everything in the frame shakes — not at the hand-overs but continuously,
     which is exactly what the client reported next.

     So the switch is removed instead of the layer. Pinning the smoothing means
     the glyphs are drawn the same way whether or not the browser decides to
     promote the element, so promotion becomes invisible and nothing inside the
     sticky frame is composited. */
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}
/* NEVER TWO AT ONCE: the outgoing one leaves over .26s with no delay, the
   incoming one is held back .3s, by which time the cell is empty. */
.cin.is-run .cin-s.is-on{opacity:1; transition:opacity .34s var(--easing) .3s}

@media (max-height:760px){
  .cin.is-run .cin-s{font-size:clamp(2.8rem, 4.6vw, 5.6rem)}
}

/* no script: the three simply stand one after the other, as the single
   headline did, and nothing is sticky or tall */
.cin:not(.is-run) .cin-in{display:block; position:static}
.cin:not(.is-run) .cin-s{opacity:1; transform:none; margin:0 auto var(--s5)}

/* arriving from inside the site: the name is not shown big while fs.js
   puts it straight into the bar */
html.cin-skip .leo-mark:not(.is-locked){opacity:0}

/* landed: the bar's own name is shown and the travelling one put away, so
   nothing fixed-and-transformed sits in the bar while the page moves */
html.is-flying.is-landed .leo .bar-brand{visibility:visible}
html.is-flying.is-landed .leo-mark{visibility:hidden}
/* the bar's name on this page is cut exactly like the travelling one, which
   hands over to it */
html.is-flying .leo .bar-brand,html.is-flying .leo .bar-brand a{
  font-weight:900;  letter-spacing:-0.02em;
}
/* ON A TOUCH SCREEN the opening holds the page by cancelling the finger
   (fs.js), not by switching the page's scrolling off: iPhone Safari swallowed
   the first swipe after scrolling was switched back on */
@media (hover:none) and (pointer:coarse){
  html.is-cin-lock,html.is-cin-lock body{overflow-y:visible}
}

/* THE OPENING IS ONE SCREEN (22 September 2026): the statements moved to the
   loading screen, so the track they used to be scrolled through is gone. */
.cin.is-run.is-simple{height:100svh; margin-bottom:8svh}
/* ONE LINE (client, 22 September 2026). The 16ch cap was cut for the wider
   face that used to set this; Helvetica is narrower, so the line broke in
   the middle instead of filling the screen. It is sized to the window now
   and never wraps. */
.cin.is-run.is-simple .cin-s{
  max-width:none; white-space:nowrap;
  font-size:clamp(2.2rem, 7.4vw, 9rem);
}
.cin.is-run.is-simple .cin-in{position:relative}

/* ============================================================
   THE BAR IS EMPTY UNTIL THE NAME ARRIVES IN IT (23 September 2026,
   client: "the top bar is not visible straight on laptop, once u scroll
   mynichefund locks into the top bar ... and also the other things
   appears").

   leo.css already faded .bar-nav, .bar-find and the theme button on
   .is-named, but that list was written for the desktop bar. At phone and
   tablet widths the bar shows a burger and a Log in pill instead, and
   neither was in it — so they sat on top of the giant name. Every direct
   child goes, including .bar-brand, whose own rule below says the same
   thing; the name in flight IS the bar's name until it lands.

   visibility, not opacity alone: a link at zero opacity is still a tab
   stop and still takes a click, and the whole first screen is under it.

   This is gated on .is-flying, which fs.js adds only on the landing page,
   so no other page's bar is touched. */
html.is-flying:not(.is-landed) .bar > *{
  opacity:0; visibility:hidden;
  transition:opacity var(--speed) var(--easing), visibility 0s linear var(--speed);
}
html.is-flying.is-landed .bar > *{
  opacity:1; visibility:visible;
  transition:opacity var(--speed-slow) var(--power3-out), visibility 0s;
}

/* ============================================================
   THE NAME AT THE TOP (23 September 2026, after cassettemusic.com, whose
   code the client sent: "mynichefund is massive on top, under it in grey
   1 quote from the loading page, same size as the cities are").

   THE ROOM IS RESERVED, NOT OCCUPIED. .leo-mark is position:fixed — it has
   no height in this flow at all — so fs.js measures the line box it draws
   and publishes it as --mark-room. Everything below clears it. The fallback
   is a viewport unit rather than a pixel count so a page without the script
   still lands somewhere sensible.
   ============================================================ */
.cin.is-run.is-simple .cin-in{
  grid-template-rows:auto 1fr;
  align-content:start;
  padding-top:calc(var(--mark-room, 24svh) + clamp(1.6rem, 2.4vw, 3.2rem));
}
.cin.is-run.is-simple .cin-s{grid-row:2; align-self:center}

/* THE GREY LINE. The reference sets its cities in small tracked-out
   capitals hard against the foot of the wordmark; this is that, in the
   role this site already has for a micro label — the figures face, uppercase,
   .14em — so it is not a new kind of type, only a new place for one.
   It fades on --hero-p, which fs.js drives from the same scroll as the
   name, so the two leave together instead of the line surviving alone. */
.cin.is-run.is-simple .cin-said{
  grid-row:1; margin:0; justify-self:center; text-align:center;
  font-family:var(--face-data); font-weight:400;
  font-size:clamp(1rem, 1.05vw, 1.3rem);
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--soft);
  opacity:var(--hero-p, 1);
  transition:opacity .18s linear;
}
/* without the script there is no flight and no --hero-p; the line still
   reads, it simply never fades */
html:not(.is-flying) .cin.is-run.is-simple .cin-said{opacity:1}
