/* Standalone holding page. Deliberately not sharing the portfolio's token
   files: this deploys as its own Worker and is meant to be deleted whole once
   the real site takes the domain, so it carries its own copy of only the few
   tokens it uses rather than a dependency on src/styles.

   A sheet of paper taped to the mat, the same object the testimonial notes
   are: --note, --note-ink and 2px corners, paper rather than a card. Those
   tokens are deliberately theme-independent in the portfolio, so the paper
   stays cream in both themes; only the mat under it changes. */

@font-face {
  font-family: "Instrument Serif";
  src: url("/fonts/instrument-serif-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Inter Variable";
  src: url("/fonts/inter-latin-wght-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}

/* Registered so they interpolate: the swing, the shadow and the sheen all
   read these, and easing them here eases everything at once, including the
   settle back when the pointer leaves. */
@property --px { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --py { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --mx { syntax: "<percentage>"; inherits: true; initial-value: 50%; }
@property --my { syntax: "<percentage>"; inherits: true; initial-value: 30%; }

:root {
  --mat: #256a54;
  --note: #f7f3ea;
  --note-ink: #1d2420;
  --note-meta: #5d5749;
  --accent: #ffbf00;
  --accent-on-paper: #8a6a00;
  --accent-text: #2a1c00;
  --key-face-hi: #fcc93a;
  --key-face: #f5b50f;
  --key-skirt: #b07800;
  --tape: rgba(198, 158, 96, 0.82);
  --tape-edge: rgba(255, 255, 255, 0.22);

  --grid-fine: rgba(255, 255, 255, 0.035);
  --grid-major: rgba(255, 255, 255, 0.06);
  --grid-accent: rgba(255, 190, 160, 0.05);

  --unit: 12px;
  --unit-major: 72px;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --font-display: "Instrument Serif", Georgia, "Times New Roman", serif;
  --font-body: "Inter Variable", system-ui, -apple-system, "Segoe UI", sans-serif;
}

:root:not([data-theme="light"]) { color-scheme: light dark; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --mat: #0e2b23;
    --grid-fine: rgba(255, 255, 255, 0.03);
    --grid-major: rgba(255, 255, 255, 0.05);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100svh;
  background: var(--mat);
  color: var(--note-ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  display: grid;
  place-items: center;
  padding: var(--unit-major) 1.25rem;
}

/* The mat: fine rule and major rule ruled into the surface, fixed so it reads
   as something the paper is taped to rather than a texture scrolling with it. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-color: var(--mat);
  background-image:
    linear-gradient(to right, var(--grid-accent) 0 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-accent) 0 1px, transparent 1px),
    linear-gradient(to right, var(--grid-major) 0 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-major) 0 1px, transparent 1px),
    linear-gradient(to right, var(--grid-fine) 0 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-fine) 0 1px, transparent 1px);
  background-size:
    calc(var(--unit-major) * 2) 100%,
    100% calc(var(--unit-major) * 2),
    var(--unit-major) 100%,
    100% var(--unit-major),
    var(--unit) 100%,
    100% var(--unit);
}

/* ---- The board ----
   Holds the perspective so the sheet's rotations have depth. The tape lives
   here rather than inside the sheet, so it stays put while the paper moves. */
.board {
  position: relative;
  width: 100%;
  max-width: 36rem;
  perspective: 1400px;
}

/* ---- The sheet ----
   Taped at the top centre, so that is where it pivots. transform-origin sits
   on the tape, which is what makes the motion read as paper rather than as a
   floating panel: the top edge barely travels and the free bottom corner
   swings furthest, the way a taped sheet actually behaves. */
.paper {
  position: relative;
  /* No background here. The sheet is drawn on ::before so the torn edge can
     be a filter on that layer alone: filtering .paper would displace the
     text with it. */
  color: var(--note-ink);
  padding: clamp(3rem, 9vw, 4rem) clamp(1.75rem, 6vw, 3rem) clamp(2.5rem, 8vw, 3.5rem);
  display: grid;
  gap: 0.9rem;
  justify-items: center;
  text-align: center;
  container-type: inline-size;

  transform-origin: 50% 0;
  /* A degree off square at rest: taped by hand, not printed in place. */
  transform:
    rotate(-0.5deg)
    rotateX(calc(var(--py) * -9deg))
    rotateY(calc(var(--px) * 12deg))
    rotateZ(calc(var(--px) * 1.4deg));
  /* drop-shadow rather than box-shadow: it reads the rendered alpha, so it
     follows the torn edge instead of outlining a clean rectangle behind it.
     Contact shadow at the tape, then a cast shadow that lengthens and slides
     opposite the lean as the free edge lifts off the mat. */
  filter:
    drop-shadow(0 1px 2px rgba(8, 32, 26, 0.22))
    drop-shadow(calc(var(--px) * -12px) calc(14px + var(--py) * 12px) 20px rgba(8, 32, 26, 0.4));
  transition:
    --px 0.7s var(--ease-out), --py 0.7s var(--ease-out),
    --mx 0.7s var(--ease-out), --my 0.7s var(--ease-out);
}
/* Following the pointer: short enough to feel attached, long enough to smooth
   the jitter. */
.paper.is-tilting { transition-duration: 0.18s; }

/* The sheet itself: the cream stock, with the sheen blended into the same
   layer so one filter covers both. Paper is matte, so the sheen is far softer
   than the stamp's foil, just enough that the surface catches light as it
   turns. The torn edge is the displacement filter; because the inside of the
   layer is flat colour, the displacement only shows where there is an edge. */
.paper::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-color: var(--note);
  background-image:
    radial-gradient(circle 460px at var(--mx) var(--my), rgba(255, 255, 255, 0.5), transparent 60%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.35), transparent 30% 70%, rgba(90, 70, 30, 0.07));
  background-blend-mode: soft-light, soft-light;
  filter: url("#torn");
}
.paper > * { position: relative; z-index: 1; }

/* Parked out of flow: it only carries the filter definition. */
.defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---- The tape ----
   Kraft, slightly translucent so the paper reads through it, torn at both
   ends and stuck on a little crooked. Sits above the sheet and does not
   inherit its transform, because it is holding the sheet to the mat. */
.tape {
  position: absolute;
  z-index: 2;
  top: -0.75rem;
  left: 50%;
  width: clamp(5rem, 18%, 7rem);
  height: 1.7rem;
  translate: -50% 0;
  rotate: -1.6deg;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.28), transparent 38% 70%, rgba(90, 60, 20, 0.16)),
    var(--tape);
  box-shadow: 0 2px 5px -2px rgba(8, 32, 26, 0.45);
  /* Ragged short edges: torn by hand rather than cut. */
  clip-path: polygon(
    3% 0%, 97% 0%,
    100% 15%, 97% 32%, 100% 50%, 97% 68%, 100% 85%, 96% 100%,
    4% 100%, 0% 84%, 3% 67%, 0% 49%, 3% 31%, 0% 14%
  );
}

/* The memoji sits in an amber disc, the way it sits on its amber card in the
   hero. Without it the cut-out illustration floats on the cream with nothing
   holding it, and the shoulders trail off into the paper. */
.mark {
  width: clamp(6rem, 22cqi, 7.5rem);
  height: auto;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--accent);
  object-fit: cover;
  margin-bottom: 0.4rem;
}

.wordmark {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 7cqi, 2.4rem);
  line-height: 1.1;
  letter-spacing: 0.01em;
  margin: 0;
  color: var(--note-ink);
}

