/* Shared state primitives (WAV-3290): segmented control, status chips, skeletons, empty and
   error states, inline validation. Helpers in states.js. */

/* Segmented control: a pill track; the selected option is raised. role=radiogroup. */
.segmented {display:inline-flex;align-items:center;gap:2px;padding:2px;border-radius:var(--radius-pill);background:var(--track);max-width:100%;overflow-x:auto;scrollbar-width:none}
.segmented [role=radio],.segmented>a {display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:32px;height:32px;padding:0 11px;border:0;border-radius:var(--radius-pill);background:transparent;box-shadow:none;color:var(--fg-3);font:var(--weight-strong) 13.5px/1 var(--font);white-space:nowrap;text-decoration:none;cursor:pointer;transition:background-color var(--dur-2) var(--ease-out),box-shadow var(--dur-2) var(--ease-out),color var(--dur-1) var(--ease-standard)}
.segmented [role=radio]:hover,.segmented>a:hover {color:var(--fg-1);background:transparent;text-decoration:none}
.segmented [role=radio][aria-checked=true],.segmented>a[aria-current] {background:var(--segment-selected,var(--surface-l1));color:var(--fg-1);box-shadow:0 1px 2px rgb(0 0 0 / .07),0 0 0 1px var(--border-1)}
.segmented [role=radio]:focus-visible,.segmented>a:focus-visible {outline:2px solid var(--fg-1);outline-offset:2px}
.segmented [role=radio] .icon {width:16px;height:16px}
.segmented.lg [role=radio] {height:36px;min-height:36px}
.segmented.icons [aria-checked=false] .lbl {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
@media (max-width:600px) {.segmented [role=radio],.segmented>a {height:auto;min-height:44px;padding-block:6px}}

/* Status chips: Healthy · Degraded · Down · Unknown · Stale. Unknown is hatched, never green. */
.status-chip {display:inline-flex;align-items:center;gap:8px;min-height:26px;padding:0 10px;border-radius:var(--radius-pill);background:var(--track);color:var(--fg-2);font:var(--weight-strong) 12.5px/1.2 var(--font);white-space:nowrap}
.status-chip.sm {min-height:22px;padding:0 8px;gap:6px;font-size:12px}
.status-chip .dot {flex:none;width:7px;height:7px;border-radius:50%;background:currentColor}
.status-chip .asof {font-weight:var(--weight-regular);color:var(--fg-3)}
.status-chip.ok {background:var(--ok-bg);color:var(--ok)}
.status-chip.warn {background:var(--warn-bg);color:var(--warn)}
.status-chip.bad {background:var(--bad-bg);color:var(--bad)}
.status-chip.info {background:var(--info-bg);color:var(--info)}
.status-chip.neutral {background:var(--track);color:var(--fg-2)}
.status-chip.stale {background:var(--track);color:var(--fg-2)}
.status-chip.stale .dot {background:transparent;box-shadow:inset 0 0 0 1.5px currentColor;opacity:.7}
.status-chip.unknown {background:var(--hatch),var(--track);color:var(--fg-2)}
.status-chip.unknown .dot {background:transparent;box-shadow:inset 0 0 0 1.5px currentColor}
.status-chip.live .dot {animation:breathe 1.8s var(--ease-standard) infinite}

/* Skeletons hold the final geometry: same size, radius and --surface-l2 as the content. */
.skeleton {display:block;border-radius:var(--radius-sm);background:linear-gradient(100deg,var(--surface-l2) 40%,var(--surface-l3) 50%,var(--surface-l2) 60%) 0 0/300% 100%;animation:sweep 1.6s linear infinite}
@keyframes sweep {from {background-position:100% 0} to {background-position:-50% 0}}
.skeleton-group {display:grid;gap:10px}
.skeleton-group.skeleton-grid {grid-template-columns:repeat(var(--sk-columns,auto-fill),minmax(min(220px,100%),1fr))}
.sk-line {height:12px;border-radius:6px}
.sk-line.short {width:60%}
.sk-tile {width:100%;border-radius:var(--radius)}
.sk-row {display:flex;align-items:center;gap:12px;min-height:56px}
.sk-thumb {flex:none;width:44px;height:44px;border-radius:10px}
.sk-lines {display:grid;gap:8px;flex:1}
.sk-turn {display:grid;gap:10px}
.sk-bubble {justify-self:end;width:min(60%,420px);height:44px;border-radius:20px}

/* Empty and error states: one line, the next step; diagnostics only behind a disclosure. */
.empty-state {text-align:center}
.empty-state .empty-media {display:flex;justify-content:center;gap:8px;margin-bottom:12px}
.empty-state .empty-media img {width:72px;height:72px;border-radius:12px;object-fit:cover}
/* WAV-3297: three fanned real posters in a fixed box (empty until real media arrives). */
.empty-state .empty-fan {position:relative;display:block;width:220px;height:112px}
.empty-fan-tile {position:absolute;top:16px;left:10px;width:110px;aspect-ratio:16/9;border-radius:10px;overflow:hidden;background:var(--stage);opacity:.55;transform:rotate(-7deg)}
.empty-fan-tile[data-fan="1"] {left:auto;right:10px;top:12px;transform:rotate(6deg)}
.empty-fan-tile[data-fan="2"] {left:50px;top:28px;width:120px;z-index:1;opacity:1;transform:none;box-shadow:var(--shadow-md)}
.empty-state .empty-fan-tile img {display:block;width:100%;height:100%;border-radius:0;object-fit:cover}
.empty-state p {max-width:420px;margin-inline:auto}
.empty-state .actions {justify-content:center;margin-top:12px}
.error-state {display:grid;gap:10px;max-width:520px;margin:0 auto;padding:var(--space-10) var(--space-5);text-align:left}
.error-state :is(h1,h2) {margin:0;font-size:var(--text-24);font-weight:600;letter-spacing:-.02em}
.error-state p {margin:0;color:var(--fg-2)}
.error-details summary {cursor:pointer;color:var(--fg-3);font-size:var(--text-13)}
.error-details pre {margin:8px 0 0;font-size:12px;white-space:pre-wrap;overflow-wrap:anywhere}

/* Inline validation, after the first blur. */
.field-hint {margin:4px 0 0;font-size:var(--text-13);font-weight:var(--weight-regular)}
.field-hint.field-error {color:var(--bad)}
.field-hint.field-ok {color:var(--ok)}

/* The public footer's Service status link never claims health: a hatched (unknown) dot. */
.footer a[href="/status"]::before {content:'';display:inline-block;width:7px;height:7px;margin:0 7px 1px 0;border-radius:50%;background:var(--hatch),var(--track);box-shadow:inset 0 0 0 1.5px currentColor;vertical-align:middle}

/* A play control waiting for media data (WAV-4393): a ring over the control, so nothing moves. */
:is(.glass-pill,.media-viewer-control)[aria-busy=true] {position:relative}
:is(.glass-pill,.video-play,.media-viewer-control)[aria-busy=true]::after {content:"";position:absolute;inset:-3px;border:2px solid transparent;border-top-color:currentColor;border-radius:50%;pointer-events:none;animation:buffer-spin .8s linear infinite}
.chat-asset-frame[data-buffering=true] .glass-controls {opacity:1;pointer-events:auto}
@keyframes buffer-spin {to {transform:rotate(360deg)}}
