/* Chameleon UI · state layer — loading / empty / error / success by construction */
/* Declarative slot machine: wrap each outcome in its slot (.cui-loading / .cui-empty / .cui-error /
   .cui-success) and the real content in .cui-ready, then set data-cui-state on the container. CSS toggles
   the WRAPPERS (never `> *`), so a child's own display rule can't defeat the state — no specificity trap.
   No attribute at all = plain flow (progressive-enhancement fallback). */
[data-cui-state] > .cui-loading,[data-cui-state] > .cui-empty,[data-cui-state] > .cui-error,
[data-cui-state] > .cui-success,[data-cui-state] > .cui-ready{display:none}
[data-cui-state="loading"] > .cui-loading{display:block}
[data-cui-state="empty"] > .cui-empty{display:flex}
[data-cui-state="error"] > .cui-error{display:flex}
[data-cui-state="success"] > .cui-success{display:flex}
[data-cui-state="ready"] > .cui-ready{display:block}
/* skeleton — reserve the FINAL box to avoid the layout shift it's meant to prevent */
.cui-skeleton{position:relative;overflow:hidden;background:var(--cui-surface);
  border-radius:var(--cui-radius);min-height:1em}
.cui-skeleton::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.06),transparent);
  animation:cui-shimmer 1.4s infinite}
@keyframes cui-shimmer{100%{transform:translateX(100%)}}
.cui-skeleton-text{height:.8em;margin:.45em 0;border-radius:4px}
.cui-skeleton-text.is-short{width:60%}
/* spinner — short, bounded single actions only (skeletons for anything longer) */
.cui-spinner{display:inline-block;width:1.25rem;height:1.25rem;border:2px solid var(--cui-line);
  border-top-color:var(--cui-primary);border-radius:50%;animation:cui-spin .8s linear infinite;vertical-align:middle}
@keyframes cui-spin{to{transform:rotate(360deg)}}
/* empty / error / success block — icon + one-line explainer + a primary action */
.cui-state{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--cui-sp-3);
  padding:var(--cui-sp-8) var(--cui-sp-4);max-width:34rem;margin-inline:auto}
.cui-state .cui-state-icon{width:3rem;height:3rem;display:grid;place-items:center;border-radius:50%;
  background:var(--cui-surface);border:1px solid var(--cui-line);font-size:var(--cui-fs-xl)}
.cui-state h3{font-size:var(--cui-fs-lg)}
.cui-state p{color:var(--cui-muted);font-size:var(--cui-fs-sm)}
.cui-error .cui-state-icon{border-color:#7a2d2d;color:var(--cui-danger-text)}
.cui-success .cui-state-icon{border-color:#245c43;color:var(--cui-accent)}
/* reduced motion: opacity pulse instead of shimmer/spin */
@media(prefers-reduced-motion:reduce){
  .cui-skeleton::after{animation:none}
  .cui-skeleton{animation:cui-pulse 1.6s ease-in-out infinite}
  .cui-spinner{animation-duration:1.6s}
}
@keyframes cui-pulse{50%{opacity:.55}}
/* a11y reminders (author must add): container aria-busy during loading; role=status on .cui-loading;
   role=alert on .cui-error. Empty vs no-results are different copy + different CTA. */


/* ══ LEISURE LOUNGE COMPONENTS, ON THE --fc- TOKENS ══════════════════════════════════════════════════════════
   The classes above are Chameleon's own (--cui-). These three are ours and use the house tokens, so they follow
   the high contrast theme and the dark floor skin without a line changing. Documented, with live examples, on
   /components.html. */

/* STATUS CHIP. A WORD ALWAYS, never a colour alone. The word says the state; the colour and the little shape
   say it again, so somebody who cannot tell red from green still can (the shapes differ: solid dot, half dot,
   tick, ring). The waiting and working tones are the state tokens, which are contrast checked at 4.5:1. */
.ll-chip{display:inline-flex;align-items:center;gap:6px;min-height:28px;padding:2px 12px;border-radius:999px;
  border:1px solid currentColor;font:700 var(--fc-text-sm)/1.2 var(--fc-font-body);letter-spacing:.02em;white-space:nowrap;
  background:transparent;color:var(--fc-text-subtle)}
.ll-chip::before{content:"";flex:0 0 auto;width:10px;height:10px;box-sizing:border-box}
.ll-chip--waiting{color:var(--fc-danger);background:var(--fc-danger-surface)}
.ll-chip--waiting::before{background:currentColor;border-radius:50%}                 /* solid dot: nothing has started */
.ll-chip--working{color:var(--fc-warning);background:var(--fc-warning-surface)}
.ll-chip--working::before{border:2px solid currentColor;border-radius:50%;
  background:linear-gradient(90deg,currentColor 50%,transparent 50%)}                /* half dot: in progress */
.ll-chip--done{color:var(--fc-success);background:var(--fc-success-surface)}
.ll-chip--done::before{width:6px;height:11px;border:solid currentColor;border-width:0 2.5px 2.5px 0;
  transform:rotate(45deg) translate(-1px,-2px)}                                       /* tick: finished */
.ll-chip--gone{color:var(--fc-info);background:var(--fc-info-surface)}
.ll-chip--gone::before{border:2.5px solid currentColor;border-radius:50%}             /* ring: handed on or planned */
.ll-chip--none{color:var(--fc-text-muted);border-color:var(--fc-border-strong)}
.ll-chip--none::before{display:none}                                                  /* outline only: no state to show */
[data-skin="floor"] .ll-chip--waiting{color:#f0a294;background:#3a2622}
[data-skin="floor"] .ll-chip--working{color:#e9c57e;background:#3a3022}
[data-skin="floor"] .ll-chip--done{color:#a9d38a;background:#232f1e}
[data-skin="floor"] .ll-chip--gone{color:#a9bddb;background:#232b38}

/* SKELETON. Reserve the final box so nothing jumps when the data arrives (loads of 0.4 to 3 seconds; anything
   longer wants a progress bar). The shimmer is gentle and is switched off for anybody who has asked for less motion. */
.ll-skel{position:relative;overflow:hidden;display:block;min-height:1em;border-radius:var(--fc-radius-sm);
  background:var(--fc-surface-sunken);opacity:.7}
.ll-skel::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.55),transparent);animation:ll-shimmer 1.5s infinite}
@keyframes ll-shimmer{100%{transform:translateX(100%)}}
.ll-skel--row{height:64px;border-radius:var(--fc-radius-md);margin-bottom:var(--fc-space-2)}
@media (prefers-reduced-motion:reduce){.ll-skel::after{animation:none}}

/* EMPTY STATE. Say why there is nothing here and what to do about it, in plain words, with the one action that helps. */
.ll-empty{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--fc-space-2);
  padding:var(--fc-space-5) var(--fc-space-4);color:var(--fc-text-muted)}
.ll-empty__icon{width:48px;height:48px;display:grid;place-items:center;border-radius:50%;
  background:var(--fc-surface-sunken);color:var(--fc-text-subtle);font-size:var(--fc-text-xl)}
.ll-empty__title{font-size:var(--fc-text-lg);font-weight:600;color:var(--fc-text)}
.ll-empty__hint{font-size:var(--fc-text-sm);max-width:44ch;line-height:1.5}
.ll-empty__action{margin-top:var(--fc-space-2)}
