/* Gate VFX prototype. Layers, bottom to top: the keycap (button), the paint canvas (wider than the key, so paint can
   fly off it), the key's letters (lifted from the key image, so paint goes under them as in the brand mark), the final
   brand mark (cross-faded in once the paint has settled onto it). */

.gate {
  --rx: 0deg;
  --ry: 0deg;
  --gx: 50%;
  --gy: 30%;
  position: relative;
  width: min(520px, 64vmin);
  aspect-ratio: 1 / 1;
}

.key {
  position: absolute;
  inset: 0;
  z-index: 1;
  border: 0;
  padding: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transform: perspective(1100px) rotateX(var(--rx)) rotateY(var(--ry)) translateY(0) scale(1);
  transition: transform 320ms cubic-bezier(.2, .9, .25, 1.25), filter 200ms ease;
}
.key:hover { filter: brightness(1.06); }
.key:focus-visible { outline: 2px solid var(--accent-soft); outline-offset: -18%; border-radius: 14%; }
.key.down {
  transform: perspective(1100px) rotateX(0deg) rotateY(0deg) translateY(1.6%) scale(.955);
  filter: brightness(.8);
  transition-duration: 70ms;
}
.key.nudge { animation: nudge 520ms cubic-bezier(.3, .7, .3, 1) 1; }
@keyframes nudge {
  0%, 100% { transform: perspective(1100px) rotateX(var(--rx)) rotateY(var(--ry)) translateY(0) scale(1); }
  30% { transform: perspective(1100px) rotateX(var(--rx)) rotateY(var(--ry)) translateY(1%) scale(.975); }
}
.key-img { display: block; width: 100%; height: 100%; pointer-events: none; }

/* The light on the key: a highlight that follows the pointer, and a slow sheen every few seconds. Both are masked to
   the key's own shape, so they never touch the page. */
.gloss, .sheen {
  position: absolute;
  inset: 0;
  pointer-events: none;
  -webkit-mask: url("/images/logo-nopaint.png") center / contain no-repeat;
  mask: url("/images/logo-nopaint.png") center / contain no-repeat;
}
.gloss {
  background: radial-gradient(circle at var(--gx) var(--gy), rgba(255, 255, 255, .6), rgba(255, 255, 255, 0) 32%);
  mix-blend-mode: overlay;
}
.sheen {
  background: linear-gradient(115deg, rgba(255, 255, 255, 0) 38%, rgba(255, 255, 255, .55) 50%, rgba(255, 255, 255, 0) 62%) no-repeat;
  background-size: 300% 100%;
  background-position: 120% 0;
  mix-blend-mode: overlay;
  animation: sheen 6s ease-in-out 2.2s infinite;
}
@keyframes sheen {
  0%, 70% { background-position: 120% 0; }
  100% { background-position: -20% 0; }
}

.paint {
  position: absolute;
  inset: -15%;
  width: 130%;
  height: 130%;
  z-index: 2;
  pointer-events: none;
}
.letters, .final {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
}
.letters { z-index: 3; transition: opacity 500ms ease; }
.final { z-index: 4; transition: opacity 280ms ease-out; }

/* The impact: the whole gate kicks once as the key bottoms out. The landing: when the paint has been sucked back
   onto the mark, the key takes it with a small bounce. */
.gate.impact { animation: impact 200ms cubic-bezier(.2, .8, .3, 1) 1; }
@keyframes impact {
  0% { transform: translate(0, 0); }
  20% { transform: translate(-0.9%, 1.1%); }
  45% { transform: translate(0.7%, -0.6%); }
  70% { transform: translate(-0.3%, 0.3%); }
  100% { transform: translate(0, 0); }
}
.gate.land { animation: land 260ms cubic-bezier(.3, 1.6, .5, 1) 1; }
@keyframes land {
  0% { transform: scale(.985); }
  100% { transform: scale(1); }
}

.gate.playing .key { cursor: crosshair; }
.gate.playing .letters { opacity: 1; }
.gate.playing .sheen, .gate.done .sheen, .gate.playing .gloss, .gate.done .gloss { display: none; }
.gate.done .final { opacity: 1; }
.gate.done .paint, .gate.done .letters { opacity: 0; transition: opacity 280ms ease-out; }

.hint {
  position: relative;
  z-index: 5;
  min-height: 2.2em;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--fg-muted);
  font-size: .95rem;
  letter-spacing: .04em;
}
.hint [hidden] { display: none; }
.hint kbd {
  display: inline-block;
  min-width: 1.9em;
  margin-right: .55em;
  padding: .15em .45em;
  border: 1px solid #555;
  border-bottom-width: 3px;
  border-radius: 4px;
  color: var(--fg);
  font-weight: 600;
  font-size: .85rem;
  line-height: 1.3;
  text-align: center;
}
.replay {
  background: none;
  border: 0;
  border-bottom: 1px solid var(--border-subtle);
  color: var(--fg-muted);
  font: inherit;
  letter-spacing: inherit;
  padding: 4px 0;
  cursor: pointer;
}
.replay:hover { color: var(--fg); border-bottom-color: var(--accent-soft); }
.replay:focus-visible { outline: 2px solid var(--accent-soft); outline-offset: 4px; }

.renderer {
  position: fixed;
  left: 14px;
  bottom: 10px;
  margin: 0;
  color: #6b6b6b;
  font: 12px/1.4 ui-monospace, Consolas, monospace;
  letter-spacing: .04em;
}

/* Reduced motion: no tilt, no sheen, no nudge, no flying paint. The press shows the finished mark at once (gate.js
   skips the simulation); only opacity changes remain. */
@media (prefers-reduced-motion: reduce) {
  .key, .key.down { transform: none !important; transition: filter 1ms !important; }
  .key.nudge, .gate.impact, .gate.land { animation: none !important; }
  .sheen { animation: none !important; display: none; }
  .gloss { display: none; }
  .letters, .final, .gate.done .paint, .gate.done .letters { transition-duration: 1ms !important; }
}

/* The words stay readable over flying paint. */
.stage .tagline, .stage .cta-row { position: relative; z-index: 5; }

/* The 3D keycap (key3d.js). When it is running it replaces the flat key image (kept in the button for its name and
   as the fallback), the CSS swivel, gloss and sheen, and the logo image at the end: the finished mark is the live key
   with the dry paint on it. */
.key3d { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.gate.has3d .key-img { opacity: 0; }
.gate.has3d .gloss, .gate.has3d .sheen { display: none; }
.gate.has3d .key, .gate.has3d .key.down, .gate.has3d .key.nudge { transform: none; filter: none; animation: none; }
.gate.has3d .final { display: none; }
.gate.has3d.done .paint { opacity: 1; }

/* The homepage layout: the gate as large as the screen allows, the links tight under the key. The gate's square frame
   is mostly air (the key spans 24.5..75.5% of it, the splatter about 13..87%), so its margins pull in by that air: the
   links sit just under the key's bottom edge, over the splatter's last drops (they stack above the paint). */
.home-body .stage { gap: 14px; padding-block: 12px; }
.home-body .gate {
  /* Desktop: as tall as the screen allows. Phone: wider than the screen (the frame's sides are air). */
  --s: min(880px, max(100vmin, min(118vw, 70vh)));
  width: var(--s);
  margin: calc(var(--s) * -0.12) 0 calc(var(--s) * -0.2);
}
.home-body .tagline { font-size: clamp(.9rem, 1.6vw, 1.05rem); }
