@layer components {
  .badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .03em;
    padding: 3px 9px;
    border-radius: var(--r-full);
    line-height: 1.4;
  }
  .badge-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }

  /* Spinning ring for an in-progress badge (e.g. a finalist file still
     processing). Reuses the global `spin` keyframe and inherits the badge's
     text colour, so it matches whatever variant it sits in. */
  .badge-spinner {
    width: 9px;
    height: 9px;
    border: 1.5px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    flex-shrink: 0;
    animation: spin 0.6s linear infinite;
  }

  .badge-neutral  { background: var(--ink-100); color: var(--ink-600); }
  .badge-neutral  .badge-dot { background: var(--ink-400); }
  .badge-forest   { background: var(--forest-100); color: var(--forest-700); }
  .badge-forest   .badge-dot { background: var(--forest-500); }
  .badge-amber    { background: var(--amber-100); color: var(--amber-700); }
  .badge-amber    .badge-dot { background: var(--amber-500); }
  .badge-success  { background: var(--success-50); color: var(--success-600); }
  .badge-success  .badge-dot { background: var(--success-500); }
  .badge-danger   { background: var(--danger-50); color: var(--danger-600); }
  .badge-danger   .badge-dot { background: var(--danger-500); }
  .badge-warning  { background: var(--warning-50); color: var(--warning-500); }
  .badge-warning  .badge-dot { background: var(--warning-500); }
  .badge-dark     { background: var(--ink-950); color: rgba(255,255,255,.85); }

  /* ── Award tiers ──────────────────────────────────────────────────────────
     The participant's final placement, revealed only after winners are
     announced. These are the crowning result, not a status — so they get a
     filled, medal-toned treatment (gold / silver / bronze) that reads as more
     significant than a status badge, and the dot becomes a small star. */
  .badge-tier {
    font-weight: 700;
    letter-spacing: .02em;
    padding: 3px 10px 3px 8px;
    color: #fff;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 1px 2px rgba(20,23,20,.2);
  }
  .badge-tier .badge-dot {
    width: 9px;
    height: 9px;
    border-radius: 0;
    background: rgba(255,255,255,.95);
    /* A five-point star, so the tier badge carries an award mark, not a status dot. */
    clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
    filter: drop-shadow(0 1px 1px rgba(20,23,20,.25));
  }

  /* The three tiers use three distinct hues — warm gold, cool silver, brand
     green — not three shades of metal, so a glance tells them apart. */
  /* Gold — the top prize, from the warm amber primitives. */
  .badge-tier-winner {
    background: linear-gradient(135deg, var(--amber-300), var(--amber-500) 55%, var(--amber-700));
  }
  /* Silver — a cool metallic grey, deliberately away from the warm gold and the green. */
  .badge-tier-runner-up {
    background: linear-gradient(135deg, #C4CDD6, #93A0AC 55%, #616E7C);
  }
  /* Forest — the brand green, a different hue entirely from the gold rather than
     a second warm-brown shade of it. */
  .badge-tier-highly-commended {
    background: linear-gradient(135deg, var(--forest-300), var(--forest-500) 55%, var(--forest-700));
  }

  /* Status pill with large dot */
  .status-pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 13px;
    font-weight: 500;
    color: var(--ink-600);
  }
  .status-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
  }
  .status-dot.pending  { background: var(--amber-500); }
  .status-dot.active   { background: var(--success-500); animation: pulse 2s infinite; }
  .status-dot.complete { background: var(--forest-500); }
  .status-dot.error    { background: var(--danger-500); }
  .status-dot.locked   { background: var(--ink-400); }

  @keyframes pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(39,137,76,.4); }
    50% { box-shadow: 0 0 0 4px rgba(39,137,76,0); }
  }
}
