/* ============================================================
   EduShieldID — components/feedback.css
   Alert toasts, empty states, and the full-page error shell —
   the three ways the app tells you something happened.
   ============================================================ */

/* ── Alert stack (partials/alert_messages.html) ─────────────── */
.alert-stack {
  position: fixed;
  top: var(--sp-4);
  right: var(--sp-4);
  z-index: 9000;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  max-width: 380px;
  width: 100%;
}

.alert[hidden] {
  display: none;
}

.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  box-shadow: var(--shadow-md);
  animation: alertSlideIn 200ms ease;
}

@keyframes alertSlideIn {
  from { transform: translateX(20px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}

.alert-success { background: var(--clr-success-bg); color: var(--clr-success); border-left: 3px solid var(--clr-success); }
.alert-error,
.alert-danger   { background: var(--clr-danger-bg);  color: var(--clr-danger);  border-left: 3px solid var(--clr-danger); }
.alert-warning  { background: var(--clr-warning-bg); color: var(--clr-warning); border-left: 3px solid var(--clr-warning); }
.alert-info     { background: var(--clr-info-bg);    color: var(--clr-info);    border-left: 3px solid var(--clr-info); }

/* ── Empty state (partials/empty_state.html) ────────────────── */
/* Fills its container rather than sitting as a short line of grey text in the
   middle of a tall panel: when a card's only content is "nothing here", the
   empty state IS the card's content and should occupy it deliberately. */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  /* Claim any spare height the parent was stretched to, so the message sits in
     the optical centre of the panel rather than pinned to its top edge. */
  flex: 1 1 auto;
  padding: var(--sp-12) var(--sp-8);
  text-align: center;
  color: var(--clr-text-muted);
  font-size: var(--text-sm);
}
/* Inside small panels the full padding is more air than the panel has to give. */
.empty-state--compact { padding: var(--sp-6) var(--sp-4); gap: var(--sp-3); }

.empty-state-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-full);
  background: var(--clr-bg);
  border: 1px solid var(--clr-border);
  color: var(--clr-text-muted);
  flex-shrink: 0;
}
.empty-state-icon svg { width: 26px; height: 26px; }
.empty-state--compact .empty-state-icon { width: 44px; height: 44px; }
.empty-state--compact .empty-state-icon svg { width: 21px; height: 21px; }

.empty-state-copy { display: flex; flex-direction: column; gap: var(--sp-1); max-width: 44ch; }
.empty-state-title {
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  color: var(--clr-text);
  margin: 0;
}
.empty-state-message { margin: 0; }
.empty-state-hint { margin: 0; font-size: var(--text-xs); }

.empty-state-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  justify-content: center;
}

/* An empty state standing in for table rows spans the whole table, so it must
   not inherit the cell's left alignment or the row's tight vertical padding. */
.data-table .empty-state { min-height: 0; padding: var(--sp-10) var(--sp-6); }

/* ── Error shell (errors/*.html) ────────────────────────────── */
.error-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  text-align: center;
  padding: var(--sp-8);
}
.error-shell h1 {
  font-size: var(--text-6xl);
  font-weight: var(--weight-bold);
  color: var(--clr-primary);
  line-height: 1;
}
.error-shell h2 { font-size: var(--text-2xl); }
.error-shell p  { color: var(--clr-text-muted); max-width: 420px; }
/* The trace id a user quotes to support: one click selects all of it. */
.error-shell .error-reference code { user-select: all; }

/* An alert that carries its own action button (e.g. the rejected-student
   appeal banner): text left, button right, stacking on a narrow screen. */
.alert-with-action {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-3);
}
.alert-with-action p { margin: 0; flex: 1 1 24rem; }
