/* ------------------------------------------------------------
   Landing page
   The layout is drawn on a 2000 × 1130 grid (the original
   design). --u is one grid unit, scaled to fit the viewport.
   Type and arrow form one block that is centred on the page.
   ------------------------------------------------------------ */

/* ---------- Font ----------
   Archivo (SIL Open Font License, see fonts/OFL.txt), hosted
   with the site so no visitor data goes to Google. Variable:
   weight 100–900, width 62–125%. */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("fonts/archivo-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("fonts/archivo-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --bg: #ffffff;
  --ink: #000000;
  --stroke: 1px;               /* all contours */
  --text-stroke: var(--stroke); /* outlined type, visible width */

  --u: min(calc(100vw / 2000), calc(100svh / 1130));
  --margin: calc(82 * var(--u));
  --type-size: calc(264 * var(--u));
  --cap-offset: 0.1375;          /* space above cap height, in em */
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  height: 100%;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: "Archivo", system-ui, sans-serif;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

/* The whole start page is clickable (see main.js) */
.start-page {
  cursor: pointer;
}

/* ---------- Frame ---------- */

.frame {
  position: fixed;
  z-index: 3; /* lines stay on top of content scrolling past them */
  inset: 0;
  pointer-events: none;
}

.line {
  position: absolute;
  background: var(--ink);
}

.line--top,
.line--bottom {
  left: 0;
  right: 0;
  height: var(--stroke);
}

.line--top    { top: var(--margin); }
.line--bottom { bottom: var(--margin); }

.line--left,
.line--right {
  top: var(--margin);
  bottom: var(--margin);
  width: var(--stroke);
}

.line--left  { left: var(--margin); }
.line--right { right: var(--margin); }

/* ---------- Stage ----------
   Exactly as big as type + arrow; all positions inside it
   are measured from the top-left of the "P" in PORTFOLIO */

.stage {
  position: absolute;
  /* Centred without transform, so lines stay on whole pixels */
  top: calc(50% - 388.5 * var(--u));
  left: calc(50% - 760.5 * var(--u));
  width: calc(1521 * var(--u));
  height: calc(777 * var(--u));
}

/* ---------- Page transition ----------
   On arrow click the stage slides left and disappears
   under the left frame line (see main.js) */

.clip {
  position: fixed;
  inset: 0;
  clip-path: inset(0 0 0 calc(var(--margin) + var(--stroke)));
}

.leaving .stage {
  transform: translateX(-100vw);
  transition: transform 1.1s cubic-bezier(0.65, 0, 0.35, 1);
}

/* ---------- Typography ---------- */

.title {
  margin: 0;
  font-weight: inherit;
}

.word {
  position: absolute;
  left: calc(var(--x) * var(--u));
  /* --y is the top of the capital letters */
  top: calc(var(--y) * var(--u) - var(--cap-offset) * var(--type-size));
  font-size: var(--type-size);
  line-height: 1;
  white-space: nowrap;
  letter-spacing: -0.005em;
}

/* Outlined names: white fill + thin stroke, so each line
   covers the one before it where they overlap */
.word--paula,
.word--sophie,
.word--jae,
.word--bambach {
  color: var(--bg);
  /* The fill is painted over the inner half of the stroke,
     so it is doubled to show the full --text-stroke */
  -webkit-text-stroke: calc(2 * var(--text-stroke)) var(--ink);
  paint-order: stroke fill;
}

/* --w is the final font weight; letters can set their own */
.word,
.word * {
  font-weight: var(--w);
}

.word--paula   { --x: 440;  --y: 134; --w: 600; font-stretch: 101%; z-index: 1; }
.word--sophie  { --x: 159;  --y: 302; --w: 100; font-stretch: 97%; z-index: 2; }
.word--jae     { --x: 928;  --y: 422; --w: 400; font-stretch: 96.5%; z-index: 3; }
.word--bambach { --x: 58;   --y: 593; --w: 800; font-stretch: 96.5%; z-index: 4; }

.word--portfolio {
  --x: -18;
  --y: 0;
  --w: 400;
  font-stretch: 95%;
  letter-spacing: -0.02em;
  z-index: 5;
}

.word--portfolio b {
  --w: 900;
}

/* ---------- Arrow ---------- */

.arrow {
  position: absolute;
  z-index: 10;
  left: calc(1404 * var(--u));
  top: calc(648 * var(--u));
  width: max(32px, calc(117 * var(--u)));
  color: var(--ink);
}

/* On hover a same-coloured outline thickens around the shape,
   so the arrow looks like it gets bolder */
.arrow svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  fill: currentColor;
  stroke: currentColor;
  stroke-width: 0;
  stroke-linejoin: miter;
  transition: stroke-width 0.35s ease;
}

