/* Ozzie's frame. The ring color shows his mood; what's inside is a photo, a video loop, or the drawn portrait. */

.theo { --size: 44px; position: relative; width: var(--size); height: var(--size); border-radius: 50%; flex: none; overflow: hidden; background: var(--cobalt);
  box-shadow: 0 0 0 3px var(--ring, var(--good)); transition: box-shadow .3s, transform .3s; }
.theo-sm { --size: 44px; }
.theo-lg { --size: 260px; box-shadow: 0 0 0 6px #fff; }
.theo-xl { --size: 100%; width: 100%; height: auto; aspect-ratio: 1; border-radius: 32px; box-shadow: 0 0 0 4px var(--ring, var(--good)); }
.theo-svg { width: 100%; height: 100%; display: block; }

.theo[data-mood="idle"]     { --ring: var(--good); }
.theo[data-mood="thinking"] { --ring: var(--cobalt); }
.theo[data-mood="pleased"]  { --ring: var(--good); }
.theo[data-mood="alert"]    { --ring: var(--warn); }
.theo[data-mood="worried"]  { --ring: var(--bad); }
.theo.talking, .theo.listening { --ring: var(--cobalt); }
.theo-sm.talking { transform: scale(1.06); }
.theo-lg.talking, .theo-lg.listening { box-shadow: 0 0 0 6px #fff; }

/* Photo Ozzie: his ring swells with his voice (--lvl is 0..1, set ~30 times a second while he talks). */
/* Photo Ozzie: avatar.js moves the photo (breathing, drift, lean-in, nods); the ring swells with his voice (--lvl, 0..1). */
.avatar-photo .face { position: absolute; inset: 0; transform-origin: 50% 62%; will-change: transform; }
.avatar-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; display: block; }
/* Expression and mouth layers (public/avatar/expressions.json): soft ovals over the face and mouth. */
.avatar-photo img.expr { opacity: 0; -webkit-mask-image: radial-gradient(ellipse 30% 34% at 50% 42%, #000 62%, transparent 100%); mask-image: radial-gradient(ellipse 30% 34% at 50% 42%, #000 62%, transparent 100%); }
.avatar-photo img.mouth { opacity: 0; -webkit-mask-image: radial-gradient(ellipse 14% 9% at 50% 54.5%, #000 55%, transparent 100%); mask-image: radial-gradient(ellipse 14% 9% at 50% 54.5%, #000 55%, transparent 100%); }
/* Blink layers: only a soft oval around the eyes shows through, so a near-perfect match is enough. */
.avatar-photo img.eyes { opacity: 0; -webkit-mask-image: radial-gradient(ellipse 21% 8.5% at 50% 36.5%, #000 55%, transparent 100%); mask-image: radial-gradient(ellipse 21% 8.5% at 50% 36.5%, #000 55%, transparent 100%); }
.theo-xl.avatar-photo.talking { box-shadow: 0 0 0 calc(4px + var(--lvl, 0) * 10px) var(--ring); transition: box-shadow .08s; }
.theo-sm.avatar-photo.talking { box-shadow: 0 0 0 calc(3px + var(--lvl, 0) * 4px) var(--ring); }

/* Real-person video avatar (public/avatar/manifest.json): two stacked loops that cross-fade between states. */
.avatar-video { background: var(--cobalt); }
.avatar-video video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; opacity: 0; transition: opacity .28s ease; }
.avatar-video video.on { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .theo, .theo-sm.talking { transition: none; transform: none; }
  .avatar-video video { transition: none; }
}

/* Meet Ozzie gallery */
.mood-card .theo { --size: 170px; }
