/* anim.css (L4, illustrator). Art contract: docs/art-style.md.
   F4.1 holds only the static art contract: part pivots, mood faces, look-at,
   hold ring, day phases. Action keyframes ([data-anim]) are added by later L4 work. */

/* ---- Part pivots (art-style.md §7) ---- */
:is(.entity, .fixture) svg [class*="part-"] { transform-box: fill-box; transform-origin: 50% 50%; }
:is(.entity, .fixture) svg .part-body { transform-origin: 50% 100%; }
:is(.entity, .fixture) svg .part-head { transform-origin: 50% 90%; }
:is(.entity, .fixture) svg .part-leg-f, :is(.entity, .fixture) svg .part-leg-b, :is(.entity, .fixture) svg .part-wing, :is(.entity, .fixture) svg .part-arm { transform-origin: 50% 0; }
:is(.entity, .fixture) svg .part-cargo { transform-origin: 50% 100%; }
:is(.entity, .fixture) svg .pivot-l { transform-origin: 0 50%; }
:is(.entity, .fixture) svg .pivot-r { transform-origin: 100% 50%; }
:is(.entity, .fixture) svg .pivot-t { transform-origin: 50% 0; }
:is(.entity, .fixture) svg .pivot-b { transform-origin: 50% 100%; }
:is(.entity, .fixture) svg .pivot-tl { transform-origin: 0 0; }
:is(.entity, .fixture) svg .pivot-tr { transform-origin: 100% 0; }
:is(.entity, .fixture) svg .pivot-bl { transform-origin: 0 100%; }
:is(.entity, .fixture) svg .pivot-br { transform-origin: 100% 100%; }

/* ---- Look-at (ARCH §5.2): --look-x / --look-y in [-1, 1], written at AI tick rate ---- */
.entity .part-eye {
  translate: calc(var(--look-x, 0) * 2.5px) calc(var(--look-y, 0) * 2px);
  transition: translate 250ms ease-out, scale 300ms ease-out;
}
.entity .part-head { rotate: calc(var(--look-x, 0) * 4deg); transition: rotate 300ms ease-out; }

/* ---- Mood faces (art-style.md §8). Defaults: eye-open + mouth-smile ---- */
.eye-happy, .eye-closed, .mouth-open, .mouth-o, .mouth-lick { display: none; }
[data-mood="happy"] .eye-open, [data-mood="happy"] .mouth-smile { display: none; }
[data-mood="happy"] .eye-happy, [data-mood="happy"] .mouth-open { display: inline; }
[data-mood="playful"] .mouth-smile { display: none; }
[data-mood="playful"] .mouth-open { display: inline; }
[data-mood="curious"] .mouth-smile { display: none; }
[data-mood="curious"] .mouth-o { display: inline; }
[data-mood="peckish"] .mouth-smile { display: none; }
[data-mood="peckish"] .mouth-lick { display: inline; }
.eye-open { transform-box: fill-box; transform-origin: 50% 60%; transition: scale 300ms ease-out; }
[data-mood="sleepy"] .eye-open { scale: 1 0.45; }
[data-state="sleep"] .eye-open, [data-state="sleep"] .eye-happy { display: none; }
[data-state="sleep"] .eye-closed { display: inline; }

/* ---- Hold ring (ui.svg#ring): host sets --hold from 0 to 1 ---- */
.ring-fill { stroke-dashoffset: calc(100 - 100 * var(--hold, 0)); }

