/* Empty and loading states, Arc-style (piece 18, 2026-10-29).
 *
 * Arc references: empty-state, skeleton. Tokens: arc_tokens.css only.
 *
 * 1. .oc-empty-state — the partial (partials/empty_state.html): an icon in
 *    a soft square, a title, one line, one action; centred, quiet.
 * 2. OcStates.state() output (.oc-state) takes the same voice, and the
 *    portal's per-page empties (.dash-empty, .im-empty, .wl-empty, … — the
 *    list below) take its type, ink and the soft-square mark in place of
 *    polish.css's "◌" glyph. Settings, admin and Helm empties belong to
 *    their own pieces and are not listed. They do not animate: pages that
 *    poll redraw them, and a rise on every poll would read as flicker.
 * 3. Skeletons — OcStates.skeleton() (.oc-sk) and polish.css's .sk-* lines
 *    pulse instead of sweeping, each line a beat after the one above
 *    (Arc's staggered pulse). arc_states.js lets the content that replaces
 *    a skeleton rise 4px into place.
 * PM OS pages (html.page-pmos) keep their own states (D7).
 */

/* ======================================================================
   1. The partial
   ====================================================================== */
.oc-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--arc-space-2);
  padding: var(--arc-space-8) var(--arc-space-4);
  text-align: center;
  color: var(--arc-text-secondary);
  font-size: var(--arc-text-sm);
  line-height: 1.5;
  letter-spacing: var(--arc-tracking);
  animation: oc-arc-rise var(--arc-dur) var(--arc-ease-enter) both;
}
.oc-empty-state__icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--arc-space-1);
  border: 1px solid var(--arc-border-subtle);
  border-radius: var(--arc-radius-card);
  background: var(--arc-surface-muted);
  color: var(--arc-text-secondary);
}
.oc-empty-state__icon .oc-ico { width: 18px; height: 18px; }
.oc-empty-state__title {
  margin: 0;
  font-size: var(--arc-text-md);
  font-weight: var(--arc-weight-strong);
  color: var(--arc-foreground);
}
.oc-empty-state__body {
  margin: 0;
  max-width: 44ch;
}
.oc-empty-state__action { margin-top: var(--arc-space-2); }
.oc-empty-state--compact { padding: var(--arc-space-5) var(--arc-space-3); }
.oc-empty-state--compact .oc-empty-state__icon { width: 32px; height: 32px; border-radius: var(--arc-radius-control); }

/* ======================================================================
   2. OcStates.state() and the per-page empties
   ====================================================================== */
