/* Tensile: a minimal hover piece. Warm paper, one word on one hairline. Every letter is tied to the line by an
   invisible rubber band: the pointer catches a letter and pulls it off the line, and the line underneath bends
   and changes colour with the tension. The script moves only the inner glyph of each letter, so the word never
   reflows while the letters stretch, thin out and snap back. */
:root {
  --paper: #f3f0e8;     /* the background */
  --ink: #171614;       /* the word */
  --line: #b8b2a5;      /* the hairline at rest */
  --taut: #e0462a;      /* the colour of tension, on the line and on a stretched letter */
  --muted: #8a8478;     /* the small print */
  --weight: 640;        /* how heavy the word is (100 to 900) */
  --width: 112;         /* how wide the word is, in percent of the typeface width (60 to 140) */
}

* {
  box-sizing: border-box;
}

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

body {
  background: var(--paper);
  color: var(--ink);
  font-family: 'Anybody Variable', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

.stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

/* --t is the tension of the whole line, from 0 to 1, written by the script */
.line {
  --t: 0;
  fill: none;
  stroke: color-mix(in oklab, var(--line), var(--taut) calc(var(--t) * 100%));
  stroke-width: calc(1px + var(--t) * 0.6px);
  stroke-linecap: round;
  stroke-linejoin: round;
}

.word {
  position: absolute;
  left: 50%;
  top: 47%;
  margin: 0;
  transform: translate(-50%, -50%);
  display: flex;
  font-size: clamp(60px, min(19vw, 30vh), 270px);
  font-weight: var(--weight);
  font-stretch: calc(var(--width) * 1%);
  line-height: 1;
  letter-spacing: 0;
  white-space: pre;
  pointer-events: none;
}

/* the box of a letter keeps its width at rest; the glyph inside is free to stretch past it on both sides */
.word__l {
  display: flex;
  justify-content: center;
  flex: none;
}

/* the glyph the script moves: --t its own tension, --wd and --wg the change in width and weight */
.word__g {
  --t: 0;
  --wd: 0;
  --wg: 0;
  display: block;
  color: color-mix(in oklch, var(--ink), var(--taut) calc(var(--t) * 100%));
  font-weight: clamp(100, calc(var(--weight) + var(--wg)), 900);
  font-stretch: clamp(50%, calc((var(--width) + var(--wd)) * 1%), 150%);
  transform-origin: 50% 82%;
  will-change: transform;
  opacity: 0;
}

.hint,
.read {
  position: absolute;
  top: 0;
  margin: 0;
  font-size: 12px;
  line-height: 1.3;
  font-weight: 460;
  font-stretch: 100%;
  letter-spacing: 0.02em;
  color: var(--muted);
  white-space: nowrap;
  opacity: 0;
}

.read {
  display: flex;
  align-items: baseline;
  gap: 8px;
  text-align: right;
}

/* a little window the value rolls through when it changes */
.read__win {
  display: inline-block;
  overflow: hidden;
  min-width: 4.2em;
  height: 1.3em;
  text-align: left;
}

.read__value {
  display: inline-block;
  font-weight: 620;
  font-stretch: 92%;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.read__value.is-snap {
  color: var(--taut);
}

@media (max-width: 560px) {
  .hint,
  .read {
    font-size: 11px;
  }
}