/* ---- Day phases on the backdrop (art-style.md §9). L2 sets --daylight and data-phase on .stage ---- */
:is(.layer-backdrop, .backdrop-bleed) .night-veil { opacity: calc(max(0, 0.75 - var(--daylight, 1)) * 1.29); transition: opacity 1.5s linear; }
:is(.layer-backdrop, .backdrop-bleed) .dusk-veil, :is(.layer-backdrop, .backdrop-bleed) .dawn-veil,
:is(.layer-backdrop, .backdrop-bleed) .stars, :is(.layer-backdrop, .backdrop-bleed) .night-light { opacity: 0; transition: opacity 1.5s linear; }
.stage[data-phase="evening"] :is(.layer-backdrop, .backdrop-bleed) .dusk-veil { opacity: 0.25; }
.stage[data-phase="morning"] :is(.layer-backdrop, .backdrop-bleed) .dawn-veil { opacity: 0.18; }
.stage[data-phase="night"] :is(.layer-backdrop, .backdrop-bleed) .stars,
.stage[data-phase="night"] :is(.layer-backdrop, .backdrop-bleed) .night-light,
.stage[data-phase="evening"] :is(.layer-backdrop, .backdrop-bleed) .night-light { opacity: 1; }
.stage[data-phase="night"] :is(.entity, .fixture) .part-light,
.stage[data-phase="evening"] :is(.entity, .fixture) .part-light { fill: #ffe9a0; }

/* ---- Cars sheet (art-style.md §16) ---- */
/* Traffic light: data-light="red|amber|green" (D16: at most one change per second); unlit lamps stay as dim grey glass. */
.fixture .lamp { opacity: 0.18; transition: opacity 400ms ease-out; }
.fixture:not([data-light="red"]):not([data-light="amber"]) .lamp-green,
.fixture[data-light="red"] .lamp-red,
.fixture[data-light="amber"] .lamp-amber { opacity: 1; }
/* Roof beacons glow softly while data-light="on" (never flashing). */
.entity .beacon-glow { transition: opacity 500ms ease-out; }
.entity[data-light="on"] .beacon-glow { opacity: 0.85; }
/* Top rotor seen from the side: turns by squashing along its length while the helicopter acts. */
.entity .rotor { transform-box: fill-box; transform-origin: 50% 50%; }
.entity[data-anim] .rotor { animation: gfk-rotor 400ms linear infinite; }
@keyframes gfk-rotor { 0%, 100% { scale: 1 1; } 50% { scale: 0.15 1; } }
html[data-reduced-motion] .entity[data-anim] .rotor { animation: none; }

/* ---- Nature sheet (art-style.md §17) ---- */
/* Rain cloud: drops hidden until the cloud sprinkles (wiggle) or showers (sneeze); they fall gently. */
.entity .rain { opacity: 0; transition: opacity 300ms ease-out; }
.entity[data-anim="wiggle"] .rain, .entity[data-anim="sneeze"] .rain { opacity: 1; animation: gfk-rain 1s linear infinite; }
@keyframes gfk-rain { from { translate: 0 -4px; } to { translate: 0 6px; } }

/* Ladybird counting (SPEC 4.7): the host sets data-light="0".."7" = spots shown so far; no data-light shows all seven. */
.entity[data-light] .spot { opacity: 0.2; transition: opacity 300ms ease-out; }
.entity[data-light="1"] .spot-1,
.entity[data-light="2"] :is(.spot-1, .spot-2),
.entity[data-light="3"] :is(.spot-1, .spot-2, .spot-3),
.entity[data-light="4"] :is(.spot-1, .spot-2, .spot-3, .spot-4),
.entity[data-light="5"] :is(.spot-1, .spot-2, .spot-3, .spot-4, .spot-5),
.entity[data-light="6"] :is(.spot-1, .spot-2, .spot-3, .spot-4, .spot-5, .spot-6),
.entity[data-light="7"] .spot { opacity: 1; }

/* ---- Village sheet (art-style.md §18) ---- */
/* Bucket water shows while data-light="full"; a shirt fresh off the line is darker while data-light="wet". */
.entity .fill, .entity .wet { transition: opacity 400ms ease-out; }
.entity[data-light="full"] .fill { opacity: 1; }
.entity[data-light="wet"] .wet { opacity: 0.35; }
/* Long-press peek: the pumpkin shows a smile, the apple's friendly worm waves hello. */
.entity .face, .entity .worm { transition: opacity 300ms ease-out; }
.entity[data-anim="peek"] :is(.face, .worm) { opacity: 1; }

/* ---- City sheet (art-style.md §19) ---- */
/* Pedestrian light reuses .lamp-red / .lamp-green (data-light="red|green", default green). Streetlamp glow: data-light="on". */
.fixture .lamp-glow { transition: opacity 600ms ease-out; }
.fixture[data-light="on"] .lamp-glow { opacity: 0.6; }

/* ---- ABC sheet (art-style.md §21) ---- */
/* Letter tiles show the lowercase glyph on their back while flipping (long press). */
.entity[data-anim="flip"] .upper { opacity: 0; }
.entity[data-anim="flip"] .lower { opacity: 1; }

/* ---- Shapes sheet (art-style.md §22) ---- */
/* Recolourable shapes: class "tint" reads --tint (tokens.css), set per entity by the host. */
.entity .tint { fill: var(--tint, #e85a4f); transition: fill 300ms ease-out; }
/* The rainbow and the studio window are backdrop pieces: shapes sitting in the rainbow zone stand in front of them (E4). */
.fixture[data-fixture="rainbow"] { z-index: 900 !important; }
.fixture[data-fixture="window"] { z-index: 901 !important; }
/* Rainbow bands fill when their colour is listed in data-bands (space separated, e.g. "red blue"; set by js/ui/shapes.js). */
.fixture .band { transition: opacity 600ms ease-out; }
.fixture[data-bands~="red"] .band-red, .fixture[data-bands~="orange"] .band-orange,
.fixture[data-bands~="yellow"] .band-yellow, .fixture[data-bands~="green"] .band-green,
.fixture[data-bands~="blue"] .band-blue, .fixture[data-bands~="purple"] .band-purple { opacity: 1; }
/* S9: the sun/moon fixture crossfades its art (1.5 s, never a flash; reduced motion 250 ms). */
.fixture > svg.phase-in { animation: gfk-phase-in var(--dur-daynight, 1500ms) linear both; }
.fixture > svg.phase-out { position: absolute; left: 0; top: 0; pointer-events: none; animation: gfk-phase-out var(--dur-daynight, 1500ms) linear both; }
@keyframes gfk-phase-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes gfk-phase-out { from { opacity: 1; } to { opacity: 0; } }
html[data-reduced-motion] .fixture > svg:is(.phase-in, .phase-out) { animation-duration: 250ms; }
@media (prefers-reduced-motion: reduce) { .fixture > svg:is(.phase-in, .phase-out) { animation-duration: 250ms; } }

/* Studio window = the sun/moon fixture: moon at night, clouds while data-light="clouds". */
.fixture .win-sun, .fixture .win-moon, .fixture .win-clouds { transition: opacity 1.5s linear; }
.stage[data-phase="night"] .fixture .win-sun { opacity: 0; }
.stage[data-phase="night"] .fixture .win-moon { opacity: 1; }
.fixture[data-light="clouds"] .win-clouds { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .entity .part-eye, .entity .part-head, .eye-open { transition: none; }
  .fixture .lamp, .fixture .lamp-glow, .fixture .band, .fixture :is(.win-sun, .win-moon, .win-clouds), .entity .beacon-glow, .entity .spot, .entity .fill, .entity .wet, .entity .face, .entity .worm, .entity .tint { transition-duration: 250ms; }
  .entity[data-anim] .rotor { animation: none; }
  .entity[data-anim] .rain { animation: none; }
}
html[data-reduced-motion] .entity[data-anim] .rain { animation: none; }
