/**
 * The SAGE mark, alive.
 *
 * The same five-capsule waveform the app draws in its title bar, animated the
 * same way — a travelling wave through the bars and on into the letters, over a
 * slow hue rotation. Ported from SageLogo.tsx and main.css in the app so the
 * website and the product read as one thing rather than two drawings that
 * happen to look alike. Keep the numbers here in step with those: bar geometry,
 * the 110ms stagger, and the 40° hue step.
 *
 * Every bar and letter carries a single custom property, `--i`, which is its
 * position in the wave. Hue and delay are both derived from it, so a mark
 * cannot end up with its colour running one way and its motion the other.
 *
 * Shared by every page rather than pasted into each. There are four of them
 * now, and four copies of an animation is four chances for one to drift.
 */

.sage-mark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}

/* How hard and how fast the wave swings. Overridden on hover so the mark
   answers the cursor — the app does the same thing while a session is live. */
.sage-mark {
  --sage-dur: 2.6s;
  --sage-low: 0.72;
  /* Sky through to blue, and nothing else.
     The app runs the full spectrum here, which suits a small live indicator
     over dark glass. On a white marketing page a five-colour wordmark does not
     read as a rainbow; it reads as a font that failed to load. So the mark
     keeps its motion and gives up its rainbow. */
  --sage-hue: 199;
  --sage-hue-step: 5;
  --sage-sat: 88%;
  --sage-light: 52%;
}

a:hover > .sage-mark,
a.sage-mark:hover {
  --sage-dur: 1.15s;
  --sage-low: 0.42;
}

/* transform-box is what makes a CSS transform on an SVG rect scale about its
   own centre rather than the viewBox origin — without it the bars slide out of
   the mark instead of pulsing in place. */
.sage-bar {
  transform-box: fill-box;
  transform-origin: center;
  fill: hsl(calc(var(--sage-hue) + var(--i) * var(--sage-hue-step)) var(--sage-sat) var(--sage-light));
  animation: sage-bar var(--sage-dur) ease-in-out infinite;
  animation-delay: calc(var(--i) * 110ms);
}

/* Solid, and still. The bars are what say "listening"; a wordmark that also
   hops is two things competing for the same glance, and at 13px the hop reads
   as jitter rather than as a wave. */
.sage-word {
  font-weight: 800;
  letter-spacing: 0.2em;
  color: var(--text, #0b2545);
  margin-right: -0.2em;
}

.sage-word i {
  font-style: normal;
}

@keyframes sage-bar {
  0%,
  100% {
    transform: scaleY(var(--sage-low));
  }
  50% {
    transform: scaleY(1);
  }
}

/* A logo that will not sit still is a real problem for some people, and this
   one moves on every page. Motion off, colour kept. */
@media (prefers-reduced-motion: reduce) {
  .sage-bar {
    animation: none;
  }
}

/* ---------------------------------------------------------------- watermark

   The mark again, very large, very faint, and alive.

   A static logo stamped in the corner reads as a sticker. The same shape
   breathing reads as the product listening, which is what SAGE actually does -
   so the motion is not decoration, it is the mark saying what it is.

   Deliberately slow. Seven seconds a cycle against the header logo's 2.6, with
   a long stagger between bars, so it reads as a tide rather than a meter. The
   whole thing also drifts a few pixels over half a minute: nothing you can
   catch moving, but enough that the corner is never quite the same twice.

   Opacity peaks at 7% and troughs at 4%. Past about 8% it stops being a
   watermark and starts competing with the text; below 3% the motion is
   invisible and the whole thing is wasted effort.

   The pages that do not carry the markup fall back to the flat CSS stamp
   below, which is why body::after still exists. */
.sage-watermark {
  position: fixed;
  right: 4vmin;
  bottom: 4vmin;
  width: 42vmin;
  height: 42vmin;
  z-index: 0;
  pointer-events: none;
  animation: wm-drift 34s ease-in-out infinite alternate;
}

.sage-watermark svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* transform-box again - without it a scale on an SVG rect grows from the
   viewBox origin and the bars slide out of the mark instead of pulsing. */
.wm-bar {
  fill: #0b2545;
  transform-box: fill-box;
  transform-origin: center;
  animation: wm-breathe 7s ease-in-out infinite;
  animation-delay: calc(var(--i) * 420ms);
}

@keyframes wm-breathe {
  0%,
  100% {
    transform: scaleY(0.8);
    opacity: 0.04;
  }
  50% {
    transform: scaleY(1);
    opacity: 0.07;
  }
}

@keyframes wm-drift {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(-1.4vmin, -2vmin, 0);
  }
}

/* A page carrying its own background treatment must not also paint the flat
   corner stamp behind it. index.html has the waveform field and its own grain
   layer; the utility pages keep the stamp. */
body:has(.sage-watermark)::after,
body:has(.sage-field)::after {
  display: none;
}

/* Motion off, mark kept. Something this large moving is a real problem for
   some people, and it is on every screen of the page. */
@media (prefers-reduced-motion: reduce) {
  .sage-watermark {
    animation: none;
  }
  .wm-bar {
    animation: none;
    opacity: 0.05;
  }
}

/* On a narrow screen it would sit under the text rather than beside it, and a
   watermark competing with body copy is just noise. */
@media (max-width: 720px) {
  .sage-watermark {
    width: 34vmin;
    height: 34vmin;
  }
}

/* ------------------------------------------------- flat fallback watermark

   For pages without the live markup. Same geometry, same colour, no motion. */
body::after {
  content: '';
  position: fixed;
  right: 4vmin;
  bottom: 4vmin;
  width: 40vmin;
  height: 40vmin;
  z-index: 0;
  pointer-events: none;
  opacity: 0.05;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='%230b2545'%3E%3Crect x='4.2' y='8.4' width='2.1' height='7.2' rx='1.05'/%3E%3Crect x='7.6' y='5.8' width='2.1' height='12.5' rx='1.05'/%3E%3Crect x='11' y='3.4' width='2.1' height='17.3' rx='1.05'/%3E%3Crect x='14.4' y='5.8' width='2.1' height='12.5' rx='1.05'/%3E%3Crect x='17.8' y='8.4' width='2.1' height='7.2' rx='1.05'/%3E%3C/g%3E%3C/svg%3E")
      center / contain no-repeat;
}

@media (max-width: 720px) {
  body::after {
    opacity: 0.035;
    width: 34vmin;
    height: 34vmin;
  }
}
