/* LAMPA — the lamp, seven states. Source of truth: docs/brand/r3/MOTION-SPEC.md.
   Pose carries the connection state, light carries egress authority (§4).
   No light is drawn in the asset; every glow below is a runtime layer (§0).
   With JS off the markup's data-state="disconnected" — or no attribute at all — is the resting pose. */

@property --lp-dip{syntax:'<number>';inherits:true;initial-value:1}
@property --lp-dx{syntax:'<length>';inherits:true;initial-value:0px}
/* the light channels are registered so they TRANSITION on the root; the layers below multiply
   them by --lp-dip without a transition of their own — an opacity transition on a layer would be
   retriggered every frame by the loop and shave the keyframes (measured: .226/.400 for .218/.420) */
@property --lp-fill{syntax:'<color>';inherits:true;initial-value:#615850}
@property --lp-beam{syntax:'<number>';inherits:true;initial-value:0}
@property --lp-core{syntax:'<number>';inherits:true;initial-value:0}
@property --lp-halo{syntax:'<number>';inherits:true;initial-value:0}
@property --lp-spill{syntax:'<number>';inherits:true;initial-value:0}
@property --lp-rim{syntax:'<number>';inherits:true;initial-value:0}
@property --lp-pool{syntax:'<number>';inherits:true;initial-value:0}
@property --lp-amb{syntax:'<number>';inherits:true;initial-value:0}

:where(.lamp){
  /* PALETTE.md dark — the light */
  --lamp-light:#F0A93C;   /* the brand: egress verified, connected only */
  --lamp-lit:#FBE3A8;     /* opening fill, connected */
  --lamp-mid:#E5CE97;     /* opening fill, degraded + reconnecting */
  --lamp-search:#C9A45E;  /* opening fill, connecting + blocked — lit, unverified */
  --lamp-off:#615850;     /* opening fill, disconnected + failed (AMENDMENT-off-state-luminance) */
  --lamp-dim:#8A6A34;     /* the wordmark's P counter while searching; not used by the rig itself */
  /* the body — owner trace, warmed per AMENDMENT-off-state-luminance */
  --lamp-shade:#3D3730; --lamp-base:#352F2A; --lamp-base-top:#3D3730; --lamp-neck:#252119; --lamp-face:#1B1814;
  --lamp-shadow:#0B0A08; --lamp-ink:#000;
  /* tints of the one light — same hue turned up, never a second colour (§10.3) */
  --lamp-glow-core:#FFF3D4; --lamp-glow-hot:#FFF6DE; --lamp-glow-pool:#FFEEC9; --lamp-glow-halo:#FFEFCB;
  --lamp-glow-beam:#F8D48F; --lamp-glow-rim:#FFEBBB; --lamp-glow-joint:#F7CE8A; --lamp-glow-edge:#E09A34;
  /* the counter colour the wordmark should paint in sympathy (§4) — light authority, not pose */
  --lamp-counter:#14120F;

  /* curves, §2 */
  --lp-e-spring:cubic-bezier(.34,1.30,.48,1);
  --lp-e-swing:cubic-bezier(.30,1.42,.42,1);
  --lp-e-settle:cubic-bezier(.22,1,.36,1);
  --lp-e-weight:cubic-bezier(.45,.05,.25,1);
  --lp-e-out:cubic-bezier(.25,.46,.45,.94);

  /* levers, defaults = disconnected (§3, §4, §5) */
  --lp-rot:0deg; --lp-dy:1.6px; --lp-sy:1; --lp-openY:1.05; --lp-lean:0deg; --lp-dx:0px;
  --lp-fill:var(--lamp-off);
  --lp-beam:0; --lp-core:0; --lp-halo:0; --lp-spill:0; --lp-rim:0; --lp-pool:0; --lp-amb:0;
  --lp-poolx:0px; --lp-poolr:0deg; --lp-poolsx:1; --lp-poolsy:1; --lp-ambx:0px; --lp-amby:0px;
  --lp-eyeS:.04; --lp-eyeO:0; --lp-lidO:1; --lp-mS:0; --lp-mA:1; --lp-mL:0; --lp-gaze:0px;
  --lp-t-rig:620ms; --lp-e-rig:var(--lp-e-spring); --lp-t-lit:420ms; --lp-t-pool:520ms;
  --lp-dip:1;
  /* Presence has no write access to the state or light channels. */
  --lp-presence-rot:0deg; --lp-presence-dy:0px; --lp-presence-gaze:0px; --lp-presence-blink:0;
}

.lamp{display:block;position:relative;
  transition:--lp-dip 300ms var(--lp-e-settle),
    --lp-fill var(--lp-t-lit) var(--lp-e-settle),--lp-beam var(--lp-t-lit) var(--lp-e-settle),
    --lp-core var(--lp-t-lit) var(--lp-e-settle),--lp-halo var(--lp-t-lit) var(--lp-e-settle),
    --lp-spill var(--lp-t-lit) var(--lp-e-settle),--lp-rim var(--lp-t-lit) var(--lp-e-settle),
    --lp-pool var(--lp-t-lit) var(--lp-e-settle),--lp-amb var(--lp-t-lit) var(--lp-e-settle)}
.lamp-svg{display:block;width:100%;height:auto;overflow:visible}

/* ---- the seven settings ---- */
.lamp[data-state="connecting"]{
  --lp-dy:5px; --lp-sy:.945; --lp-openY:1.26;
  --lp-fill:var(--lamp-search); --lamp-counter:var(--lamp-dim);
  --lp-beam:.42; --lp-core:.30; --lp-halo:.40; --lp-spill:.34; --lp-rim:.45; --lp-pool:.34; --lp-amb:.30;
  --lp-poolsx:.62; --lp-poolsy:.84; --lp-amby:6px;
  --lp-eyeS:1; --lp-eyeO:1; --lp-lidO:0;
  --lp-t-rig:520ms; --lp-t-lit:900ms; --lp-t-pool:900ms;
}
.lamp[data-state="connected"]{
  --lp-dy:0px; --lp-openY:1;
  --lp-fill:var(--lamp-lit); --lamp-counter:var(--lamp-light);
  --lp-beam:1; --lp-core:1; --lp-halo:1; --lp-spill:.8; --lp-rim:1; --lp-pool:1; --lp-amb:1;
  --lp-eyeS:1; --lp-eyeO:1; --lp-lidO:0; --lp-mS:1; --lp-mA:0;
  --lp-t-rig:660ms; --lp-t-lit:520ms; --lp-t-pool:620ms;
}
.lamp[data-state="degraded"]{
  --lp-rot:-9deg; --lp-dy:1px; --lp-openY:1.02; --lp-lean:-3.2deg;
  --lp-fill:var(--lamp-mid); --lamp-counter:var(--lamp-mid);
  --lp-beam:.58; --lp-core:.40; --lp-halo:.62; --lp-spill:.5; --lp-rim:.6; --lp-pool:.56; --lp-amb:.5;
  --lp-poolx:10px; --lp-poolr:-3deg; --lp-poolsx:.8; --lp-poolsy:.88; --lp-ambx:-6px; --lp-amby:3px;
  --lp-eyeS:.68; --lp-eyeO:1; --lp-lidO:0; --lp-gaze:-1px;
  --lp-t-rig:760ms; --lp-e-rig:var(--lp-e-weight); --lp-t-lit:700ms; --lp-t-pool:760ms;
}
.lamp[data-state="reconnecting"]{
  --lp-dy:9px; --lp-sy:.94; --lp-openY:1.08;
  --lp-fill:var(--lamp-mid); --lamp-counter:var(--lamp-mid);
  --lp-beam:.55; --lp-core:.38; --lp-halo:.58; --lp-spill:.46; --lp-rim:.55; --lp-pool:.5; --lp-amb:.45;
  --lp-poolsx:.6; --lp-poolsy:.8; --lp-amby:12px;
  --lp-eyeS:1; --lp-eyeO:1; --lp-lidO:0;
  --lp-t-rig:560ms; --lp-t-lit:480ms; --lp-t-pool:560ms;
}
.lamp[data-state="blocked"]{
  --lp-rot:41deg; --lp-dy:0px; --lp-openY:1;
  --lp-fill:var(--lamp-search); --lamp-counter:var(--lamp-dim);
  --lp-beam:.72; --lp-core:.62; --lp-halo:.74; --lp-spill:.62; --lp-rim:.72; --lp-pool:.68; --lp-amb:.7;
  --lp-poolx:-46px; --lp-poolr:6deg; --lp-poolsx:1.24; --lp-poolsy:.62; --lp-ambx:14px; --lp-amby:14px;
  --lp-eyeS:1; --lp-eyeO:1; --lp-lidO:0; --lp-gaze:2.4px;
  --lp-t-rig:820ms; --lp-e-rig:var(--lp-e-swing); --lp-t-lit:520ms; --lp-t-pool:900ms;
}
.lamp[data-state="failed"]{
  --lp-dy:0px; --lp-openY:.90;
  --lp-eyeS:1; --lp-eyeO:1; --lp-lidO:0; --lp-mA:0; --lp-mL:1;
  --lp-t-rig:380ms; --lp-e-rig:var(--lp-e-out); --lp-t-lit:180ms; --lp-t-pool:200ms;
}

/* ---- colour bindings — nothing is hard-coded in the svg ---- */
.lp-c-light{stop-color:var(--lamp-light)} .lp-c-lit{stop-color:var(--lamp-lit)}
.lp-c-amb-edge{stop-color:var(--lamp-glow-edge)} .lp-c-beam-mid{stop-color:var(--lamp-glow-beam)}
.lp-c-core{stop-color:var(--lamp-glow-core)} .lp-c-pool-hot{stop-color:var(--lamp-glow-pool)}
.lp-c-halo-hot{stop-color:var(--lamp-glow-halo)}
.lp-contact-a{fill:var(--lamp-ink);opacity:.5} .lp-contact-b{fill:var(--lamp-ink);opacity:.55}
.lp-stem,.lp-shade{fill:var(--lamp-shade)} .lp-neck{fill:var(--lamp-neck)}
.lp-base{fill:var(--lamp-base)} .lp-baseTop,.lp-joint{fill:var(--lamp-base-top)}
.lp-baseShadow{fill:var(--lamp-shadow);opacity:.38} .lp-jointShadow{fill:var(--lamp-shadow);opacity:.45}
.lp-shadeForm{fill:var(--lamp-shadow);opacity:.22} .lp-openShade{fill:var(--lamp-ink);opacity:.16}
.lp-baseLit{fill:var(--lamp-light)} .lp-jointLit{fill:var(--lamp-glow-joint)}
.lp-hot{fill:var(--lamp-glow-hot)} .lp-spill{fill:var(--lamp-light)}
.lp-rim{fill:none;stroke:var(--lamp-glow-rim);stroke-width:1.45;stroke-linecap:round}
.lp-eye{fill:var(--lamp-face)}
.lp-lid,.lp-mouth{fill:none;stroke:var(--lamp-face);stroke-width:1.9;stroke-linecap:round}

/* ---- the rig: pose (§1, §3) ---- */
.lp-rig,.lp-beamRig{transform:translateY(calc(var(--lp-dy) + var(--lp-presence-dy))) rotate(calc(var(--lp-rot) + var(--lp-presence-rot))) scaleY(var(--lp-sy));
  transform-box:view-box;transform-origin:75.4px 115.4px;transition:transform var(--lp-t-rig) var(--lp-e-rig)}
.lp-rigAnim,.lp-beamAnim{transform-box:view-box;transform-origin:75.4px 115.4px}
.lp-beamReach{transform-box:view-box;transform-origin:75px 80px}
.lp-lean{transform:translateX(var(--lp-dx)) rotate(var(--lp-lean));transform-box:view-box;transform-origin:75px 146px;
  transition:transform 760ms var(--lp-e-weight)}
.lp-interior{transform:scaleY(var(--lp-openY));transform-box:view-box;transform-origin:75px 80px;
  transition:transform var(--lp-t-rig) var(--lp-e-settle)}
.lp-faceCounter{transform:rotate(calc((var(--lp-rot) + var(--lp-presence-rot)) * -0.55));transform-box:view-box;transform-origin:75px 81px;
  transition:transform var(--lp-t-rig) var(--lp-e-rig)}
.lp-gaze{transform:translateX(calc(var(--lp-gaze) + var(--lp-presence-gaze)));transition:transform 260ms var(--lp-e-settle)}

/* ---- the rig: light (§4) — every layer × the global dip ---- */
.lp-open{fill:var(--lp-fill)}
.lp-hot{opacity:calc(var(--lp-halo) * var(--lp-dip))}
.lp-spill{opacity:calc(var(--lp-spill) * var(--lp-dip))}
.lp-rim{opacity:calc(var(--lp-rim) * var(--lp-dip))}
.lp-halo{opacity:calc(var(--lp-halo) * .9 * var(--lp-dip))}
.lp-beamVol{opacity:calc(var(--lp-beam) * var(--lp-dip))}
.lp-beamCore{opacity:calc(var(--lp-core) * var(--lp-dip))}
.lp-jointLit{opacity:calc(var(--lp-pool) * .5 * var(--lp-dip))}
.lp-baseLit{opacity:calc(var(--lp-pool) * .8 * var(--lp-dip))}
.lp-pool{opacity:calc(var(--lp-pool) * var(--lp-dip));
  transform:translateX(var(--lp-poolx)) rotate(var(--lp-poolr)) scale(var(--lp-poolsx),var(--lp-poolsy));
  transform-box:view-box;transform-origin:75px 152px;
  transition:transform var(--lp-t-pool) var(--lp-e-settle)}
.lp-ambient{opacity:calc(var(--lp-amb) * var(--lp-dip));transform:translate(var(--lp-ambx),var(--lp-amby));
  transition:transform var(--lp-t-pool) var(--lp-e-settle)}

/* ---- the face (§7) ---- */
.lp-eye{transform:scaleY(calc(var(--lp-eyeS) * (1 - var(--lp-presence-blink) * .96)));opacity:calc(var(--lp-eyeO) * (1 - var(--lp-presence-blink)));transform-box:view-box;
  transition:transform 160ms var(--lp-e-out),opacity 90ms linear 70ms}
.lp-eyeL{transform-origin:57px 78.4px} .lp-eyeR{transform-origin:92px 78.4px}
.lp-lid{opacity:max(var(--lp-lidO),var(--lp-presence-blink));transition:opacity 90ms linear 60ms}
.lp-mSmile{opacity:var(--lp-mS)} .lp-mArc{opacity:var(--lp-mA)} .lp-mLine{opacity:var(--lp-mL)}
.lp-mouth{transition:opacity 140ms var(--lp-e-out)}

/* ---- connection work loops (§6); resting presence is sparse and scheduled by presence.js ---- */
.lamp[data-state="connecting"] .lp-rigAnim,.lamp[data-state="connecting"] .lp-beamAnim{animation:lp-scan 3.6s cubic-bezier(.44,0,.36,1) infinite}
.lamp[data-state="connecting"] .lp-beamReach{animation:lp-reach 3.6s cubic-bezier(.44,0,.36,1) infinite}
.lamp[data-state="connecting"]{animation:lp-warm 3.6s cubic-bezier(.44,0,.36,1) infinite}
.lamp[data-state="reconnecting"] .lp-rigAnim,.lamp[data-state="reconnecting"] .lp-beamAnim{animation:lp-dip 1.9s cubic-bezier(.5,0,.4,1) infinite}
.lamp[data-state="reconnecting"] .lp-beamReach{animation:lp-reach-slow 1.9s cubic-bezier(.5,0,.4,1) infinite}
.lamp[data-state="reconnecting"]{animation:lp-dip-light 1.9s cubic-bezier(.5,0,.4,1) infinite}
.lamp[data-state="degraded"]{animation:lp-breathe-light 3.2s ease-in-out infinite}
/* connected: converge once, then stop (§5) */
.lamp[data-state="connected"]{animation:lp-settle 860ms var(--lp-e-settle) 1 both}

@keyframes lp-scan{0%{transform:rotate(0deg)}20%{transform:rotate(-3.2deg)}43%{transform:rotate(1.4deg)}58%{transform:rotate(3.4deg)}78%{transform:rotate(-1.1deg)}100%{transform:rotate(0deg)}}
@keyframes lp-reach{0%{transform:scaleY(.70)}20%{transform:scaleY(1.06)}43%{transform:scaleY(.82)}58%{transform:scaleY(1.16)}78%{transform:scaleY(.88)}100%{transform:scaleY(.70)}}
@keyframes lp-warm{0%{--lp-dip:.52}20%{--lp-dip:.86}43%{--lp-dip:.6}58%{--lp-dip:1}78%{--lp-dip:.7}100%{--lp-dip:.52}}
@keyframes lp-dip{0%,100%{transform:translateY(0) rotate(0deg)}44%{transform:translateY(7.5px) rotate(1.4deg)}72%{transform:translateY(.8px) rotate(-.4deg)}}
@keyframes lp-reach-slow{0%,100%{transform:scaleY(.95)}44%{transform:scaleY(.64)}72%{transform:scaleY(.88)}}
@keyframes lp-dip-light{0%,100%{--lp-dip:1}44%{--lp-dip:.56}72%{--lp-dip:.92}}
@keyframes lp-breathe-light{0%,100%{--lp-dip:1}50%{--lp-dip:.9}}
@keyframes lp-settle{0%{--lp-dip:.62}52%{--lp-dip:1.1}100%{--lp-dip:1}}

/* An active presence sample must not retrigger the base transition every frame. */
.lamp[data-presence-event] .lp-rig,.lamp[data-presence-event] .lp-beamRig,
.lamp[data-presence-event] .lp-faceCounter,.lamp[data-presence-event] .lp-gaze,
.lamp[data-presence-event] .lp-eye,.lamp[data-presence-event] .lp-lid{transition:none}
.lamp[data-presence-motion="static"],.lamp[data-presence-motion="static"] *{animation:none !important}
.lamp[data-presence-motion="static"]{transition-duration:180ms;transition-delay:0s}
.lamp[data-presence-motion="static"] *{transition-property:opacity;transition-duration:180ms;transition-delay:0s}

/* ---- the switch (hero) — a native button, so Space/Enter come free ---- */
:where(.lamp-switch){--lamp-switch-track:#312A22;--lamp-switch-track-on:#4A3D26;--lamp-switch-knob-on:#F3EEE4;
  --lamp-light:#F0A93C;--lp-e-spring:cubic-bezier(.34,1.30,.48,1);--lp-e-out:cubic-bezier(.25,.46,.45,.94)}
.lamp-switch{appearance:none;-webkit-appearance:none;border:0;padding:0;margin:0;background:none;cursor:pointer;
  display:inline-block;inline-size:64px;block-size:36px;border-radius:999px;position:relative;vertical-align:middle;
  -webkit-tap-highlight-color:transparent;touch-action:manipulation}
.lamp-switch::before{content:"";position:absolute;inset:0;border-radius:inherit;background:var(--lamp-switch-track);
  transition:background 180ms var(--lp-e-out)}
.lamp-switch::after{content:"";position:absolute;top:4px;left:4px;width:28px;height:28px;border-radius:50%;
  background:var(--lamp-light);transition:transform 220ms var(--lp-e-spring),background 180ms var(--lp-e-out)}
.lamp-switch[aria-checked="true"]::before{background:var(--lamp-switch-track-on)}
.lamp-switch[aria-checked="true"]::after{transform:translateX(28px);background:var(--lamp-switch-knob-on)}
.lamp-switch:focus-visible{outline:2px solid var(--lamp-light);outline-offset:3px}

/* ---- Reduce Motion (§8): the poses still change, the movement between them does not.
   Transforms snap (transition removed, never shortened — a shortened composited transition
   plays out in full); the light and the face cross-fade in ≤ 180 ms. ---- */
@media (prefers-reduced-motion:reduce){
  .lamp,.lamp *{animation:none !important}
  .lamp{transition-duration:180ms !important;transition-delay:0s !important;transition-timing-function:cubic-bezier(.25,.46,.45,.94) !important}
  .lamp *{transition-property:opacity !important;transition-duration:180ms !important;transition-delay:0s !important;
    transition-timing-function:cubic-bezier(.25,.46,.45,.94) !important}
  .lamp-switch::after{transition:background 180ms cubic-bezier(.25,.46,.45,.94)}
}
