/* =============================================================================
   MissionAlarm — animated UI sequences.

   Four looping recreations of the app's real screens, drawn in CSS from
   design-system tokens. They exist because the thing this app does is motion:
   a counter climbing, a meter settling, a heatmap filling. A static PNG cannot
   show any of that.

   Contract:
   - Nothing animates until assets/anim.js adds .is-playing, so a tile that is
     off-screen costs nothing and a scripts-off visitor still sees a legible
     final frame (the un-animated state IS the finished state).
   - prefers-reduced-motion: reduce holds every tile at its final frame.
   - Every colour, radius, duration and easing below comes from tokens.css.
     No literal hex, no invented timing.
   ========================================================================== */

.demo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(248px, 1fr));
  gap: var(--space-xl);
  margin-top: var(--space-xxl);
}

.demo-tile {
  background: var(--surface-raised);
  border: var(--border-hairline) solid var(--smoke-border);
  border-radius: var(--radius-card);
  padding: var(--space-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* The little screen each sequence plays inside. 9:16-ish, like the phone. */
.demo-screen {
  position: relative;
  aspect-ratio: 9 / 13;
  border-radius: var(--radius-lg);
  background: var(--surface-base);
  border: var(--border-hairline) solid var(--smoke-border);
  overflow: hidden;
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
}

.demo-cap { display: flex; flex-direction: column; gap: var(--space-xxs); }
.demo-cap b {
  font-family: var(--font-mono);
  font-size: var(--mono-label-size);
  font-weight: var(--mono-label-weight);
  letter-spacing: var(--mono-label-tracking);
  text-transform: uppercase;
  color: var(--acid);
}
.demo-cap span {
  font-size: var(--caption-size);
  line-height: var(--caption-line);
  color: var(--text-secondary-accessible);
}

.demo-label {
  font-family: var(--font-mono);
  font-size: var(--mono-label-size);
  letter-spacing: var(--mono-label-tracking);
  text-transform: uppercase;
  color: var(--text-secondary-accessible);
}

/* ---------- 1. The ring ---------------------------------------------------- */

.d1-time {
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: var(--alarm-time-weight);
  letter-spacing: var(--alarm-time-tracking);
  color: var(--text-primary);
  line-height: 1;
  margin-top: var(--space-sm);
}
.d1-date { margin-top: var(--space-xxs); }

.d1-alert {
  margin-top: auto;
  background: var(--surface-float);
  border-radius: var(--radius-lg);
  padding: var(--space-sm);
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  opacity: 0;
  transform: translateY(14px);
}
.is-playing .d1-alert {
  animation: d1-in var(--duration-card-reveal) var(--ease-spring) forwards;
}
@keyframes d1-in { to { opacity: 1; transform: none; } }

.d1-alert-name { font-size: var(--caption-size); color: var(--text-primary); font-weight: 700; }

/* Apple's slide-to-stop, which we can neither remove nor restyle in the real
   product. Drawn here for the same reason the copy admits it exists. */
.d1-stop {
  position: relative;
  height: 26px;
  border-radius: var(--radius-full);
  background: var(--smoke);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.d1-stop em {
  font-style: normal;
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: var(--mono-label-tracking);
  text-transform: uppercase;
  color: var(--text-secondary-accessible);
}
.d1-stop::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 35%,
              rgba(240, 238, 233, var(--opacity-lock-shimmer)) 50%, transparent 65%);
  transform: translateX(-100%);
}
.is-playing .d1-stop::after {
  animation: d1-shimmer var(--duration-shimmer-interval) linear infinite;
}
@keyframes d1-shimmer { to { transform: translateX(100%); } }

.d1-cta {
  height: 28px;
  border-radius: var(--radius-full);
  background: var(--acid);
  color: var(--text-inverse);
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.is-playing .d1-cta {
  animation: d1-pulse var(--duration-blaze-pulse) ease-in-out infinite;
}
@keyframes d1-pulse { 50% { transform: scale(1.035); } }

/* ---------- 2. The rep counter --------------------------------------------- */

.d2-meter {
  height: var(--size-confidence-bar-height);
  border-radius: var(--radius-full);
  background: var(--smoke);
  overflow: hidden;
  margin-top: var(--space-sm);
}
.d2-meter i { display: block; height: 100%; width: 8%; background: var(--acid); border-radius: inherit; }
.is-playing .d2-meter i { animation: d2-fill 2.4s var(--ease-spring) forwards; }
@keyframes d2-fill { to { width: 88%; } }

.d2-conf { margin-top: var(--space-xs); color: var(--acid); }

/* Odometer: a strip of 21 numbers stepped through its own height, so the count
   really climbs 0 -> 20 rather than cross-fading between two states. */
.d2-count {
  margin-top: auto;
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--space-xs);
  font-family: var(--font-mono);
  font-size: var(--mono-counter-size);
  font-weight: var(--mono-counter-weight);
  color: var(--acid);
}
.d2-window { height: 1em; overflow: hidden; }
.d2-strip { display: block; transform: translateY(calc(-20 * 1em)); }
.is-playing .d2-strip { animation: d2-roll 4s steps(20, end) infinite; }
.d2-strip b { display: block; height: 1em; line-height: 1; font-weight: inherit; }
@keyframes d2-roll { from { transform: translateY(0); } to { transform: translateY(calc(-20 * 1em)); } }

.d2-total { font-size: 18px; color: var(--text-secondary-accessible); }
.d2-foot { text-align: center; margin-top: var(--space-xs); }

/* ---------- 3. The object hunt --------------------------------------------- */

.d3-card {
  background: var(--surface-float);
  border-radius: var(--radius-lg);
  padding: var(--space-sm);
  text-align: center;
}
.d3-card b { display: block; font-size: var(--caption-size); color: var(--text-primary); }

.d3-view {
  position: relative;
  flex: 1;
  margin-top: var(--space-sm);
  border-radius: var(--radius-lg);
  background: var(--surface-float);
  overflow: hidden;
}
/* Viewfinder brackets, drawn with two gradients rather than four elements. */
.d3-view::before {
  content: "";
  position: absolute;
  inset: 14%;
  border: var(--border-control) solid var(--smoke-border);
  border-radius: var(--radius-sm);
}
.d3-scan {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--acid), transparent);
  opacity: 0;
}
.is-playing .d3-scan { animation: d3-scan 3.2s ease-in-out infinite; }
@keyframes d3-scan {
  0%        { top: 8%;  opacity: 0; }
  12%       { opacity: .9; }
  55%       { top: 88%; opacity: .9; }
  70%, 100% { top: 88%; opacity: 0; }
}

