:root {
  --haier: #0a64d6;
  --haier-light: #4f97ff;
  --ink: #e9eef6;
  --ink-dim: #9aa7ba;
  --glass: rgba(20, 27, 40, 0.72);
  --glass-line: rgba(255, 255, 255, 0.09);
  --alert: #ff3b4a;
  --ok: #34d399;
  --warm: #ffc46b;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  font-family: var(--font);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  user-select: none;
}

body {
  /* --haze is the colour the city fades into with distance, set by the page for the time of day */
  background: var(--haze, #9d8db6);
  transition: background-color 2s ease;
  cursor: grab;
}
body.dragging { cursor: grabbing; }
body.dragging .tag, body.dragging .eye { pointer-events: none; }

/* Soft shades along the top and bottom edges, so the white titles and the log read over the
   city. They run past the stage into any letterbox margin. */
.scrim {
  position: absolute; left: -2000px; right: -2000px;
  pointer-events: none;
  --shade: rgba(28, 24, 52, 0.5);
}
.scrim.top { top: -1000px; height: 1250px; background: linear-gradient(180deg, var(--shade) 80%, rgba(28, 24, 52, 0) 100%); }
.scrim.bottom { bottom: -1000px; height: 1240px; background: linear-gradient(0deg, var(--shade) 80.6%, rgba(28, 24, 52, 0) 100%); --shade: rgba(28, 24, 52, 0.28); }
body[data-ambient="day"] .scrim.top { --shade: rgba(20, 30, 50, 0.45); }

/* The stage is laid out at 1920×1080 and scaled to the window as one piece, so the SVG
   and every overlay stay registered with each other at any size. */
#stage {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 1920px;
  height: 1080px;
  transform-origin: 0 0;
}

#scene {
  position: absolute;
  inset: 0;
  width: 1920px;
  height: 1080px;
  overflow: visible;
  transform-origin: 0 0;
}
/* The city recolours smoothly when the time of day changes. */
#layer-city.eased :is(polygon, path, circle, rect, ellipse, line) {
  transition: fill 2s ease, stroke 2s ease, opacity 2s ease;
}

/* ------------------------------------------------------------------ brand + status */

.brand { position: absolute; left: 56px; top: 44px; }
.brand-mark { display: flex; align-items: baseline; gap: 14px; font-size: 40px; font-weight: 700; letter-spacing: -0.5px; }
.brand-mark .ongo { color: var(--warm); text-shadow: 0 0 24px rgba(255, 196, 107, 0.45); }
.brand-mark .x { color: var(--ink-dim); font-weight: 300; font-size: 30px; }
.brand-mark .haier { color: #fff; }
.brand { text-shadow: 0 1px 12px rgba(20, 16, 40, 0.45); }
.brand-sub { margin-top: 6px; font-size: 17px; color: #d6dbe6; letter-spacing: 0.2px; }
.brand-sub span { opacity: 0.8; }

.status {
  position: absolute; right: 56px; top: 48px;
  display: flex; align-items: center; gap: 10px;
  font-size: 14px; color: var(--ink-dim);
  padding: 8px 14px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--glass-line);
}
.status-dot { width: 8px; height: 8px; border-radius: 50%; background: #f59e0b; box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.5); }
.status.live .status-dot { background: var(--ok); animation: live 2.4s infinite; }
.status.down .status-dot { background: var(--alert); }
@keyframes live { 0% { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0.55); } 70% { box-shadow: 0 0 0 9px rgba(52, 211, 153, 0); } 100% { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0); } }

/* ------------------------------------------------------------------ start button */

