/* ===================================================================
   statement.css — the playful words in the About page's opening line.
   Each marked word (.pw) acts out what it says when you hover or tap it:
   "complex" falls apart, "motion" waves, "3D" is a cube you can spin,
   "legible" magnifies, "trustworthy" locks. The switch after
   "interaction" turns them all on at once. Wired by statement.js; the
   sentence reads normally without either file.
   Sizes are in em so everything scales with the statement's type.
   =================================================================== */
.pw {
  position: relative;
  display: inline-block;
  white-space: nowrap;
  cursor: default;
  -webkit-tap-highlight-color: transparent;
}
/* The line is for playing with, not for selecting: a double click or a drag
   across it would paint a selection over words that are mid-performance. */
.about-statement {
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
/* a faint dotted line says "this one does something" */
.pw-hint {
  text-decoration: underline dotted;
  text-decoration-thickness: 0.045em;
  text-underline-offset: 0.17em;
  text-decoration-color: color-mix(in srgb, currentColor 32%, transparent);
  transition: text-decoration-color 0.3s ease;
}
:is(.pw-hint:hover, .pw-hint.is-on, .is-live .pw-hint) { text-decoration-color: transparent; }
/* the real word, for screen readers, where its letters are drawn separately */
.pw-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- complex: the letters come apart, then pull back together ---- */
.pw-complex i,
.pw-wave i {
  display: inline-block;
  font-style: normal;
  transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}
:is(.pw-complex:hover, .pw-complex.is-on, .is-live .pw-complex) i {
  transform: translate(var(--x), var(--y)) rotate(var(--r));
}

/* ---- technical: a code tag ---- */
.pw-tag,
.pw-rot {
  padding: 0.3em 0.7em;
  border: 0.07em solid currentColor;
  border-radius: 999px;
  font-size: 0.6em;
  line-height: 1;
  letter-spacing: 0;
  vertical-align: 0.24em;
}
.pw-tag {
  font-family: var(--font-mono, ui-monospace, Menlo, Consolas, monospace);
  font-weight: 500;
  transition: background-color 0.3s ease, color 0.3s ease;
}
.pw-tag::before,
.pw-tag::after {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  vertical-align: bottom;
  opacity: 0;
  transition: max-width 0.4s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.3s ease;
}
.pw-tag::before { content: '<'; }
.pw-tag::after { content: '/>'; }
:is(.pw-tag:hover, .pw-tag.is-on, .is-live .pw-tag) { background: var(--ink); color: var(--bg); }
:is(.pw-tag:hover, .pw-tag.is-on, .is-live .pw-tag)::before,
:is(.pw-tag:hover, .pw-tag.is-on, .is-live .pw-tag)::after { max-width: 1.4em; opacity: 1; }

/* ---- interaction: a real switch; on, every word performs at once ---- */
.pw-toggle {
  position: relative;
  display: inline-block;
  width: 1.08em;
  height: 0.6em;
  margin-left: 0.2em;
  padding: 0;
  border: 0.06em solid currentColor;
  border-radius: 999px;
  background: none;
  color: inherit;
  font: inherit;
  vertical-align: -0.02em;
  cursor: pointer;
  transition: background-color 0.3s ease;
}
.pw-toggle::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 0.07em;
  width: 0.36em;
  height: 0.36em;
  border-radius: 50%;
  background: currentColor;
  translate: 0 -50%;
  transition: left 0.4s cubic-bezier(0.34, 1.56, 0.64, 1), background-color 0.3s ease;
}
.pw-toggle[aria-checked="true"] { background: var(--ink); }
.pw-toggle[aria-checked="true"]::after { left: calc(100% - 0.43em); background: var(--bg); }
.pw-toggle:focus-visible { outline: 0.06em solid currentColor; outline-offset: 0.12em; }

/* ---- motion: a wave runs through the letters ---- */
:is(.pw-wave:hover, .pw-wave.is-on, .is-live .pw-wave) i {
  animation: pw-wave 0.9s ease-in-out infinite;
  animation-delay: calc(var(--i) * 80ms);
}
@keyframes pw-wave {
  0%, 100% { transform: translateY(0); }
  35% { transform: translateY(-0.2em); }
  70% { transform: translateY(0.06em); }
}