.d3-verdict {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%) scale(.9);
  font-family: var(--font-mono);
  font-size: var(--mono-label-size);
  letter-spacing: var(--mono-label-tracking);
  text-transform: uppercase;
  color: var(--text-inverse);
  background: var(--acid);
  border-radius: var(--radius-full);
  padding: 5px 10px;
  opacity: 0;
}
.is-playing .d3-verdict { animation: d3-verdict 3.2s var(--ease-spring) infinite; }
@keyframes d3-verdict {
  0%, 58%   { opacity: 0; transform: translate(-50%, -50%) scale(.9); }
  70%, 92%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100%      { opacity: 0; transform: translate(-50%, -50%) scale(1); }
}

/* ---------- 4. The streak --------------------------------------------------- */

.d4-grid {
  margin-top: var(--space-sm);
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 3px;
}
.d4-grid i {
  aspect-ratio: 1;
  border-radius: 2px;
  background: var(--smoke);
  opacity: .35;
}
.is-playing .d4-grid i {
  animation: d4-pop var(--duration-streak-burst) var(--ease-spring) forwards;
  animation-delay: calc(var(--i) * var(--stagger-price-lines) / 3);
}
@keyframes d4-pop { to { opacity: 1; transform: none; } }

/* The four states the heatmap actually distinguishes. Grey is "we couldn't
   tell", and it is deliberately not a failure colour. */
.d4-grid i.on   { background: var(--acid); }
.d4-grid i.late { background: var(--ember); }
.d4-grid i.miss { background: var(--blaze); }
.d4-grid i.grey { background: var(--text-secondary); }

.d4-day {
  margin-top: auto;
  font-family: var(--font-mono);
  font-size: var(--mono-counter-size);
  font-weight: var(--mono-counter-weight);
  color: var(--acid);
  text-align: center;
  line-height: 1;
}
.d4-foot { text-align: center; margin-top: var(--space-xs); }

/* ---------- reduced motion: hold every tile on its finished frame ---------- */

@media (prefers-reduced-motion: reduce) {
  .is-playing .d1-alert,
  .is-playing .d1-stop::after,
  .is-playing .d1-cta,
  .is-playing .d2-meter i,
  .is-playing .d2-strip,
  .is-playing .d3-scan,
  .is-playing .d3-verdict,
  .is-playing .d4-grid i { animation: none !important; }

  .d1-alert    { opacity: 1; transform: none; }
  .d2-meter i  { width: 88%; }
  .d3-verdict  { opacity: 1; }
  .d4-grid i   { opacity: 1; }
}

/* Same treatment with no JavaScript at all: .is-playing never arrives, so the
   rules above never fire and these defaults are what a visitor sees. */
.demo-tile:not(.is-playing) .d1-alert   { opacity: 1; transform: none; }
.demo-tile:not(.is-playing) .d2-meter i { width: 88%; }
.demo-tile:not(.is-playing) .d3-verdict { opacity: 1; }
.demo-tile:not(.is-playing) .d4-grid i  { opacity: 1; }