.role {
  margin: 0;
  font-size: 0.8rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--note-meta);
}

.rule {
  width: min(100%, 16rem);
  height: 1px;
  background: color-mix(in srgb, var(--note-ink) 16%, transparent);
  margin: 0.6rem 0 0.3rem;
}


h1 {
  font-family: var(--font-display);
  font-weight: 400;
  /* Capped to the sheet's own width so the longer line never runs into the
     margin. The divisor is set by "Still on the Cutting Mat", which is the
     line that has to fit. */
  font-size: min(3.4rem, 100cqi / 9);
  line-height: 1.06;
  margin: 0;
  color: var(--note-ink);
  text-wrap: balance;
}
/* Two fixed lines where the sheet has room, so the break lands after "Is"
   rather than wherever the measure happens to run out. Below that it wraps
   as ordinary text. */
h1 .line { display: block; }
@container (max-width: 400px) {
  h1 .line { display: inline; }
}

.copy {
  margin: 0;
  color: var(--note-meta);
  max-width: 46ch;
  text-wrap: balance;
}
/* One sentence to a line where the sheet has room. The spans share a source
   line so the space between them survives when the break lets go. */
.copy .line { display: block; }
@container (max-width: 400px) {
  .copy .line { display: inline; }
}

/* The keycap, flattened to CSS. The portfolio draws this as an SVG so the rim
   can follow a squircle, which is more machinery than one link needs here. */
.btn {
  margin-top: 0.9rem;
  display: inline-block;
  padding: 0.95rem 1.6rem;
  border-radius: 14px;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--accent-text);
  background: linear-gradient(180deg, var(--key-face-hi), var(--key-face));
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.6) inset,
    0 4px 0 var(--key-skirt),
    0 10px 18px -8px rgba(0, 0, 0, 0.35);
  transition: translate 120ms ease-out, box-shadow 120ms ease-out;
}
.btn:hover {
  translate: 0 1px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.6) inset,
    0 3px 0 var(--key-skirt),
    0 8px 14px -8px rgba(0, 0, 0, 0.35);
}
.btn:active { translate: 0 3px; box-shadow: 0 1px 0 var(--key-skirt); }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .paper { transform: rotate(-0.5deg); }
}
