/* Mirror Glint: a celebration made of reflected light (Mirror Health)
 *
 * A seal draws its ring and check while small facets burst out, turn to
 * catch the light, and settle. Use for finished milestones (setup complete,
 * team invited). Never for readings or health values.
 *
 * Default look: muted colors and a solid seal. Options (on the stage, the
 * toast, or any ancestor):
 *   .mg-vivid  full-strength colors
 *   .mg-glass  glossy glass seal with a moving sheen and gradient ring
 *
 * Markup (the stage is complete at rest; .is-playing only adds motion):
 *   <div class="mg-stage">
 *     <span class="mg-ring" aria-hidden="true"></span>
 *     <span class="mg-seal"><svg class="mg-check" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5l4.2 4.2L19 7"/></svg></span>
 *     <span class="mg-glints" aria-hidden="true"></span>
 *   </div>
 * Play: MirrorGlint.play(stage) from mirror-glint.js.
 *
 * Theme tokens (set on any ancestor; all optional):
 *   --mg-c1 … --mg-c4  base colors (accent, cyan, green, glass)
 *   --mg-mute          the grey that muting mixes in
 *   --mg-seal          solid seal color (defaults to muted --mg-c1)
 *   --mg-size          seal diameter (set on the stage itself)
 * No libraries. Honors prefers-reduced-motion.
 */

@property --mg-sweep { syntax: "<angle>"; inherits: false; initial-value: 360deg; }

/* Working colors. Defaults live in var() fallbacks so a palette set on any
   ancestor always wins. Muted by default; .mg-vivid restores full strength. */
