/* EmptyState — single source of truth for empty / loading / error states.
 *
 * Spec: docs/enterprise-grc-review-2026-05-24/09-ux-styling-review.md § 3.3
 *
 * Token contract
 * --------------
 * Uses base.css surface + text + semantic tokens only — no hex literals.
 *   --color-surface-*       background/border
 *   --color-text-*          title/description
 *   --color-primary*        primary CTA
 *   --color-danger / -info  variant accents
 *   --space-*               vertical rhythm
 *
 * The 79 legacy .empty-state declarations in www-talarity/css/** are
 * scoped to their owning pages (page-prefixed selectors like
 * `.assessment-center .empty-state`). This component owns the
 * un-prefixed `.empty-state` class — page-local rules can keep their
 * own paint until they're migrated.
 */

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: var(--space-3, 0.75rem);
    padding: var(--space-8, 2rem) var(--space-6, 1.5rem);
    border-radius: var(--radius-lg, 12px);
    background: var(--bg-secondary, transparent);
    /* --color-text-* does not exist. The real tokens are --text-primary /
       --text-secondary / --text-tertiary, so every rule in this file was resolving to
       its hardcoded FALLBACK — and those literals are the DARK palette. This component
       is loaded globally from app/index.html, so on every light-mode page its title
       rendered #f5f5f5 on a white card: ~1.01:1, invisible. A phantom token fails
       silently and the fallback becomes the only path. */
    color: var(--text-secondary, #94a3b8);
    /* Caller controls outer width — we just stretch to it.   */
    width: 100%;
    box-sizing: border-box;
    min-height: 180px;
}

.empty-state--compact {
    padding: var(--space-4, 1rem) var(--space-4, 1rem);
    min-height: 0;
    gap: var(--space-2, 0.5rem);
}

/* ─────────────────────────────────────────────────────────────────────
 * Icon
 * ─────────────────────────────────────────────────────────────────────
 */
.empty-state__icon {
    width: 56px;
    height: 56px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-tertiary, var(--cat-slate, #64748b));
    opacity: 0.65;
}
.empty-state__icon svg {
    width: 100%;
    height: 100%;
    display: block;
}
.empty-state--compact .empty-state__icon {
    width: 32px;
    height: 32px;
}

/* ─────────────────────────────────────────────────────────────────────
 * Title + description
 * ─────────────────────────────────────────────────────────────────────
 */
.empty-state__title {
    font-size: var(--text-lg, 1.125rem);
    font-weight: 600;
    color: var(--text-primary, #f5f5f5);
    margin: 0;
}
.empty-state--compact .empty-state__title {
    font-size: var(--text-base, 1rem);
}

.empty-state__description {
    font-size: var(--text-sm, 0.875rem);
    color: var(--text-secondary, #94a3b8);
    max-width: 56ch;
    line-height: 1.5;
    margin: 0;
}

/* ─────────────────────────────────────────────────────────────────────
 * Actions
 * ─────────────────────────────────────────────────────────────────────
 */
.empty-state__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-3, 0.75rem);
    margin-top: var(--space-2, 0.5rem);
}

.empty-state__action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem 1.125rem;
    border-radius: var(--radius-md, 8px);
    font-size: var(--text-sm, 0.875rem);
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background 120ms ease-out, color 120ms ease-out,
        border-color 120ms ease-out, transform 80ms ease-out;
}
.empty-state__action:focus-visible {
    outline: 2px solid var(--color-primary, #3b82f6);
    outline-offset: 2px;
}
.empty-state__action:active { transform: translateY(1px); }
.empty-state__action:disabled {
    cursor: not-allowed;
    opacity: 0.6;
}

.empty-state__action--primary {
    background: var(--color-primary, #3b82f6);
    color: #fff;
}
.empty-state__action--primary:hover:not(:disabled) {
    background: var(--color-primary-dark);
}

.empty-state__action--secondary {
    background: transparent;
    color: var(--text-primary, #f5f5f5);
    border-color: var(--border-color, var(--cat-slate-border, rgba(100, 116, 139, 0.3)));
}
.empty-state__action--secondary:hover:not(:disabled) {
    background: var(--cat-slate-bg, var(--cat-slate-bg, rgba(100, 116, 139, 0.1)));
}

/* ─────────────────────────────────────────────────────────────────────
 * Variants — error vs loading vs empty
 * ─────────────────────────────────────────────────────────────────────
 */

.empty-state--error {
    background: var(--color-danger-bg, rgba(239, 68, 68, 0.08));
    border: 1px solid var(--color-danger-border, rgba(239, 68, 68, 0.3));
}
.empty-state--error .empty-state__icon {
    color: var(--color-danger, #ef4444);
    opacity: 1;
}
.empty-state--error .empty-state__title {
    color: var(--color-danger-text, var(--text-primary));
}

/* All-clear (widget-data-contract flavor B): the data exists and nothing needs
   attention. A RESULT, not an absence — it reads as good news, carries no
   create-data CTA, and must not wear the neutral empty-inbox grey that says
   "you have nothing here". Tokens only (no literals) so both themes follow. */
.empty-state--all-clear .empty-state__icon {
    color: var(--color-success, #22c55e);
    opacity: 1;
}
.empty-state--all-clear .empty-state__title {
    color: var(--text-primary);
}

.empty-state--loading .empty-state__icon {
    color: var(--color-info, #0ea5e9);
    opacity: 1;
    animation: empty-state-spin 1.2s linear infinite;
}

@keyframes empty-state-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .empty-state--loading .empty-state__icon { animation: none; }
    .empty-state__action { transition: none; }
}

@media (prefers-contrast: more) {
    .empty-state--error { border-width: 2px; }
}
