/* fun mode V2, scrapbook: type layer. Loads after fun.css; everything scoped under html.fun-mode.

   RANSOM LETTERING. ransom.js cuts each title into glyphs and each glyph is a
   real scanned clipping: `.rn` is the piece, `.rn-i` is the clipping itself.
   The paper, the torn edge and the ink are all inside the file, so there is
   nothing here that draws them: no font-family on a letter, no background
   paper, no grain tile, no clip-path edge, no text-stroke, and no hard fake
   shadow — a cut letter lying on a page casts almost nothing.

   Colour is printed rather than filled: `.rn-c` carries the colour, clipped to
   the clipping's own silhouette by a mask of the same file, and the letter
   multiplies over it, so white paper takes the colour and black ink stays
   black. That is for the punk set only. `.rn-col` is a magazine cutting, which
   arrived printed in colour already — it is never given `.rn-c`, and the rule
   below makes sure no colour, mask or blend can reach one by any other route.

   NOTE, standing: no handwritten or script typeface, no marker rings, no
   underlines, no doodles, no tape, no paperclips and no drawn arrows belong in
   this sheet. They were removed on purpose. Do not add them back. */

/* the tokens live on the curtain too: it outlives the class by half a second on the way out */
html.fun-mode,
.fun-wipe {
  /* the optical ink height of a cut letter, in ems of the title it sits in.
     ransom.js divides it by each clipping's own measured ink fraction, so a
     tall thin cutting and a squat wide one still read as one line of letters. */
  --rn-cap: .72em;
}