html:not(.page-pmos) body:is(body, #oc-arc):is(body, #oc-arc-2) .oc-state {
  gap: var(--arc-space-1);
  color: var(--arc-text-secondary);
  font-size: var(--arc-text-sm);
  line-height: 1.5;
  letter-spacing: var(--arc-tracking);
}
html:not(.page-pmos) body:is(body, #oc-arc):is(body, #oc-arc-2) .oc-state .oc-state-title {
  margin: 0;
  font-size: var(--arc-text-md);
  font-weight: var(--arc-weight-strong);
  color: var(--arc-foreground);
}
html:not(.page-pmos) body:is(body, #oc-arc):is(body, #oc-arc-2) .oc-state .oc-state-body { margin: 0; max-width: 52ch; }
html:not(.page-pmos) body:is(body, #oc-arc):is(body, #oc-arc-2) .oc-state .oc-state-note {
  font-size: var(--arc-text-xs);
  color: var(--arc-text-muted);
}
html:not(.page-pmos) body:is(body, #oc-arc):is(body, #oc-arc-2) .oc-state .oc-state-actions { gap: var(--arc-space-2); margin-top: var(--arc-space-2); }
html:not(.page-pmos) body:is(body, #oc-arc):is(body, #oc-arc-2) .oc-state--error .oc-state-title { color: var(--arc-danger); }
html:not(.page-pmos) body:is(body, #oc-arc):is(body, #oc-arc-2) .oc-state--center { padding: var(--arc-space-8) var(--arc-space-4); }

html:not(.page-pmos) body:is(body, #oc-arc):is(body, #oc-arc-2) :is(
  .oc-empty, .empty-state, .dash-empty, .im-empty, .wl-empty, .cal-empty,
  .t-empty, .news-empty, .earn-empty, .fund-empty, .chart-empty, .pp-empty,
  .finder-empty, .th-empty, .th-panel-empty, .pw-empty, .pw-th-empty,
  .hd-empty, .ind-empty, .pf-empty, .pf2-empty, .au-empty, .tw-empty,
  .sx-empty, .st-empty, .mdl-empty, .scout-empty, .pub-empty, .an-empty,
  .activity-empty, .thread-empty, .press-empty, .mcb-empty, .bk-empty
) {
  color: var(--arc-text-secondary);
  font-size: var(--arc-text-sm);
  font-style: normal;
  font-weight: var(--arc-weight);
  line-height: 1.5;
  letter-spacing: var(--arc-tracking);
  text-transform: none;
}
html:not(.page-pmos) body:is(body, #oc-arc):is(body, #oc-arc-2) :is(
  .oc-empty, .empty-state, .dash-empty, .im-empty, .wl-empty, .pw-empty,
  .hd-empty, .ind-empty, .pf-empty, .pf2-empty, .au-empty, .sx-empty,
  .mdl-empty, .scout-empty, .pub-empty, .an-empty, .press-empty
) :is(strong, b, h3, h4, .title) {
  color: var(--arc-foreground);
  font-weight: var(--arc-weight-strong);
}
/* polish.css's "◌" becomes Arc's soft square with a hollow mark. */
html:not(.page-pmos) body:is(body, #oc-arc):is(body, #oc-arc-2) :is(
  .dash-empty, .im-empty, .wl-empty, .cal-empty, .t-empty, .news-empty,
  .earn-empty, .fund-empty, .pp-empty, .finder-empty, .th-empty
)::before {
  content: "";
  display: block;
  width: 32px;
  height: 32px;
  margin: 0 auto var(--arc-space-2);
  border: 1px solid var(--arc-border-subtle);
  border-radius: var(--arc-radius-control);
  background:
    radial-gradient(circle at center, transparent 5px, var(--arc-border-strong) 5.5px, var(--arc-border-strong) 6.5px, transparent 7px),
    var(--arc-surface-muted);
}
/* A skeleton sitting inside an empty box is a loading state, not an empty
   one: no mark above it. */
html:not(.page-pmos) body:is(body, #oc-arc):is(body, #oc-arc-2) :is(.dash-empty, .im-empty, .wl-empty, .pp-empty, .th-empty):has(> .oc-sk)::before { content: none; }

/* ======================================================================
   3. Skeletons: a staggered pulse
   ====================================================================== */
html body:is(body, #oc-arc):is(body, #oc-arc-2) :is(.oc-sk-line, .sk-line, .sk-card, .sk-circle, .sk-block) {
  background: var(--arc-press);
  background-image: none;
  border-radius: calc(var(--arc-radius-chip) - 2px);
  animation: oc-arc-pulse 1.6s var(--arc-ease) infinite both;
  animation-delay: calc(var(--i, 0) * 110ms);
}
html body:is(body, #oc-arc):is(body, #oc-arc-2) .sk-circle { border-radius: var(--arc-radius-pill); }
html body:is(body, #oc-arc):is(body, #oc-arc-2) .sk-card,
html body:is(body, #oc-arc):is(body, #oc-arc-2) .sk-block { border-radius: var(--arc-radius-card); }
/* Rows of a table skeleton, and the market timeline's skeleton rows, carry
   their own index; lines inside a .oc-sk take theirs from states.css. */
html body:is(body, #oc-arc):is(body, #oc-arc-2) .is-skeleton .oc-sk-line { animation-delay: calc((var(--row, 0) + var(--i, 0)) * 110ms); }

/* Content that replaces a skeleton rises into place (arc_states.js marks it). */
.oc-arc-rise { animation: oc-arc-rise var(--arc-dur) var(--arc-ease-enter) both; }

@keyframes oc-arc-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .45; }
}
@keyframes oc-arc-rise {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  html body:is(body, #oc-arc):is(body, #oc-arc-2) :is(.oc-sk-line, .sk-line, .sk-card, .sk-circle, .sk-block) { animation: none; }
  .oc-empty-state,
  .oc-arc-rise { animation: none; transform: none; }
}
