/* Thinking orbs — styles for thinking-orbs.js (added 2026-09-29, Joseph's Task P).
   Every rule is keyed on a data-orb attribute that the script sets, so if the script is switched off
   (localStorage 'orbs' = 'off') nothing here has any effect, except the empty (transparent) start-up splash box. */

.orb-cv { display: block; pointer-events: none; }

/* Loading: the orb replaces the Material spinner arc. The spinner element keeps its size and role; only its drawing is hidden. */
mat-spinner[data-orb="spinner"],
mat-progress-spinner[data-orb="spinner"] { position: relative; }
mat-spinner[data-orb="spinner"] > :not(canvas),
mat-progress-spinner[data-orb="spinner"] > :not(canvas) { display: none !important; }
.orb-spin { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Empty states: a slow ring instead of a text-only message or a static icon. */
.orb-inline { display: inline-block; width: 20px; height: 20px; margin-block: -3px 0; margin-inline: 0 8px; vertical-align: middle; }
mat-icon[data-orb="empty-icon"] { position: relative; -webkit-text-fill-color: transparent !important; }   /* glyph hidden; the icon's own colour is left alone so the orb can take its tint */
.orb-icon { position: absolute; inset: 0; width: 100%; height: 100%; }

/* AI chat button: the orb replaces the robot glyph while the panel is closed; the chevron returns when it is open. */
.ai-chatbot-fab[data-orb="fab"] { position: relative; }
.ai-chatbot-fab[data-orb="fab"] > mat-icon { opacity: 0; transition: opacity var(--ap-dur-state, .2s) ease; }
.ai-chatbot-fab-wrapper.panel-open .ai-chatbot-fab[data-orb="fab"] > mat-icon { opacity: 1; }
.orb-fab { position: absolute; left: 50%; top: 50%; width: 44px; height: 44px; transform: translate(-50%, -50%); transition: opacity var(--ap-dur-state, .2s) ease; }
.ai-chatbot-fab-wrapper.panel-open .orb-fab { opacity: 0; }
.ai-chatbot-fab-wrapper:has(.ai-chatbot-fab[data-orb="fab"]) .ai-chatbot-fab-pulse { display: none; }

/* Settings-panel ticker placeholder (waiting for market data): a listening orb replaces the pulsing dot. */
.hub-tape-dot[data-orb="tape"] { position: relative; display: inline-block; width: 18px; height: 18px; background: none; animation: none; vertical-align: middle; }
.orb-tape { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Ticket status pills: a small orb in the pill's own colour. */
.badge[data-orb="status"] { display: inline-flex; align-items: center; gap: 6px; }
.orb-status { width: 14px; height: 14px; flex: none; }

/* Login: a hero orb above the heading, and a large faint orb behind the frosted card. */
.auth-content [data-orb="hero"] > .orb-hero { display: block; width: 64px; height: 64px; margin: 0 auto 10px; }
.dark-image[data-orb="ambient"] { position: relative; overflow: hidden; }
.dark-image[data-orb="ambient"] > .row { position: relative; z-index: 1; }
.orb-ambient { position: absolute; left: 50%; top: 50%; width: min(520px, 90vmin); height: min(520px, 90vmin); transform: translate(-50%, -50%); opacity: .34; z-index: 0; }

/* Start-up splash: drawn as soon as the browser has parsed it (the script does this before the bundle runs) and shown inside <app-root> until Angular replaces it. */
.orb-splash { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 2147483000; }
.orb-splash-cv { width: 64px; height: 64px; }