/* the sentence for assistive tech; the clippings are aria-hidden */
html.fun-mode .rn-sr,
.fun-wipe .rn-sr {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---- the host: a lettered title ---- */
html.fun-mode .rn-host {
  line-height: 1.24;
  text-transform: none;
  letter-spacing: 0;
  /* the clippings carry their own paper margins, so the word gap is already
     generous before the space character is added */
  word-spacing: -.16em;
  overflow-wrap: normal;
  padding: .12em .2em .1em 0;
  margin-left: -.05em;
  position: relative;
}
html.fun-mode .rn-word,
.fun-wipe .rn-word {
  font-size: calc(1em * var(--rn-fit, 1));   /* ransom.js steps this down when a title outgrows its column */
  display: inline-block;
  white-space: nowrap;
  position: relative;
  vertical-align: baseline;
  margin: 0 .09em;
}
/* a word that will not fit its column may break between its pieces */
html.fun-mode .rn-tighter .rn-word { display: inline; white-space: normal; }

/* ---- the piece: one clipping ---- */
html.fun-mode .rn,
.fun-wipe .rn {
  display: inline-block;
  position: relative;
  /* the clipping hangs below the baseline by exactly the paper margin under
     its ink, so every letter in the word sits on one line */
  vertical-align: calc(-1 * var(--bp, 0em));
  z-index: var(--z, 1);
  margin-left: var(--ml, 0);
  transform: rotate(var(--r, 0deg)) translateY(var(--dy, 0)) scale(var(--s, 1));
  transform-origin: 50% 60%;
  /* paper on paper: a hair of contact shadow, nothing more */
  filter: none;
  transition: transform .45s cubic-bezier(.34, 1.56, .64, 1);
  -webkit-user-select: none;
  user-select: none;
}
html.fun-mode .rn-i,
.fun-wipe .rn-i {
  display: block;
  height: var(--h, 1em);
  width: auto;
  max-width: none;
  -webkit-user-drag: none;
}
html.fun-mode .rn-word:first-child .rn:first-child { margin-left: 0; }
html.fun-mode .rn:hover,
.fun-wipe .rn:hover {
  transform: rotate(0deg) translateY(calc(var(--dy, 0) - .1em)) scale(calc(var(--s, 1) * 1.06));
  z-index: 40;
}

/* the colour, printed: the wrapper is the ink pad, clipped to the clipping's
   own shape so no colour ever shows outside the torn paper, and the letter
   multiplies over it */
html.fun-mode .rn-c,
.fun-wipe .rn-c {
  background-color: var(--c, transparent);
  -webkit-mask-image: var(--src);
  mask-image: var(--src);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  isolation: isolate;
}
html.fun-mode .rn-c .rn-i,
.fun-wipe .rn-c .rn-i { mix-blend-mode: multiply; }

/* a magazine cutting is placed as it was cut: its own gold, chrome or printed
   colour, with nothing laid over or under it. Multiplying pink into a gold
   foil letter makes mud, so this is stated rather than merely not done. */
html.fun-mode .rn-col,
.fun-wipe .rn-col {
  background-color: transparent;
  -webkit-mask-image: none;
  mask-image: none;
  mix-blend-mode: normal;
  isolation: auto;
}
html.fun-mode .rn-col .rn-i,
.fun-wipe .rn-col .rn-i { mix-blend-mode: normal; }

/* characters with no cutting — punctuation, symbols, anything outside a-z0-9 —
   are set in the page's own inherited face. No display face, no script face,
   no paper drawn behind them. */
html.fun-mode .rn-pt,
.fun-wipe .rn-pt {
  vertical-align: baseline;
  font-size: .82em;
  filter: none;
}

/* ---- settling in: the masthead's letters land one by one ---- */
@keyframes rn-settle {
  from { opacity: 0; transform: rotate(calc(var(--r, 0deg) * 4)) translateY(-.5em) scale(calc(var(--s, 1) * 1.3)); }
  to   { opacity: 1; transform: rotate(var(--r, 0deg)) translateY(var(--dy, 0)) scale(var(--s, 1)); }
}
html.fun-mode .rn-host[data-settle] .rn {
  animation: rn-settle .32s cubic-bezier(.34, 1.56, .64, 1) both;
  animation-delay: var(--d, 0s);
}
.fun-wipe .rn {
  animation: rn-settle .4s cubic-bezier(.34, 1.56, .64, 1) both;
  animation-delay: calc(.35s + var(--i, 0) * .04s);
}
/* ---- the same landing, further down the page ----
   A masthead settles on load because you are already looking at it. The
   footer's line is two or three screens down, so settling it at build time
   spends the motion on nobody: ransom.js arms that host with
   data-settle-wait, which holds its pieces back at zero, and swaps it for
   data-settle the first time the host crosses into view. Same keyframe,
   same curve, same per-piece delay — nothing new, only later. */
html.fun-mode .rn-host[data-settle-wait] .rn { opacity: 0; }

/* ---- the same landing, for something that is not a letter ----
   The overshoot, the curve and the drop are rn-settle's; what changes is
   what is arriving. A cut letter is a scrap of paper and may land crooked,
   so rn-settle resolves TO its own tilt. A word, a link or a panel is
   text-bearing and has to end square, so this one resolves to nothing at
   all — it leans in on the way down and is level by the time it stops.
   Transform and opacity only: nothing here reflows or moves a hit target,
   and every user of it fires once, on arrival, and then stays put. */
@keyframes rn-settle-block {
  from { opacity: 0; transform: translateY(-.34em) scale(1.1) rotate(var(--sr, -1.6deg)); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  html.fun-mode .rn-host[data-settle] .rn,
  .fun-wipe .rn { animation: none; }
  /* the armed state is a hiding place, not a decoration: with the animation
     off there is nothing left to release the pieces, so they are never held */
  html.fun-mode .rn-host[data-settle-wait] .rn { opacity: 1; }
  html.fun-mode .rn, .fun-wipe .rn { transition: none; }
  html.fun-mode .rn:hover, .fun-wipe .rn:hover { transform: rotate(var(--r, 0deg)) translateY(var(--dy, 0)) scale(var(--s, 1)); }
}

/* ---- the curtain word ----
   chrome.css dresses `.fun-wipe span` (a yellow scrap drawn as ::before, and
   padding); the pieces inside the word are spans too, so they hand that back */
.fun-wipe span.rn-host { display: block; line-height: 1.2; text-transform: none; font-variation-settings: normal; font-optical-sizing: auto; }
.fun-wipe .rn-word, .fun-wipe .rn { padding: 0; isolation: auto; }
.fun-wipe .rn-c { isolation: isolate; }
.fun-wipe .rn-word::before, .fun-wipe .rn::before, .fun-wipe .rn-sr::before { content: none; }
.fun-wipe .rn-word { margin: 0 .09em; }

/* ---- the stats: a clipping pinned onto a stack of paper ---- */
html.fun-mode .rn-stat {
  display: inline-block;
  position: relative;
  white-space: nowrap;            /* a number never breaks; ransom.js shrinks it to its column instead */
  padding: .22em .3em .18em .26em;
  margin: .2em 0 .25em -.1em;
  line-height: 1.05;
  isolation: isolate;
}
html.fun-mode .rn-stat::before,
html.fun-mode .rn-stat::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: #fff;
  box-shadow: none;
  transform: rotate(var(--sr1, 3deg));
}
html.fun-mode .rn-stat::after {
  background-color: #efeade;
  transform: rotate(var(--sr2, -4deg)) translate(.12em, .1em);
  z-index: -2;
}
/* the pin: a red head with a highlight, its shadow on the paper */
html.fun-mode .rn-pin {
  position: absolute;
  left: var(--px, 50%);
  top: -.18em;
  width: .28em; height: .28em;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 32%, #e8a0a6 0 18%, #c43b2f 40%, #7a1a14 100%);
  box-shadow: none;
  z-index: 50;
  pointer-events: none;
}
html.fun-mode .rn-pin::after {
  content: "";
  position: absolute;
  left: 45%; top: 80%;
  width: .06em; height: .22em;
  background: linear-gradient(#777, #bbb);
  transform: rotate(-24deg);
  transform-origin: top;
  z-index: -1;
}
/* the numbers stay inside their column: the three RAF results share a row */
html.fun-mode .pv-results > div { min-width: 0; }
html.fun-mode .pv-results .rn-stat { font-size: clamp(30px, 2.6vw, 44px); }
/* a title tightened on a phone loses the overlap and the word gaps first */
html.fun-mode .rn-tight .rn { margin-left: 0; }
html.fun-mode .rn-tight .rn-word { margin: 0 .05em; }

/* ---- the titles, one by one ---- */
html.fun-mode .home-masthead h1.rn-host { max-width: 22ch; }
html.fun-mode .index-title.rn-host { line-height: 1.3; }
html.fun-mode .fx-invite.rn-host { font-size: clamp(24px, 2.4vw, 34px); line-height: 1.34; max-width: none; }
html.fun-mode main h2.rn-host { line-height: 1.28; }
html.fun-mode .cs-title.rn-host,
html.fun-mode .page-title.rn-host { line-height: 1.26; }
html.fun-mode .section-heading.rn-host { line-height: 1.34; }

/* ---- phones ---- */
@media (max-width: 760px) {
  html.fun-mode .rn-host { line-height: 1.24; padding-right: .1em; }
  html.fun-mode .rn-word { margin: 0 .06em; }
  html.fun-mode .home-masthead .mast-name.rn-host { display: block; margin-bottom: 14px; }
  html.fun-mode .pv-results .rn-stat { font-size: clamp(26px, 8vw, 34px); }
  html.fun-mode .rn-stat { padding: .18em .22em .14em .2em; }
  html.fun-mode .fx-invite.rn-host { font-size: 22px; }
}
