/* =========================================================
   PHASE 7 FRONT-END / P0.5 — gx-glyphs.css
   The ONE source of the task-status glyph grammar (○ pending / ● making / ✓ ready / ⚠ failed) and the cost/path
   grammar ($0 editor vs paid AI) — promoted out of the today-inline strings (the chat ○●✓⚠ map + the producerTrace
   $0-vs-paid derivation) so chat, the Stage, the producer-trace board, and the future enterprise dashboards render the
   SAME signal identically. The colour mapping lives ONCE here (sourced from the P0.3 tokens --glyph-* / --cost-*), never
   re-declared per component.

   A11Y LAW: every glyph is distinguishable by SHAPE (the ::before content character), NOT colour alone — colour-blind
   safe. The colour is a reinforcement, not the signal. Each glyph carries aria-hidden (it is decorative); the CONSUMER
   MUST pair it with a text label or an aria-label on the parent (e.g. <span class="gx-glyph gx-glyph--making"
   aria-hidden="true"></span><span>Rendering shot 3</span>) so a screen reader gets the state in words. Every content
   char carries the U+FE0E text variation selector + font-variant-emoji:text so a browser NEVER substitutes a multicolour
   emoji (which would ignore the token colour) — the marks stay monochrome and obey --glyph-* / --cost-*.

   ADDITIVE + INERT: nothing consumes these classes until P5 adoption -> flag-off / pre-adoption byte-identical. The
   in-flight shimmer reuses gx-motion.css's gxm-shimmer keyframe + --gx-dur-shimmer (so the single prefers-reduced-motion
   guard there covers it; this file also resets it explicitly, below).
   ========================================================= */

.gx-glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1em;
  height: 1em;
  flex: 0 0 auto;
  font-variant-emoji: text;   /* render ○●✓⚠ as glyphs, never colour-emoji */
  line-height: 1;
}
.gx-glyph::before { display: inline-block; }

/* SHAPE is the signal (the char + U+FE0E text selector); colour reinforces. */
.gx-glyph--pending::before { content: '\25CB\FE0E'; color: var(--glyph-pending); }   /* ○ queued */
.gx-glyph--making::before  { content: '\25CF\FE0E'; color: var(--glyph-making);  animation: gxm-shimmer var(--gx-dur-shimmer) var(--ease-in-out) infinite; }  /* ● in-flight */
.gx-glyph--ready::before   { content: '\2713\FE0E'; color: var(--glyph-ready); }     /* ✓ secured */
.gx-glyph--failed::before  { content: '\26A0\FE0E'; color: var(--glyph-failed); }    /* ⚠ failed */

/* COST / PATH — $0 editor (a muted "local" chip) vs paid AI (brand-tinted, with a spark mark). Shape-distinct via the
   leading mark, not colour alone. font-variant-emoji:text forces the ⚡ (U+26A1, emoji-default) monochrome so it obeys
   the token colour, matching .gx-glyph. */
.gx-cost {
  display: inline-flex;
  align-items: center;
  gap: .35em;
  font-family: var(--font-mono);
  font-size: .82em;
  border-radius: 999px;
  padding: .12em .6em;
  white-space: nowrap;
  font-variant-emoji: text;
}
.gx-cost--free {
  color: var(--cost-free);
  border: .5px solid var(--hairline-neon);
}
.gx-cost--free::before { content: '\26A1\FE0E'; }   /* ⚡ instant / local — the $0 editor mark */
.gx-cost--paid {
  color: var(--cost-paid);
  background: var(--reason-tint-producer);
}
.gx-cost--paid::before { content: '\2726\FE0E'; }   /* ✦ spark — the paid-AI mark */

/* under reduced motion the in-flight dot stops pulsing but stays fully visible (the static end-state) — covered by
   gx-motion.css's guard, and reset explicitly here so the dot is correct even if gx-motion.css is somehow absent. */
@media (prefers-reduced-motion: reduce) {
  .gx-glyph--making::before { animation: none; opacity: 1; }
}
