/* ------------------------------------------------------------
   Start page (index.html, home.js)
   Builds on styles.css and the shared bar in landing.css.
   Positions are grid units (--u) of the 2000 × 1130 design,
   measured from the top-left of the area below the bar.

   The text grows in stages (TEXT + / −):
   1–3  more and more text (stage 3 is typed in on opening)
   4    the marked words (texts.md) grow large
   5    … in capitals
   7    … as outlines with changing weights; a letter fills black
        under the pointer (stage 6, plain outlines, is skipped)
   IMAGE + / − adds and removes project images (carousel/),
   DOODLES + / − illustrations (doodles/).
   Whatever was used last (text, images or doodles) lies on top; the
   controls always do.
   ------------------------------------------------------------ */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- Text ---------- */

.home-text {
  /* Sizes at full window size; --fit (home.js) makes them smaller
     where a stage would not fit into the frame */
  --size: 52;        /* text */
  --leading: 57.5;   /* line spacing */
  --big-size: 87;    /* marked words from stage 4 */
  --big-leading: 84;
  --ease: cubic-bezier(0.65, 0, 0.35, 1);

  position: absolute;
  z-index: 1;
  top: calc(90 * var(--u));
  left: calc(84 * var(--u));
  /* Line length: stages 1–3, wider from stage 4 */
  width: calc(1360 * var(--u));
  max-width: calc(100% - 124 * var(--u));
  margin: 0;
  font-size: calc(var(--size) * var(--u) * var(--fit, 1));
  line-height: calc(var(--leading) * var(--u) * var(--fit, 1));
  font-weight: 400;
  letter-spacing: -0.005em;
  pointer-events: none;
  transition:
    width 0.8s var(--ease),
    font-size 0.8s var(--ease),
    line-height 0.8s var(--ease);
}

/* The lines next to the controls end before them: an invisible
   float on the right, as high as from the top of the text to the
   bottom of the controls, whose shape only takes the controls'
   height (plus a gap) at its bottom. Desktop only: on the phone
   the text stays above the controls (home.js, fit). */
.home-text::before {
  --gap: calc(36 * var(--u));
  --controls-w: calc(124 * var(--mu) + 2 * 83 * var(--mu));
  --controls-h: calc(3 * 83 * var(--mu) + 2 * 43 * var(--mu));
  content: "";
  float: right;
  /* how far the text box reaches past the controls' left edge */
  width: max(0px, calc(84 * var(--u) + 100% + 81 * var(--u) + var(--controls-w) + var(--gap) - (100vw - 2 * var(--margin))));
  height: calc(100svh - 2 * var(--margin) - var(--bar-height) - 90 * var(--u) - 82 * var(--u));
  shape-outside: inset(calc(100% - var(--controls-h) - var(--gap)) 0 0 0);
}

/* Wider at once (longer lines make the text shorter), narrower
   smoothly once the words are small again (home.js) */
.home-text.is-wide {
  width: calc(1705 * var(--u));
  transition-property: font-size, line-height;
}

/* Words on top (after WORDS + / −): images and doodles step back
   (paler), so the words stay readable over them; once images or
   doodles come to the front again, they are fully there again.
   (Also tried: backing whole lines in the page colour; a rim in
   the page colour around every letter; mixing the words with
   the images below, mix-blend-mode: difference.) */
.home.words-front .home-img.is-in {
  opacity: 0.3;
}

/* Until home.js starts typing */
.js .home-text:not(.is-live) {
  visibility: hidden;
}

/* Letters still to be typed */
.home-text .is-hidden {
  display: none;
}

/* Words coming and going between stages 1–3 (home.js, CHANGE):
   "grow" eases their size from and to 0, "fade" their opacity */
.home-text .c.grow {
  transition:
    font-size 0.75s cubic-bezier(0.45, 0, 0.25, 1),
    opacity 0.5s ease;
}

.home-text .c.w-off {
  font-size: 0;
  opacity: 0;
}

.home-text .c.fade {
  transition: opacity 0.45s ease;
}

.home-text .c.is-fading {
  opacity: 0;
}

/* Marked words; --k (word number) lets them change one after another */
.home-text .e {
  transition:
    font-size 0.8s var(--ease) calc(var(--k, 0) * 25ms),
    line-height 0.8s var(--ease) calc(var(--k, 0) * 25ms),
    color 0.6s ease calc(var(--k, 0) * 25ms),
    font-weight 0.5s ease;
}

/* Sized from --fit directly (not from the text around them), so
   they ease straight to their final size */
.home-text.is-big .e {
  font-size: calc(var(--big-size) * var(--u) * var(--fit, 1));
  line-height: calc(var(--big-leading) * var(--u) * var(--fit, 1));
  font-weight: 500;
}

/* Capitals: switched letter by letter (home.js) */
.home-text .e.up {
  text-transform: uppercase;
}

/* Outlines: the fill turns white inside a contour (doubled: the
   fill covers its inner half, see styles.css) */
.home-text.is-outline .e {
  color: var(--bg);
  -webkit-text-stroke: calc(2 * var(--text-stroke)) var(--ink);
  paint-order: stroke fill;
}