.arrow:hover svg,
.arrow:focus-visible svg {
  stroke-width: 14px;
}

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

/* ---------- Intro animation ----------
   1. frame lines draw in
   2. letters sweep from thin to black weight and settle
   3. arrow fades in
   main.js splits the words into letters and adds .intro once
   the font has loaded. Without JS everything is just shown. */

/* Frame drawing is for the start page only; other pages
   keep their frame in place */
.js:not(.intro) .start-page .frame,
.js:not(.intro) .stage {
  visibility: hidden;
}

.intro .start-page .line {
  animation: draw 1.1s cubic-bezier(0.65, 0, 0.35, 1) backwards;
}

.intro .start-page .line--top    { transform-origin: left;   animation-delay: 0.4s; }
.intro .start-page .line--right  { transform-origin: top;    animation-delay: 0.6s; }
.intro .start-page .line--bottom { transform-origin: right;  animation-delay: 0.8s; }
.intro .start-page .line--left   { transform-origin: bottom; animation-delay: 1s; }

.intro .start-page .line--top,
.intro .start-page .line--bottom { --from: scaleX(0); }
.intro .start-page .line--left,
.intro .start-page .line--right  { --from: scaleY(0); }

@keyframes draw {
  from { transform: var(--from); }
}

/* --d (delay) is set per letter by main.js */
.intro .char {
  animation: weight-sweep 1.4s cubic-bezier(0.45, 0, 0.2, 1) var(--d) backwards;
}

/* After the intro: weight shifts on hover (see main.js) */
.ready .char {
  transition: font-weight 0.5s cubic-bezier(0.25, 0.1, 0.25, 1);
}

@keyframes weight-sweep {
  0%   { font-weight: 100; opacity: 0; }
  20%  { opacity: 1; }
  55%  { font-weight: 900; }
  100% { font-weight: var(--w); }
}

.intro .arrow {
  animation: fade-in 0.8s ease 5.5s backwards;
}

@keyframes fade-in {
  from { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .arrow svg {
    transition: none;
  }
  .intro .start-page .line,
  .intro .char,
  .intro .arrow {
    animation: none;
  }
}

/* ---------- Custom cursor (see cursor.js) ----------
   A dot that follows the pointer and swells slightly over
   links and buttons. The white outline keeps it visible on
   black areas. */

.has-custom-cursor,
.has-custom-cursor *,
.has-custom-cursor ::backdrop {
  cursor: none !important;
}

.cursor {
  --size: 12px;
  position: fixed;
  inset: 0 auto auto 0;
  z-index: 2147483647;
  width: var(--size);
  height: var(--size);
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  overflow: visible;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.cursor.is-visible {
  opacity: 1;
}

.cursor__dot {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: var(--ink);
  stroke: var(--bg);
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
  transform: translate(-50%, -50%) scale(1);
  transition: transform 0.3s ease;
}

.cursor__dot circle {
  vector-effect: non-scaling-stroke;
}

.cursor.is-active .cursor__dot {
  transform: translate(-50%, -50%) scale(1.5);
}

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