.mg-stage, .mg-toast {
  --mg-k1: color-mix(in oklab, var(--mg-c1, #1769d2) 58%, var(--mg-mute, #8c96a6));
  --mg-k2: color-mix(in oklab, var(--mg-c2, #0ea5c6) 52%, var(--mg-mute, #8c96a6));
  --mg-k3: color-mix(in oklab, var(--mg-c3, #1d7a3b) 52%, var(--mg-mute, #8c96a6));
  --mg-k4: color-mix(in oklab, var(--mg-c4, #b9d6ff) 70%, var(--mg-mute, #8c96a6));
}
.mg-vivid .mg-stage, .mg-vivid .mg-toast, .mg-stage.mg-vivid, .mg-toast.mg-vivid {
  --mg-k1: var(--mg-c1, #1769d2);
  --mg-k2: var(--mg-c2, #0ea5c6);
  --mg-k3: var(--mg-c3, #1d7a3b);
  --mg-k4: var(--mg-c4, #b9d6ff);
}

.mg-stage {
  --mg-size: 104px;
  --mg-dur: 1500ms;
  position: relative;
  display: grid;
  place-items: center;
  width: calc(var(--mg-size) * 2.6);
  max-width: 100%;
  aspect-ratio: 1;
  isolation: isolate;
}

/* Light ripple behind the seal */
.mg-stage::before {
  content: "";
  position: absolute;
  width: var(--mg-size);
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1.5px solid color-mix(in oklab, var(--mg-k1) 60%, transparent);
  opacity: 0;
  z-index: -1;
}

/* Seal: solid by default */
.mg-seal {
  position: relative;
  grid-area: 1 / 1;
  display: grid;
  place-items: center;
  width: var(--mg-size);
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  background: var(--mg-seal, var(--mg-k1));
  box-shadow: 0 14px 30px -18px color-mix(in oklab, var(--mg-seal, var(--mg-k1)) 80%, transparent);
}
.mg-seal::after {
  content: "";
  position: absolute;
  inset: -30%;
  background: linear-gradient(104deg, transparent 42%, rgb(255 255 255 / 0.7) 50%, transparent 58%);
  transform: translateX(-130%);
  display: none;
}
.mg-check {
  width: 46%;
  fill: none;
  stroke: #fff;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 24;
  stroke-dashoffset: 0;
}

/* Ring that draws around the seal: one solid color by default */
.mg-ring {
  grid-area: 1 / 1;
  width: calc(var(--mg-size) * 1.26);
  aspect-ratio: 1;
  border-radius: 50%;
  background: color-mix(in oklab, var(--mg-seal, var(--mg-k1)) 70%, transparent);
  -webkit-mask-image:
    radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px)),
    conic-gradient(from -90deg, #000 var(--mg-sweep), transparent 0);
  -webkit-mask-composite: source-in;
  mask-image:
    radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px)),
    conic-gradient(from -90deg, #000 var(--mg-sweep), transparent 0);
  mask-composite: intersect;
}

/* Glass option: glossy seal, sheen, gradient ring and shimmering facets */
:is(.mg-glass .mg-stage, .mg-glass .mg-toast, .mg-stage.mg-glass, .mg-toast.mg-glass) .mg-seal {
  background:
    radial-gradient(110% 90% at 28% 18%, rgb(255 255 255 / 0.55), transparent 52%),
    linear-gradient(155deg, var(--mg-k1), color-mix(in oklab, var(--mg-k1), var(--mg-k2) 60%));
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / 0.55),
    inset 0 -12px 26px rgb(0 0 0 / 0.16),
    0 22px 44px -20px color-mix(in oklab, var(--mg-k1) 75%, transparent);
}
:is(.mg-glass .mg-stage, .mg-glass .mg-toast, .mg-stage.mg-glass, .mg-toast.mg-glass) .mg-seal::after { display: block; }
:is(.mg-glass .mg-stage, .mg-stage.mg-glass) .mg-ring {
  background: conic-gradient(from -90deg, var(--mg-k2), var(--mg-k1) 40%, var(--mg-k3) 75%, var(--mg-k2));
  opacity: 0.85;
}
:is(.mg-glass .mg-stage, .mg-glass .mg-toast, .mg-stage.mg-glass, .mg-toast.mg-glass) .mg-check {
  filter: drop-shadow(0 1px 1px rgb(0 0 0 / 0.18));
}

/* Facets: flat by default; the turn makes them flash as they spin */
.mg-glints { position: absolute; inset: 0; pointer-events: none; perspective: 600px; }
.mg-glint {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--s, 9px);
  height: var(--s, 9px);
  margin: calc(var(--s, 9px) / -2) 0 0 calc(var(--s, 9px) / -2);
  opacity: 0;
  transform-style: preserve-3d;
}
.mg-glint::before {
  content: "";
  position: absolute;
  inset: 0;
  clip-path: var(--shape, polygon(50% 0, 100% 50%, 50% 100%, 0 50%));
  background: var(--c);
}
:is(.mg-glass .mg-stage, .mg-glass .mg-toast, .mg-stage.mg-glass, .mg-toast.mg-glass) .mg-glint::before {
  background: linear-gradient(135deg, var(--c) 20%, color-mix(in oklab, var(--c), #fff 70%) 50%, var(--c) 80%);
  background-size: 260% 260%;
}
.mg-glint[data-shape="shard"] { --shape: polygon(50% 0, 100% 34%, 76% 100%, 16% 84%, 0 30%); }
.mg-glint[data-shape="spark"] { --shape: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%); }
.mg-glint[data-shape="sliver"] { height: calc(var(--s, 9px) * 0.38); --shape: inset(0 round 99px); }
.mg-glint[data-shape="bead"] { --shape: circle(50%); }

/* ------------------------------------------------------------------ */
/* Motion: plays only while .is-playing is set; the rest state is final */
/* ------------------------------------------------------------------ */
.is-playing .mg-seal { animation: mg-seal 620ms cubic-bezier(0.2, 0.9, 0.25, 1.25) both; }
.is-playing .mg-ring { animation: mg-ring 760ms cubic-bezier(0.55, 0, 0.25, 1) 120ms both; }
.is-playing .mg-check { animation: mg-check 420ms cubic-bezier(0.4, 0, 0.2, 1) 300ms both; }
.is-playing .mg-seal::after { animation: mg-sheen 820ms ease-out 680ms both; }
.is-playing.mg-stage::before { animation: mg-ripple 1100ms cubic-bezier(0.2, 0.7, 0.2, 1) 180ms both; }
.is-playing .mg-glint { animation: mg-fly var(--mg-dur, 1500ms) cubic-bezier(0.14, 0.8, 0.28, 1) var(--t, 260ms) both; }
:is(.mg-glass .is-playing, .is-playing.mg-glass) .mg-glint::before {
  animation: mg-catch calc(var(--mg-dur, 1500ms) * 0.45) linear var(--t, 260ms) 2 alternate;
}

@keyframes mg-seal {
  0% { transform: scale(0.82); }
  60% { transform: scale(1.05); }
  100% { transform: scale(1); }
}
@keyframes mg-ring { from { --mg-sweep: 0deg; } to { --mg-sweep: 360deg; } }
@keyframes mg-check { from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } }
@keyframes mg-sheen { from { transform: translateX(-130%); } to { transform: translateX(130%); } }
@keyframes mg-ripple {
  0% { opacity: 0.6; transform: scale(1); }
  100% { opacity: 0; transform: scale(2.3); }
}
@keyframes mg-fly {
  0% { opacity: 0; transform: translate(calc(var(--x) * 0.28), calc(var(--y) * 0.28)) rotate(0deg) rotateY(0deg) scale(0.3); }
  10% { opacity: 1; }
  62% { opacity: 1; transform: translate(var(--x), var(--y)) rotate(var(--r)) rotateY(var(--flip)) scale(1); }
  100% { opacity: 0; transform: translate(calc(var(--x) * 1.1), calc(var(--y) * 1.1 + var(--drop, 16px)))
    rotate(calc(var(--r) * 1.35)) rotateY(calc(var(--flip) * 1.5)) scale(0.55); }
}
@keyframes mg-catch { from { background-position: 0% 0%; } to { background-position: 100% 100%; } }

/* ------------------------------------------------------------------ */
/* Compact: a toast or button confirmation                             */
/* ------------------------------------------------------------------ */
.mg-toast {
  --mg-size: 26px;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  overflow: visible;
}
.mg-toast .mg-mini {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--mg-size);
  aspect-ratio: 1;
  flex: none;
}
.mg-toast .mg-mini .mg-seal { width: 100%; box-shadow: none; }
.mg-toast .mg-mini .mg-check { width: 56%; stroke-width: 3; }
.mg-toast .mg-glints { inset: -2px; }

/* ------------------------------------------------------------------ */
/* Reduced motion: the finished seal appears; no flying facets          */
/* ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .mg-glint, .mg-stage::before { display: none; }
  .is-playing .mg-seal, .is-playing .mg-ring, .is-playing .mg-check {
    animation: mg-appear 240ms ease-out both;
  }
  .mg-seal::after { display: none !important; }
}
@keyframes mg-appear { from { opacity: 0; } to { opacity: 1; } }