/* Changing weights (--w per letter): they sweep in like LET'S TALK!,
   then shift under the pointer (home.js) */
.home-text.is-weights .e {
  font-weight: var(--w, 400);
  animation: home-sweep 1.3s cubic-bezier(0.45, 0, 0.2, 1) var(--d, 0s) backwards;
}

/* Hover: the letter under the pointer fills black (home.js), then
   eases back to its outline */
.home-text.is-hoverable .e {
  transition: color 0.45s ease, font-weight 0.5s ease;
}

.home-text.is-hoverable .e.is-filled {
  color: var(--ink);
  transition: color 0.12s ease;
}

@keyframes home-sweep {
  0%   { font-weight: 400; }
  50%  { font-weight: 900; }
  100% { font-weight: var(--w, 400); }
}

/* Copy used by home.js to measure a stage before showing it */
.home-text.is-measure,
.home-text.is-measure * {
  visibility: hidden;
  transition: none !important;
  animation: none !important;
}

/* ---------- Images and doodles ----------
   Placed freely in the frame (home.js: --x / --y from 0 to 1,
   width --w, height / width --ratio), always completely inside it */

.home-images {
  position: absolute;
  inset: calc(36 * var(--u));
  pointer-events: none;
}

.home-img {
  --w: calc(333 * var(--u));
  position: absolute;
  /* --s: size after a click (home.js); as it is part of the
     position, the image always stays inside the frame */
  --sw: calc(var(--w) * var(--s, 1));
  left: calc(var(--x) * (100% - var(--sw)));
  top: calc(var(--y) * (100% - var(--sw) * var(--ratio, 0.7361)));
  display: block;
  width: var(--sw);
  height: auto;
  /* Contour like all frames; an outline is drawn over the image */
  outline: var(--stroke) solid var(--ink);
  outline-offset: calc(-1 * var(--stroke));
  opacity: 0;
  transform: scale(0.97);
  transition: opacity 0.45s ease, transform 0.6s cubic-bezier(0.25, 0.1, 0.25, 1);
}

.home-img.is-in {
  opacity: 1;
  transform: none;
  /* A click makes it larger or smaller (home.js) */
  pointer-events: auto;
  cursor: pointer;
}

/* Its width changes (not a scale), so the contour stays as fine */
.home-img.is-scaling {
  transition:
    opacity 0.45s ease,
    transform 0.6s cubic-bezier(0.25, 0.1, 0.25, 1),
    width 0.7s cubic-bezier(0.34, 1.3, 0.64, 1),
    left 0.7s cubic-bezier(0.34, 1.3, 0.64, 1),
    top 0.7s cubic-bezier(0.34, 1.3, 0.64, 1);
}

/* Doodles lie freely on the page: no contour */
.home-doodle {
  outline: none;
}

/* ---------- Controls ----------
   Bottom right, always on top. A button that can't be used (no
   less text at stage 1, …) disappears; the others keep their place */

.home-controls {
  position: absolute;
  /* Quick clicks never select the labels */
  -webkit-user-select: none;
  user-select: none;
  z-index: 1000;
  right: calc(81 * var(--u));
  bottom: calc(82 * var(--u));
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: calc(43 * var(--mu));
}

.control {
  display: flex;
}

/* Appear one after the other once the text is there (home.js) */
.js .control {
  visibility: hidden;
}

.js .controls-in .control {
  visibility: visible;
  animation: show 0.01s steps(1) calc(var(--n, 0) * 0.2s) backwards;
}

/* Hidden with the rest of the page while imprint / privacy is open */
.legal-open .home-controls .control,
.legal-open .home-controls .control__button {
  visibility: hidden;
}

.control--image  { --n: 1; }
.control--doodle { --n: 2; }

.control__button,
.control__label {
  position: relative;
  height: calc(83 * var(--mu));
  margin-left: calc(-1 * var(--stroke));
  box-shadow: inset 0 0 0 var(--stroke) var(--ink); /* not border: browsers round thin borders down */
  background: var(--bg);
}

.control__label {
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(124 * var(--mu));
  font-size: calc(19 * var(--mu));
  letter-spacing: 0.01em;
  text-transform: uppercase;
}

.control__button {
  display: grid;
  place-items: center;
  width: calc(83 * var(--mu));
  padding: 0;
  border: 0;
  color: var(--ink);
  cursor: pointer;
  transition: opacity 0.3s ease, visibility 0s;
}

.control__button.is-off {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0s 0.3s;
}

/* Contour hover: the outline thickens, the sign gets bolder */
.control__button svg {
  width: calc(31 * var(--mu));
  overflow: visible;
  fill: currentColor;
  stroke: currentColor;
  stroke-width: 0;
  transition: stroke-width 0.35s ease;
}

.control__button:hover svg,
.control__button:focus-visible svg {
  stroke-width: 7px;
}

.control__button:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: -6px;
}

@media (prefers-reduced-motion: reduce) {
  .home-text,
  .home-text *,
  .home-img {
    transition: none !important;
    animation: none !important;
  }
}

/* Safety net: nothing of the start page ever shows outside the frame */
.home {
  overflow: clip;
}