/* Which conversation the next "Ongo" opens: under the start button. */
.convo {
  position: absolute; right: 56px; top: 162px;
  display: flex; align-items: center; gap: 6px;
  padding: 5px; border-radius: 999px;
  background: rgba(10, 14, 24, 0.55); border: 1px solid rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
}
.convo-label { font-size: 12px; color: rgba(233, 238, 246, 0.6); padding: 0 8px 0 10px; }
.convo button {
  font: inherit; font-size: 13px; font-weight: 600; color: var(--ink); cursor: pointer;
  padding: 7px 14px; border: 0; border-radius: 999px; background: transparent;
  transition: background 0.25s, color 0.25s;
}
.convo button:hover { background: rgba(255, 255, 255, 0.08); }
.convo button.next { background: var(--warm); color: #2a1d08; }
.convo kbd { font: inherit; font-size: 11px; opacity: 0.55; margin-left: 4px; }

.start-demo {
  position: absolute; right: 56px; top: 100px;
  display: flex; align-items: center; gap: 12px;
  font: inherit; font-size: 16px; font-weight: 650; color: #2a1d08; cursor: pointer;
  padding: 12px 22px 12px 14px; border: 0; border-radius: 999px;
  background: var(--warm);
  box-shadow: 0 10px 30px rgba(255, 196, 107, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.5);
  transition: transform 0.15s var(--ease), box-shadow 0.3s, background 0.3s, color 0.3s;
}
.start-demo:hover { transform: translateY(-1px); box-shadow: 0 14px 36px rgba(255, 196, 107, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.5); }
.start-demo:active { transform: scale(0.97); }
.start-demo .play { width: 26px; height: 26px; border-radius: 50%; background: #2a1d08; position: relative; flex: none; }
.start-demo .play::after { content: ""; position: absolute; left: 10px; top: 7px; border-style: solid; border-width: 6px 0 6px 9px; border-color: transparent transparent transparent var(--warm); }
.start-demo:disabled { cursor: default; background: rgba(255, 255, 255, 0.12); color: var(--ink); box-shadow: none; transform: none; }
.start-demo:disabled .play { background: var(--warm); animation: blink 1.6s infinite; }
.start-demo:disabled .play::after { display: none; }

/* ------------------------------------------------------------------ scenario banner */

.banner {
  position: absolute; left: 50%; top: 34px;
  transform: translate(-50%, -20px); opacity: 0;
  display: flex; align-items: center; gap: 16px;
  padding: 14px 28px 14px 22px; border-radius: 999px;
  background: linear-gradient(135deg, rgba(10, 100, 214, 0.95), rgba(79, 151, 255, 0.92));
  box-shadow: 0 18px 50px rgba(10, 100, 214, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.25);
  transition: transform 0.7s var(--ease), opacity 0.5s ease;
  pointer-events: none;
}
.banner.show { transform: translate(-50%, 0); opacity: 1; }
.banner-kicker { font-size: 13px; text-transform: uppercase; letter-spacing: 1.6px; opacity: 0.8; padding-right: 16px; border-right: 1px solid rgba(255, 255, 255, 0.3); }
.banner-title { font-size: 24px; font-weight: 650; }

/* ------------------------------------------------------------------ proactive caption */

/* Big and bilingual, between the log and the phone: what Ongo just did without being asked. */
.caption {
  position: absolute; left: calc(50% + 80px); bottom: 64px; width: 940px; z-index: 2;
  transform: translate(-50%, 24px) scale(0.97); opacity: 0;
  display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;
  padding: 22px 36px 24px; border-radius: 28px;
  background: linear-gradient(135deg, rgba(10, 100, 214, 0.96), rgba(79, 151, 255, 0.93));
  box-shadow: 0 24px 70px rgba(10, 100, 214, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.3);
  transition: transform 0.7s var(--ease), opacity 0.5s ease;
  pointer-events: none;
}
.caption.show { transform: translate(-50%, 0) scale(1); opacity: 1; }
.caption-kicker { font-size: 15px; font-weight: 600; text-transform: uppercase; letter-spacing: 2px; color: var(--warm); }
.caption-en, .caption-zh { text-wrap: balance; }
.caption-en { font-size: 36px; font-weight: 750; line-height: 1.2; }
.caption-zh { font-size: 32px; font-weight: 600; line-height: 1.25; opacity: 0.95; }

/* ------------------------------------------------------------------ fall alert */

.alert {
  position: absolute; left: 50%; top: 30px; z-index: 2;
  transform: translate(-50%, -16px) scale(0.96); opacity: 0;
  display: flex; align-items: center; gap: 18px;
  padding: 18px 30px 18px 20px; border-radius: 20px;
  background: rgba(70, 10, 18, 0.92); border: 1px solid rgba(255, 59, 74, 0.6);
  box-shadow: 0 0 0 0 rgba(255, 59, 74, 0.5), 0 24px 60px rgba(0, 0, 0, 0.45);
  transition: transform 0.6s var(--ease), opacity 0.4s ease;
  pointer-events: none;
}
.alert.show { transform: translate(-50%, 0) scale(1); opacity: 1; animation: alert-ring 1.6s infinite; }
@keyframes alert-ring { 0% { box-shadow: 0 0 0 0 rgba(255, 59, 74, 0.55), 0 24px 60px rgba(0, 0, 0, 0.45); } 80%, 100% { box-shadow: 0 0 0 22px rgba(255, 59, 74, 0), 0 24px 60px rgba(0, 0, 0, 0.45); } }
.alert-icon { width: 46px; height: 46px; border-radius: 50%; background: var(--alert); display: grid; place-items: center; font-weight: 800; font-size: 26px; color: #fff; }
.alert-title { font-size: 24px; font-weight: 700; }
.alert-title span { font-weight: 500; opacity: 0.85; }
.alert-body { margin-top: 4px; font-size: 15px; color: #ffc9cd; }

/* ------------------------------------------------------------------ command log */

.log {
  position: absolute; left: 48px; bottom: 44px; width: 500px;
  padding: 18px 20px 14px; border-radius: 20px;
  background: var(--glass); border: 1px solid var(--glass-line);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.log-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.log-title { font-size: 13px; text-transform: uppercase; letter-spacing: 1.4px; color: var(--ink-dim); font-weight: 600; }
.log-title span { text-transform: none; letter-spacing: 0; }
.log-live { font-size: 12px; color: var(--ok); display: flex; align-items: center; gap: 6px; text-transform: uppercase; letter-spacing: 1px; }
.log-live i { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); animation: blink 1.6s infinite; }
@keyframes blink { 50% { opacity: 0.3; } }

#log { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; height: 252px; overflow: hidden; justify-content: flex-end; }
#log li {
  display: grid; grid-template-columns: 70px 1fr; align-items: baseline;
  padding: 7px 10px; border-radius: 10px; font-size: 16px; line-height: 1.3;
  animation: log-in 0.7s var(--ease) both;
}
#log li:last-child { background: rgba(255, 196, 107, 0.1); }
#log li .t { font-variant-numeric: tabular-nums; font-size: 13px; color: var(--ink-dim); }
#log li .who { color: var(--warm); font-weight: 650; }
#log li .arrow { color: var(--ink-dim); margin: 0 6px; }
#log li .dev { font-weight: 650; color: #fff; }
#log li .dev small { font-weight: 400; color: var(--ink-dim); font-size: 13px; margin-left: 4px; }
#log li .det { color: #cdd6e4; }
#log li.scenario .dev { color: var(--haier-light); }
#log li.alert-line .det, #log li.alert-line .dev { color: #ff8a94; }
@keyframes log-in { from { opacity: 0; transform: translateY(14px); filter: blur(4px); } to { opacity: 1; transform: none; filter: none; } }
.log-empty { position: absolute; left: 0; right: 0; bottom: 120px; text-align: center; color: var(--ink-dim); font-size: 16px; line-height: 1.6; transition: opacity 0.4s; }
.log-empty span { opacity: 0.7; }
.log-empty.hide { opacity: 0; }

/* ------------------------------------------------------------------ phone */

.phone {
  position: absolute; right: 52px; top: 560px; width: 300px; height: 470px;
  border-radius: 46px; padding: 22px 14px;
  background: linear-gradient(160deg, #26324a, #10151f 70%);
  border: 6px solid #0a0d13; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.12), 0 30px 70px rgba(0, 0, 0, 0.5);
  transform: translateX(400px); opacity: 0;
  transition: transform 0.9s var(--ease), opacity 0.6s ease;
  display: flex; flex-direction: column; overflow: hidden;
}
.phone.show { transform: none; opacity: 1; }
.phone-notch { position: absolute; top: 10px; left: 50%; width: 92px; height: 26px; margin-left: -46px; background: #0a0d13; border-radius: 14px; }
.phone-time { margin-top: 34px; text-align: center; font-size: 52px; font-weight: 300; letter-spacing: -1px; font-variant-numeric: tabular-nums; }
.phone-date { text-align: center; font-size: 13px; color: var(--ink-dim); margin-bottom: 14px; }
/* Whatever does not fit stays inside the screen: the oldest card fades out under the edge. */
.phone-stack {
  flex: 1; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column; gap: 8px;
  -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 46px), transparent);
  mask-image: linear-gradient(180deg, #000 calc(100% - 46px), transparent);
}
.note { flex: none; }
.note {
  border-radius: 18px; padding: 12px 14px; background: rgba(255, 255, 255, 0.13);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  animation: note-in 0.8s var(--ease) both;
}
.note-app { display: flex; align-items: center; gap: 7px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.8px; color: var(--ink-dim); margin-bottom: 4px; }
.note-app i { width: 16px; height: 16px; border-radius: 5px; background: var(--haier); display: inline-block; }
.note-app em { margin-left: auto; font-style: normal; text-transform: none; letter-spacing: 0; }
.note-title { font-weight: 650; font-size: 15px; }
.note-body { font-size: 13px; color: #d5dceb; margin-top: 2px; line-height: 1.35; }
.note.alert-note { background: rgba(255, 59, 74, 0.32); border: 1px solid rgba(255, 59, 74, 0.6); }
.note.alert-note .note-app i { background: var(--alert); }
@keyframes note-in { from { opacity: 0; transform: translateY(-18px) scale(0.96); } to { opacity: 1; transform: none; } }

/* ------------------------------------------------------------------ control panel */

.panel {
  position: absolute; left: 0; top: 0; bottom: 0; width: 430px;
  background: rgba(12, 16, 25, 0.94); border-right: 1px solid var(--glass-line);
  transform: translateX(-100%); transition: transform 0.45s var(--ease);
  display: flex; flex-direction: column; z-index: 10;
  box-shadow: 30px 0 60px rgba(0, 0, 0, 0.4);
}
.panel.open { transform: none; }
.panel-head { padding: 26px 26px 14px; display: flex; flex-direction: column; gap: 4px; }
.panel-head strong { font-size: 20px; }
.panel-head span { font-size: 12px; color: var(--ink-dim); }
.panel-body { overflow-y: auto; padding: 4px 26px 26px; }
.panel h4 { margin: 18px 0 8px; font-size: 11px; text-transform: uppercase; letter-spacing: 1.4px; color: var(--ink-dim); font-weight: 600; }
.panel .row { display: flex; flex-wrap: wrap; gap: 6px; }
.panel { cursor: default; }
.panel button {
  font: inherit; font-size: 13px; color: var(--ink); cursor: pointer;
  padding: 7px 11px; border-radius: 9px; border: 1px solid var(--glass-line);
  background: rgba(255, 255, 255, 0.06); transition: background 0.15s, transform 0.1s;
}
.panel button:hover { background: rgba(255, 255, 255, 0.14); }
.panel button:active { transform: scale(0.96); }
.panel button.primary { background: var(--haier); border-color: transparent; }
.panel button.primary:hover { background: var(--haier-light); }
.panel button.danger { background: rgba(255, 59, 74, 0.2); border-color: rgba(255, 59, 74, 0.4); }

/* ------------------------------------------------------------------ SVG scene */

.vignette { transition: opacity 1.6s ease; mix-blend-mode: multiply; }
.glow { transition: opacity 1.6s ease; mix-blend-mode: screen; }
.glow stop, linearGradient stop, radialGradient stop { transition: stop-color 1.6s ease; }
.window-pane { transition: fill 2s ease; }
.tv-screen { transition: opacity 1.2s ease; }

.tag { pointer-events: none; }
.tag-card {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  white-space: nowrap; display: flex; align-items: center; gap: 9px;
  padding: 7px 12px 7px 10px; border-radius: 12px;
  background: rgba(16, 22, 34, 0.8); border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.3);
  font-family: var(--font); color: var(--ink);
  transition: border-color 0.5s, box-shadow 0.5s, background 0.5s;
}
.tag-card .ic { width: 9px; height: 9px; border-radius: 50%; background: #5d6878; flex: none; transition: background 0.4s, box-shadow 0.4s; }
.tag-card.on .ic { background: var(--haier-light); box-shadow: 0 0 10px var(--haier-light); }
.tag-card.warn .ic { background: #f59e0b; box-shadow: 0 0 10px #f59e0b; }
.tag-card.good .ic { background: var(--ok); box-shadow: 0 0 10px var(--ok); }
.tag-card.bad { border-color: rgba(255, 59, 74, 0.7); background: rgba(70, 10, 18, 0.88); }
.tag-card.bad .ic { background: var(--alert); box-shadow: 0 0 10px var(--alert); }
.tag-card .nm { font-size: 13px; font-weight: 650; line-height: 1.2; }
.tag-card .nm i { font-style: normal; font-weight: 400; color: var(--ink-dim); margin-left: 4px; }
.tag-card .st { font-size: 12px; color: #c3cddc; line-height: 1.25; font-variant-numeric: tabular-nums; }
.tag-card .bar { margin-top: 4px; height: 4px; width: 150px; border-radius: 2px; background: rgba(255, 255, 255, 0.12); overflow: hidden; }
.tag-card .bar b { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--haier), var(--haier-light)); border-radius: 2px; }
.tag-card.ping { animation: ping 1s var(--ease); }
@keyframes ping { 0% { box-shadow: 0 0 0 0 rgba(255, 196, 107, 0.8), 0 8px 22px rgba(0, 0, 0, 0.3); border-color: var(--warm); } 100% { box-shadow: 0 0 0 16px rgba(255, 196, 107, 0), 0 8px 22px rgba(0, 0, 0, 0.3); } }

.ongo-label {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  font-family: var(--font); font-size: 13px; font-weight: 700; letter-spacing: 0.4px; white-space: nowrap;
  color: #2a1d08; background: var(--warm); padding: 3px 10px; border-radius: 999px;
  box-shadow: 0 0 18px rgba(255, 196, 107, 0.6);
}

/* AI Eye card */
.eye {
  position: absolute; inset: 0; border-radius: 22px; padding: 18px 20px;
  background: rgba(14, 20, 32, 0.9); border: 1px solid rgba(79, 151, 255, 0.4);
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.45), 0 0 40px rgba(79, 151, 255, 0.15);
  font-family: var(--font); color: var(--ink);
  opacity: 0; transform: translateY(14px) scale(0.97); transition: opacity 0.5s ease, transform 0.7s var(--ease);
}
.eye.show { opacity: 1; transform: none; }
.eye-head { display: flex; align-items: center; gap: 10px; }
.eye-badge { width: 30px; height: 30px; border-radius: 9px; background: linear-gradient(135deg, var(--haier), var(--haier-light)); display: grid; place-items: center; }
.eye-badge::after { content: ""; width: 10px; height: 10px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.3); }
.eye-title { font-size: 17px; font-weight: 700; }
.eye-title span { font-weight: 400; color: var(--ink-dim); }
.eye-sub { font-size: 12px; color: var(--ink-dim); }
.eye-list { margin: 12px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 5px; }
.eye-list li {
  display: grid; grid-template-columns: 30px 1fr auto; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: 10px; background: rgba(255, 255, 255, 0.04);
  opacity: 0; transform: translateX(10px); transition: opacity 0.4s ease, transform 0.5s var(--ease);
}
.eye.show .eye-list li.in { opacity: 1; transform: none; }
.eye-list .em { font-size: 21px; text-align: center; }
.eye-list .nm { font-size: 14px; font-weight: 600; white-space: nowrap; }
.eye-list .nm i { font-style: normal; font-weight: 400; color: var(--ink-dim); margin-left: 4px; font-size: 13px; }
.eye-list .fr { height: 4px; border-radius: 2px; background: rgba(255, 255, 255, 0.1); margin-top: 4px; overflow: hidden; }
.eye-list .fr b { display: block; height: 100%; border-radius: 2px; background: var(--ok); }
.eye-list .d { white-space: nowrap; font-size: 12px; color: #c3cddc; text-align: right; font-variant-numeric: tabular-nums; }
.eye-list li.flag { background: rgba(255, 59, 74, 0.16); box-shadow: inset 0 0 0 1px rgba(255, 59, 74, 0.55); }
.eye-list li.flag .fr b { background: var(--alert); }
.eye-list li.flag .d { color: #ff9aa2; font-weight: 700; }
.recipe {
  margin-top: 12px; padding: 11px 13px; border-radius: 14px;
  background: linear-gradient(135deg, rgba(255, 196, 107, 0.18), rgba(255, 196, 107, 0.06));
  border: 1px solid rgba(255, 196, 107, 0.35);
  opacity: 0; transform: translateY(8px); transition: opacity 0.5s ease, transform 0.6s var(--ease);
}
.eye.show .recipe.in { opacity: 1; transform: none; }
.recipe-k { font-size: 11px; text-transform: uppercase; letter-spacing: 1.2px; color: var(--warm); font-weight: 700; }
.recipe-t { font-size: 15px; font-weight: 650; margin-top: 3px; }
.recipe-s { font-size: 12px; color: #c9d1de; margin-top: 2px; }

/* Person + robots */
.walker .leg-l, .walker .leg-r, .walker .arm-l, .walker .arm-r { transform-box: fill-box; transform-origin: 50% 0; }
.walker.walking .leg-l, .walker.walking .arm-r { animation: swing 0.62s ease-in-out infinite alternate; }
.walker.walking .leg-r, .walker.walking .arm-l { animation: swing 0.62s ease-in-out infinite alternate-reverse; }
.walker.walking .body { animation: bob 0.31s ease-in-out infinite alternate; }
.walker.slow.walking .leg-l, .walker.slow.walking .leg-r { animation-duration: 0.95s; }
.walker.slow.walking .arm-l { animation-duration: 0.95s; }
.walker.slow.walking .body { animation-duration: 0.48s; }
.walker.seated .leg-l, .walker.seated .leg-r { transform: rotate(-78deg); transition: transform 0.4s ease; }
@keyframes swing { from { transform: rotate(-22deg); } to { transform: rotate(22deg); } }
@keyframes bob { from { transform: translateY(0); } to { transform: translateY(-1.6px); } }

.fall-ring { transform-box: fill-box; transform-origin: center; animation: fall-ring 1.5s ease-out infinite; }
.fall-ring.r2 { animation-delay: 0.5s; }
.fall-ring.r3 { animation-delay: 1s; }
@keyframes fall-ring { from { transform: scale(0.3); opacity: 0.95; } to { transform: scale(2.4); opacity: 0; } }

.ongo-glow { transition: opacity 0.6s ease; }
#layer-fx > circle[r="46"] { transition: opacity 0.6s ease; }
.ongo-pulse { transform-box: fill-box; transform-origin: center; opacity: 0; }
.ongo-pulse.go { animation: ongo-pulse 1.1s ease-out; }
@keyframes ongo-pulse { from { transform: scale(0.4); opacity: 1; } to { transform: scale(3.2); opacity: 0; } }

.ripple { transform-box: fill-box; transform-origin: center; animation: ripple 0.9s ease-out forwards; }
@keyframes ripple { from { transform: scale(0.2); opacity: 0.9; } to { transform: scale(2.2); opacity: 0; } }


.ready-pulse { transform-box: fill-box; transform-origin: center; animation: ripple 1.8s ease-out infinite; }

.fade { transition: opacity 0.6s ease; }

.follow-ring { animation: march 1s linear infinite; }
@keyframes march { to { stroke-dashoffset: -22; } }

/* Shown only while the music should play but the browser is still waiting for a first click. */
.sound-hint {
  position: absolute; left: 50%; bottom: 40px; transform: translate(-50%, 20px); opacity: 0;
  padding: 10px 18px; border-radius: 999px; font-size: 15px;
  background: rgba(79, 151, 255, 0.92); color: #fff; pointer-events: none;
  transition: opacity 0.4s ease, transform 0.5s var(--ease);
}
.sound-hint.show { opacity: 1; transform: translate(-50%, 0); }

/* the kid's snack hitting the floor in front of Ongo */
.spill { transition: opacity 0.9s ease; }
.spill .dropped { animation: spill-drop 0.5s cubic-bezier(0.3, 1.6, 0.6, 1); transform-box: fill-box; transform-origin: center; }
@keyframes spill-drop { from { transform: scale(0.2); } to { transform: scale(1); } }