/* ---- 3D: a solid black cube that turns; drag it to spin it yourself ---- */
.pw-cube-wrap {
  display: inline-block;
  width: 0.62em;
  height: 0.62em;
  margin: 0 0.06em 0 0.24em;
  perspective: 2.6em;
  vertical-align: -0.01em;
}
.pw-cube {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transform: rotateX(-24deg) rotateY(32deg);
  animation: pw-spin 10s linear infinite;
  cursor: grab;
  touch-action: none;
}
.pw-cube.is-held { animation: none; cursor: grabbing; }
:is(.pw-3d:hover, .is-live .pw-3d) .pw-cube:not(.is-held) { animation-duration: 3s; }
/* Each face is a different black, as if lit from above and a little to the
   left: the top catches the most light, the sides fall off, the underside
   is darkest. A soft gradient across each face and a hairline of light on
   its edges keep the shape readable when two faces are nearly the same tone. */
.pw-cube i {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(145deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0) 55%, rgba(0, 0, 0, 0.28)),
    var(--face, #121214);
  box-shadow: inset 0 0 0 0.012em rgba(255, 255, 255, 0.16);
  backface-visibility: hidden;
}
.pw-cube i:nth-child(1) { --face: #1b1b1e; transform: translateZ(0.31em); }                   /* front */
.pw-cube i:nth-child(2) { --face: #0e0e10; transform: rotateY(180deg) translateZ(0.31em); }   /* back */
.pw-cube i:nth-child(3) { --face: #0a0a0b; transform: rotateY(90deg) translateZ(0.31em); }    /* right */
.pw-cube i:nth-child(4) { --face: #26262a; transform: rotateY(-90deg) translateZ(0.31em); }   /* left */
.pw-cube i:nth-child(5) { --face: #3b3b40; transform: rotateX(90deg) translateZ(0.31em); }    /* top */
.pw-cube i:nth-child(6) { --face: #000000; transform: rotateX(-90deg) translateZ(0.31em); }   /* underside */
@keyframes pw-spin {
  from { transform: rotateX(-24deg) rotateY(0deg); }
  to { transform: rotateX(-24deg) rotateY(360deg); }
}

/* on About's dark theme the black cube would vanish into the page: lift its
   faces a step and brighten the hairline on its edges */
html[data-theme="dark"] .pw-cube i {
  background:
    linear-gradient(145deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.04) 55%, rgba(0, 0, 0, 0.2)),
    color-mix(in srgb, var(--face, #121214) 78%, #6a6a72);
  box-shadow: inset 0 0 0 0.014em rgba(255, 255, 255, 0.34);
}

/* ---- worlds: an orbit opens around the "o" ----
   The "o" itself keeps its size, so the word never gets wider and the
   sentence does not re-wrap. The orbit and its moon are drawn over the
   neighbouring letters instead. The "o" is tilted (which does not show on a
   circle) so that everything drawn inside it is tilted with it. */
.pw-o {
  position: relative;
  display: inline-block;
  width: 0.5em;
  height: 0.5em;
  margin: 0 0.035em;
  border: 0.085em solid currentColor;
  border-radius: 999px;
  rotate: -14deg;
}
.pw-o::before,
.pw-o::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease, scale 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
/* the orbit */
.pw-o::before {
  width: 1.7em;
  height: 0.6em;
  border: 0.045em solid currentColor;
  translate: -50% -50%;
  scale: 0.3;
}
/* the moon: side to side and up and down a quarter turn apart, which is a
   trip round the orbit */
.pw-o::after {
  width: 0.15em;
  height: 0.15em;
  margin: -0.075em 0 0 -0.075em;
  background: currentColor;
}
:is(.pw-world:hover, .pw-world.is-on, .is-live .pw-world) .pw-o::before { opacity: 1; scale: 1; }
:is(.pw-world:hover, .pw-world.is-on, .is-live .pw-world) .pw-o::after {
  opacity: 1;
  animation:
    pw-orbit-x 1.5s ease-in-out infinite alternate,
    pw-orbit-y 1.5s ease-in-out -0.75s infinite alternate;
}
@keyframes pw-orbit-x { from { left: calc(50% - 0.85em); } to { left: calc(50% + 0.85em); } }
@keyframes pw-orbit-y { from { top: calc(50% - 0.3em); } to { top: calc(50% + 0.3em); } }

/* ---- touch: it gives when pressed, and ripples ---- */
.pw-touch { transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1); }
.pw-touch:active { transform: scale(0.88); }
.pw-touch::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 55%;
  width: 0.5em;
  height: 0.5em;
  border: 0.05em solid currentColor;
  border-radius: 50%;
  translate: -50% -50%;
  opacity: 0;
  pointer-events: none;
}
:is(.pw-touch:hover, .pw-touch.is-on, .is-live .pw-touch)::after { animation: pw-ripple 1.3s ease-out infinite; }
@keyframes pw-ripple {
  0% { scale: 0.4; opacity: 0.9; }
  100% { scale: 4.2; opacity: 0; }
}

/* ---- rotate: a tag you can grab and turn; it springs back ---- */
.pw-rot {
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  transition: transform 0.7s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.pw-rot.is-held { cursor: grabbing; transition: none; }
:is(.pw-rot:hover, .is-live .pw-rot):not(.is-held) { transform: rotate(-9deg); }
.pw-rot.is-on:not(.is-held) { transform: rotate(351deg); }

/* ---- intricate: out of focus until you look at it ---- */
.pw-blur { filter: blur(0.07em); transition: filter 0.55s ease; }
:is(.pw-blur:hover, .pw-blur.is-on, .is-live .pw-blur) { filter: blur(0); }

/* ---- legible: under a magnifying glass ----
   A round lens follows the pointer over the word (statement.js: "the
   lens"). It holds an enlarged second copy of the word, and the script bends
   that copy the way a dome of glass would (an SVG displacement filter driven
   by a normal map; letter by letter where that filter is not dependable).
   The word underneath stays as it is. This is only how the glass looks. */
.pw-zoom { z-index: 2; cursor: none; }                 /* the lens stands in for the pointer */
.pw-zoom i { display: inline-block; font-style: normal; }
.pw-lens {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1;
  width: 2.5em;
  height: 2.5em;
  overflow: hidden;
  border-radius: 50%;
  border: 0.028em solid color-mix(in srgb, currentColor 80%, transparent);
  box-shadow:
    0 0.18em 0.55em color-mix(in srgb, currentColor 18%, transparent),
    0 0.03em 0.1em color-mix(in srgb, currentColor 22%, transparent);
  opacity: 0;
  pointer-events: none;
  will-change: transform, opacity;
}
/* what the glass shows: the page colour with the enlarged word on it. With
   the glass filter it is twice the lens across, so the rim has picture to
   pull in from beyond its own edge; the lens clips it back to a circle. */
.pw-lens-view {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--bg);
}
.pw-lens.is-glass .pw-lens-view { inset: -50%; }
/* the dome of glass (statement.js builds the filter) */
.pw-lens.is-glass .pw-lens-view { filter: url(#pw-lens-glass); }
.pw-lens-word { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
/* an enlarged letter: sized and placed by the script */
.pw-lens-word span {
  position: absolute;
  left: 0;
  top: 0;
  text-align: center;
  white-space: pre;
}
/* over the picture: a faint tint so the glass shows on a white page, a
   darker rim, and a thin bright inner edge, which make it read as curved */
.pw-lens::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--c-blue) 5%, transparent) 0, color-mix(in srgb, var(--c-blue) 7%, transparent) 56%, color-mix(in srgb, currentColor 20%, transparent) 100%);
  box-shadow:
    inset 0 -0.16em 0.36em color-mix(in srgb, currentColor 14%, transparent),
    inset 0 0 0 0.05em color-mix(in srgb, var(--bg) 60%, transparent);
  pointer-events: none;
}
/* the glare: a bright streak following the curve of the rim top left with a
   small hot spot in it, and a faint bounce of it bottom right. The script
   nudges it (--glare-x, --glare-y, each -1 to 1) against the lens's movement. */
.pw-lens::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: 50%;
  background:
    radial-gradient(ellipse 9% 6% at 27% 21%, #fff 0, color-mix(in srgb, #fff 70%, transparent) 45%, transparent 100%),
    radial-gradient(ellipse 30% 15% at 31% 20%, color-mix(in srgb, #fff 80%, transparent) 0, transparent 100%),
    radial-gradient(circle at 60% 62%, transparent 0 58%, color-mix(in srgb, #fff 34%, transparent) 66%, transparent 71%),
    radial-gradient(ellipse 22% 9% at 70% 83%, color-mix(in srgb, #fff 26%, transparent) 0, transparent 100%);
  transform: translate(calc(var(--glare-x, 0) * 0.14em), calc(var(--glare-y, 0) * 0.14em)) rotate(-12deg);
  filter: blur(0.012em);
  pointer-events: none;
}

/* ---- trustworthy: a padlock slides in and clicks shut ---- */
.pw-lock svg {
  width: 0;
  height: 0.66em;
  margin-left: 0;
  overflow: visible;
  vertical-align: -0.03em;
  opacity: 0;
  transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1), margin-left 0.5s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.3s ease;
}
.pw-lock rect { fill: currentColor; }
.pw-lock path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  transform: translateY(-3.5px);
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1) 0.45s;
}
:is(.pw-lock:hover, .pw-lock.is-on, .is-live .pw-lock) svg { width: 0.55em; margin-left: 0.16em; opacity: 1; }
:is(.pw-lock:hover, .pw-lock.is-on, .is-live .pw-lock) path { transform: translateY(0); }

/* ---- colour ----
   The palette of a design tool's canvas: selection blue, component purple,
   and the red, orange, green and yellow of its labels. Tags wear their
   colour all the time (a tint at rest, solid when they perform); everything
   else takes its colour as it performs. The colours themselves (--c-*) are
   in the site palette, tokens.css. */

/* technical: a purple component tag */
.pw-tag {
  border-color: var(--c-purple);
  background: color-mix(in srgb, var(--c-purple) 12%, transparent);
  color: var(--c-purple);
}
:is(.pw-tag:hover, .pw-tag.is-on, .is-live .pw-tag) { background: var(--c-purple); color: #ffffff; }

/* rotate: a blue selection label */
.pw-rot {
  border-color: var(--c-blue);
  background: color-mix(in srgb, var(--c-blue) 12%, transparent);
  color: var(--c-blue);
  transition: transform 0.7s cubic-bezier(0.34, 1.56, 0.64, 1), background-color 0.3s ease, color 0.3s ease;
}
:is(.pw-rot:hover, .pw-rot.is-on, .pw-rot.is-held, .is-live .pw-rot) { background: var(--c-blue); color: #ffffff; }

/* the switch: green when on */
.pw-toggle[aria-checked="true"] { border-color: var(--c-green); background: var(--c-green); }
.pw-toggle[aria-checked="true"]::after { background: #ffffff; }

/* complex: each letter flies off in a colour of its own */
.pw-complex i { transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), color 0.4s ease; }
:is(.pw-complex:hover, .pw-complex.is-on, .is-live .pw-complex) i:nth-of-type(6n + 1) { color: var(--c-red); }
:is(.pw-complex:hover, .pw-complex.is-on, .is-live .pw-complex) i:nth-of-type(6n + 2) { color: var(--c-purple); }
:is(.pw-complex:hover, .pw-complex.is-on, .is-live .pw-complex) i:nth-of-type(6n + 3) { color: var(--c-blue); }
:is(.pw-complex:hover, .pw-complex.is-on, .is-live .pw-complex) i:nth-of-type(6n + 4) { color: var(--c-green); }
:is(.pw-complex:hover, .pw-complex.is-on, .is-live .pw-complex) i:nth-of-type(6n + 5) { color: var(--c-orange); }
:is(.pw-complex:hover, .pw-complex.is-on, .is-live .pw-complex) i:nth-of-type(6n) { color: var(--c-pink); }

/* motion: the wave carries a colour through the letters */
.pw-wave i { transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1), color 0.4s ease; }
:is(.pw-wave:hover, .pw-wave.is-on, .is-live .pw-wave) i { color: var(--c-orange); }

/* worlds: a blue orbit with an orange moon */
.pw-o::before { border-color: var(--c-blue); }
.pw-o::after { background: var(--c-orange); }

/* touch: a red ripple */
.pw-touch::after { border-color: var(--c-red); }

/* legible: the lens is rimmed in selection blue */
.pw-lens { border-color: var(--c-blue); }

/* trustworthy: the padlock is green */
.pw-lock svg { color: var(--c-green); }

/* the dotted hints pick up the colour of what they do */
.pw-complex.pw-hint { text-decoration-color: color-mix(in srgb, var(--c-red) 70%, transparent); }
.pw-wave.pw-hint { text-decoration-color: color-mix(in srgb, var(--c-orange) 75%, transparent); }
.pw-world.pw-hint { text-decoration-color: color-mix(in srgb, var(--c-blue) 70%, transparent); }
.pw-touch.pw-hint { text-decoration-color: color-mix(in srgb, var(--c-red) 70%, transparent); }
.pw-zoom.pw-hint { text-decoration-color: color-mix(in srgb, var(--c-blue) 70%, transparent); }
.pw-lock.pw-hint { text-decoration-color: color-mix(in srgb, var(--c-green) 75%, transparent); }
:is(.pw-hint:hover, .pw-hint.is-on, .is-live .pw-hint) { text-decoration-color: transparent; }

@media (prefers-reduced-motion: reduce) {
  .pw-cube,
  .pw-wave i,
  .pw-touch::after,
  .pw-o::after { animation: none !important; }
  .pw, .pw i, .pw-o, .pw-rot, .pw-zoom, .pw-lock svg, .pw-lock path { transition-duration: 0.01s !important; }
}
