/* gold.sy */

@font-face {
  font-family: "Cormorant Garamond";
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/cormorant-garamond-latin-500-italic.woff2") format("woff2");
}

/* Every colour and curve lives here once. Restyling means changing a token. */
:root {
  color-scheme: dark;

  --bg: #0b0906;
  --bg-lift: #1a140b;
  --bg-deep: #050403;

  --gold-50: #fffbe8;
  --gold-100: #fff1bf;
  --gold-200: #f2d27e;
  --gold-400: #d4a640;
  --gold-600: #9f7420;
  --gold-800: #5f430c;
  --shadow: #140d02;

  --ease-out: cubic-bezier(.2, .7, .2, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
}

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

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

body {
  background: var(--bg-deep);
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}

/* The warm light behind the "?". It sits on its own layer so it can fade up
   when the page opens, like a lamp warming. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(120% 85% at 50% 45%, var(--bg-lift) 0%, var(--bg) 55%, var(--bg-deep) 100%);
  animation: fade-in 1.8s ease-out backwards;
}

/* Fine film grain over everything, so the black reads as a surface rather
   than an empty screen. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: .07;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Drifting gold dust, painted by main.js. */
.dust {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  animation: fade-in 2s ease-out .2s backwards;
}

/* The "?" and the answer share one grid cell, so they sit exactly on top of
   each other in the middle of the screen. svh = the screen height with the
   phone's address bar showing, so nothing hides behind it. */
.stage {
  position: relative;
  display: grid;
  place-items: center;
  height: 100svh;
  touch-action: manipulation;
}
.stage > * { grid-area: 1 / 1; }

/* ---------- the question mark ---------- */

.mark {
  position: relative;
  width: min(34svh, 56vw);
  aspect-ratio: 100 / 150;
}

.hook {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  transform-origin: 50% 66%;
}

/* A dash as long as the whole curve, then a gap. Sliding the dash along
   (dashoffset 0 → 1) pulls the curve back from the stem end like thread being
   reeled in; sliding it back redraws it. */
.hook path {
  fill: none;
  stroke-width: 12;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1 2;
  stroke-dashoffset: 0;
  transition:
    stroke-dashoffset .9s var(--ease-in-out) .5s,
    opacity .2s .5s;
}
.hook .shadow { stroke: var(--shadow); opacity: .85; }
.hook .body   { stroke: url(#gold); }
.hook .sheen  { stroke: url(#sheen); }

.stage[data-state="answer"] .mark { pointer-events: none; }
/* 1.05 rather than 1: at exactly 1 the dash shrinks to zero length but its
   rounded end still paints a faint dot where the curve starts. */
.stage[data-state="answer"] .hook path {
  stroke-dashoffset: 1.05;
  opacity: 0;
  transition:
    stroke-dashoffset .85s var(--ease-in-out),
    opacity .3s .6s;
}

/* ---------- the dot ---------- */

/* A gold bead. No pointer cursor and no button styling on purpose: nothing
   says "click me". Its home is under the stem: x 42–58, y ≈ 119–135 of the
   100 × 150 drawing. */
.dot {
  position: absolute;
  left: 42%;
  top: 79.33%;
  width: 16%;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 30%,
    var(--gold-50) 0 5%,
    var(--gold-200) 18%,
    var(--gold-400) 45%,
    var(--gold-600) 72%,
    var(--gold-800) 100%);
  box-shadow: 0 2px 6px rgb(0 0 0 / .55);
  cursor: default;
  -webkit-appearance: none;
  appearance: none;
}

/* An invisible ring around the bead so a fingertip finds it, even when it
   is a tiny full stop (44 px is Apple's minimum comfortable tap size). */
.dot::before {
  content: "";
  position: absolute;
  inset: -20px;
  border-radius: 50%;
}

.dot:focus { outline: none; }
.dot:focus-visible { outline: 2px solid var(--gold-100); outline-offset: 5px; }

@media (hover: hover) {
  .dot { transition: filter .3s; }
  .dot:hover { filter: brightness(1.15); }
}

/* ---------- the answer ---------- */

.answer {
  position: relative;
  z-index: 1;
  margin: 0;
  font: italic 500 clamp(2.6rem, 13vw, 7.5rem) / 1.2 "Cormorant Garamond", Georgia, serif;
  letter-spacing: .005em;
  white-space: nowrap;
  pointer-events: none;
}

/* Each letter is its own box so it can arrive on its own. The gold runs top
   to bottom, so it lines up across letters without one shared background.
   The padding (cancelled by the negative margin) keeps italic overhangs and
   the tail of the "g" from being clipped. */
.ch {
  display: inline-block;
  padding: .08em .1em .22em;
  margin: -.08em -.1em -.22em;
  background: linear-gradient(180deg,
    var(--gold-100) 10%,
    var(--gold-200) 34%,
    #c99a35 58%,
    #8d6519 74%,
    #e9c770 92%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  opacity: 0;
  transform: translateY(.22em);
  filter: blur(.08em);
  transition:
    opacity .3s,
    transform .4s var(--ease-out),
    filter .3s;
  transition-delay: calc((var(--n) - 1 - var(--i)) * 18ms);
}

.stage[data-state="answer"] .ch {
  opacity: 1;
  transform: none;
  filter: none;
  transition:
    opacity .6s,
    transform .9s var(--ease-out),
    filter .7s;
  transition-delay: calc(260ms + var(--i) * 60ms);
}

/* Where the dot lands: a full-stop-sized space sitting on the baseline. */
.slot {
  position: relative;
  display: inline-block;
  width: .15em;
  height: .15em;
  margin-inline-start: .04em;
}
.slot .dot {
  left: 0;
  top: 0;
  width: 100%;
  pointer-events: auto;
  box-shadow: 0 1px 2px rgb(0 0 0 / .5);
}
.slot .dot:focus-visible { outline-offset: 4px; }

/* ---------- the entrance ---------- */

/* Plays once as the page opens. The curve writes itself in gold, from the
   tail to the tip of the stem, then a drop of molten gold falls off the tip,
   squashes as it lands, bounces, and settles as the dot.

   "backwards" means each animation only holds its first frame while waiting
   to start, and lets go completely once done, so the clicks and transitions
   above behave exactly as before. main.js removes .intro afterwards; without
   that, moving the dot into the text would replay the drop. */
.intro .hook path {
  animation: write 1.3s cubic-bezier(.55, .1, .35, 1) .25s backwards;
}

.intro .dot {
  transform-origin: 50% 100%;
  animation: drip .8s 1.45s backwards;
}

@keyframes write {
  from { stroke-dashoffset: 1.05; }
}

/* The drop starts small and tall at the tip of the stem (165% of its own
   height above its resting place), speeds up as it falls, flattens on
   impact, then bounces twice, smaller each time. The 45% mark is the impact:
   main.js sends up a few sparks then. */
@keyframes drip {
  0% {
    opacity: 0;
    transform: translateY(-165%) scale(.3, .42);
    animation-timing-function: cubic-bezier(.5, 0, 1, 1);
  }
  12% { opacity: 1; }
  45% {
    transform: translateY(0) scale(1.14, .84);
    animation-timing-function: cubic-bezier(0, 0, .3, 1);
  }
  63% {
    transform: translateY(-16%) scale(.96, 1.05);
    animation-timing-function: cubic-bezier(.7, 0, 1, 1);
  }
  80% {
    transform: translateY(0) scale(1.04, .96);
    animation-timing-function: ease-out;
  }
  100% { transform: none; }
}

/* Only a "from" frame: each thing fades up to whatever opacity it normally
   has (the shadow under the curve, for one, is not fully opaque). */
@keyframes fade-in {
  from { opacity: 0; }
}

/* ---------- people who asked for less motion ---------- */

@media (prefers-reduced-motion: reduce) {
  .hook .sheen { display: none; }
  .hook path,
  .stage[data-state="answer"] .hook path {
    stroke-dasharray: none;
    transition: opacity .4s;
  }
  .ch,
  .stage[data-state="answer"] .ch {
    transform: none;
    filter: none;
    transition: opacity .4s;
  }
  /* No writing, no falling: the "?" simply fades in. */
  .intro .hook path,
  .intro .dot {
    animation: fade-in .7s ease-out .2s backwards;
  }
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
