/* ═══════════════════════════════════════════════════════════════════════════
   OMNIS — Neural × Pulse v3 Signature
   
   The visual DNA that makes OMNIS recognizable:
     • Three-dot crimson bracket next to active elements (logo inheritance)
     • Static neural mesh background (warm radial gradients, no animation)
     • Status dot pulse rhythms (calm 3.5s / warn 2s / urgent 1.2s)
     • Connected-dot heartbeat with ripple
     • AI suggestion bracket purple breath
     • Urgent row subtle tint for peripheral awareness
     • Focus rings, row hovers, button lifts
   
   All motion honors prefers-reduced-motion (handled in omnis-theme.css).
   
   Convention:
     • Classes prefixed .nx-* are NXP v3 specific
     • Global enhancements apply via semantic classes (tbody tr[data-status])
     • Pages opt OUT with data-no-nxp-signature="true" on <html> or <body>
   =========================================================================== */


/* ═══════════════════════════════════════════════════════════════════
   NEURAL MESH BACKGROUND
   Two warm radial gradients + subtle scattered points.
   Pins to <body> via ::before and ::after (pages don't need to add markup).
   ═══════════════════════════════════════════════════════════════════ */
body {
  position: relative;
}
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(ellipse 80% 60% at 15% 10%, rgba(232, 35, 74, .05) 0%, transparent 50%),
    radial-gradient(ellipse 70% 50% at 85% 90%, rgba(159, 108, 247, .04) 0%, transparent 50%);
}
[data-theme="light"] body::before {
  background:
    radial-gradient(ellipse 80% 60% at 15% 10%, rgba(216, 35, 74, .03) 0%, transparent 50%),
    radial-gradient(ellipse 70% 50% at 85% 90%, rgba(110, 64, 204, .025) 0%, transparent 50%);
}

/* Any page that opts out (e.g. public marketing, login, 3D twin viewport) */
html[data-no-nxp-signature="true"] body::before,
body[data-no-nxp-signature="true"]::before {
  display: none;
}


/* ═══════════════════════════════════════════════════════════════════
   THREE-DOT BRACKET SIGNATURE
   Appears to the left of elements with .nx-brand or on page titles.
   Inherits from the OMNIS logo's dot language.
   ═══════════════════════════════════════════════════════════════════ */
.nx-brand {
  position: relative;
  padding-left: 1rem;
}
.nx-brand::before {
  content: '';
  position: absolute;
  left: 0;
  top: 52%;
  transform: translateY(-50%);
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--c-text);
  box-shadow:
    0 -7px 0 var(--c-text),
    0 7px 0 var(--c-text);
}

/* Apply automatically to H1 inside common page-header patterns */
h1.nx-auto,
.page-hd h1,
.panel-header > .panel-title:first-child.nx-auto {
  position: relative;
  padding-left: 1rem;
}
h1.nx-auto::before,
.page-hd h1::before,
.panel-header > .panel-title:first-child.nx-auto::before {
  content: '';
  position: absolute;
  left: 0;
  top: 52%;
  transform: translateY(-50%);
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--c-text);
  box-shadow:
    0 -7px 0 var(--c-text),
    0 7px 0 var(--c-text);
}


/* ═══════════════════════════════════════════════════════════════════
   PANEL SIGNATURE — Short crimson hairline on the left edge of major panels
   ═══════════════════════════════════════════════════════════════════ */
.nx-panel {
  position: relative;
}
.nx-panel::before {
  content: '';
  position: absolute;
  top: var(--sp-7, 1.4rem);
  left: 0;
  width: 2px;
  height: 1rem;
  background: var(--c-text);
  border-radius: 0 2px 2px 0;
  opacity: .7;
}


/* ═══════════════════════════════════════════════════════════════════
   KPI CARD — subtle hairline on top-left, expands on hover
   ═══════════════════════════════════════════════════════════════════ */
.nx-kpi {
  position: relative;
  overflow: hidden;
  transition: transform var(--dur-med) var(--ease-soft),
              border-color var(--dur-fast),
              box-shadow var(--dur-med) var(--ease-soft);
}
.nx-kpi::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 24px;
  height: 1px;
  background: var(--c-text);
  opacity: .5;
  transition: width var(--dur-slow) var(--ease-soft), opacity var(--dur-fast);
}
.nx-kpi:hover {
  transform: translateY(-2px);
  border-color: var(--bh);
  box-shadow: var(--sh-3);
}
.nx-kpi:hover::before {
  width: 50%;
  opacity: 1;
}
.nx-kpi[data-attention]::before {
  width: 50%;
  opacity: 1;
}
.nx-kpi[data-attention] .kpi-value,
.nx-kpi[data-attention] .nx-kpi-value {
  color: var(--c-text);
}


/* ═══════════════════════════════════════════════════════════════════
   CONNECTED / LIVE INDICATOR
   Green dot + 3s heartbeat + ripple ring
   ═══════════════════════════════════════════════════════════════════ */
.nx-live-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--g);
  position: relative;
  animation: nxHeartbeat 3s ease-in-out infinite;
}
.nx-live-dot::before {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  border: 1px solid var(--g);
  opacity: 0;
  animation: nxHeartbeatRing 3s ease-out infinite;
}
@keyframes nxHeartbeat {
  0%, 100% { transform: scale(1);   box-shadow: 0 0 4px rgba(45, 212, 168, .4); }
  50%      { transform: scale(1.15);box-shadow: 0 0 8px rgba(45, 212, 168, .7); }
}
@keyframes nxHeartbeatRing {
  0%   { transform: scale(1);   opacity: .5; }
  100% { transform: scale(2.4); opacity: 0; }
}


/* ═══════════════════════════════════════════════════════════════════
   STATUS PILLS + PULSE (calibrated by severity)
   Convention: any .pill.ok / .pill.warn / .pill.err gets its dot pulsing.
   Classes apply without page changes.
   ═══════════════════════════════════════════════════════════════════ */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px 3px 8px;
  border-radius: var(--r-full);
  font-size: var(--fs-2);
  font-weight: var(--fw-semi);
  border: 1px solid transparent;
  font-family: inherit;
  letter-spacing: .02em;
}
.pill::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
  position: relative;
}
.pill.ok   { background: var(--gb); color: var(--g);  border-color: rgba(45,212,168,.22); }
.pill.warn { background: var(--ab); color: var(--am); border-color: rgba(229,160,17,.22); }
.pill.err  { background: var(--rb); color: var(--rd); border-color: rgba(255,107,107,.25); }

.pill.ok::before   { animation: nxDotCalm   3.5s ease-in-out infinite; }
.pill.warn::before { animation: nxDotWarn   2s   ease-in-out infinite; }
.pill.err::before  { animation: nxDotUrgent 1.2s ease-in-out infinite; }
@keyframes nxDotCalm {
  0%, 100% { box-shadow: 0 0 0 0 rgba(45,212,168,0); opacity: .9; }
  50%      { box-shadow: 0 0 0 3px rgba(45,212,168,.15); opacity: 1; }
}
@keyframes nxDotWarn {
  0%, 100% { box-shadow: 0 0 0 0 rgba(229,160,17,0); opacity: .9; }
  50%      { box-shadow: 0 0 0 4px rgba(229,160,17,.18); opacity: 1; }
}
@keyframes nxDotUrgent {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,107,107,0); opacity: 1; transform: scale(1); }
  50%      { box-shadow: 0 0 0 5px rgba(255,107,107,.22); opacity: 1; transform: scale(1.1); }
}


/* ═══════════════════════════════════════════════════════════════════
   ROW HOVER + URGENT ROW TINT (for tables)
   Apply via <tr data-status="urgent"> or legacy .urgent class.
   ═══════════════════════════════════════════════════════════════════ */
tbody tr {
  transition: background var(--dur-fast);
  position: relative;
}
tbody tr:hover {
  background: rgba(232, 35, 74, .04);
  cursor: pointer;
}
[data-theme="light"] tbody tr:hover {
  background: rgba(216, 35, 74, .04);
}
tbody tr td:first-child {
  position: relative;
}
tbody tr:hover td:first-child::before {
  content: '';
  position: absolute;
  left: -.25rem;
  top: 20%;
  bottom: 20%;
  width: 2px;
  background: var(--c-text);
  border-radius: 0 2px 2px 0;
}
tbody tr[data-status="urgent"],
tbody tr.urgent {
  background: linear-gradient(90deg, rgba(232, 35, 74, .035) 0%, rgba(232, 35, 74, .015) 100%);
}
[data-theme="light"] tbody tr[data-status="urgent"],
[data-theme="light"] tbody tr.urgent {
  background: linear-gradient(90deg, rgba(216, 35, 74, .05) 0%, rgba(216, 35, 74, .02) 100%);
}


/* ═══════════════════════════════════════════════════════════════════
   AI SUGGESTION CARD — purple bracket with slow breath
   Apply .nx-ai-card or .card.ai (either works)
   ═══════════════════════════════════════════════════════════════════ */
.nx-ai-card,
.card.ai,
.card[data-ai="true"] {
  position: relative;
  background: linear-gradient(180deg, rgba(159, 108, 247, .05) 0%, var(--s1) 50%);
  border: 1px solid var(--b);
  border-radius: var(--r-3);
  padding: var(--sp-5) var(--sp-6) var(--sp-5) var(--sp-7);
  box-shadow: var(--sh-2);
  transition: transform var(--dur-med) var(--ease-soft), border-color var(--dur-fast);
}
.nx-ai-card:hover,
.card.ai:hover,
.card[data-ai="true"]:hover {
  transform: translateY(-1px);
  border-color: rgba(159, 108, 247, .25);
}
.nx-ai-card::before,
.card.ai::before,
.card[data-ai="true"]::before {
  content: '';
  position: absolute;
  top: var(--sp-5);
  left: 0;
  width: 2px;
  height: 1.2rem;
  background: var(--p);
  border-radius: 0 2px 2px 0;
  animation: nxAiBreath 4s ease-in-out infinite;
}
@keyframes nxAiBreath {
  0%, 100% { box-shadow: 0 0 0 0 rgba(159, 108, 247, 0);   opacity: .75; }
  50%      { box-shadow: 0 0 8px 0 rgba(159, 108, 247, .55); opacity: 1; }
}


/* ═══════════════════════════════════════════════════════════════════
   BUTTON INTERACTION
   Apply to .btn-primary or standalone buttons with .nx-btn
   ═══════════════════════════════════════════════════════════════════ */
.nx-btn,
.btn-primary {
  transition: transform var(--dur-fast) var(--ease-soft),
              box-shadow var(--dur-med),
              background var(--dur-fast);
  box-shadow: 0 2px 8px rgba(232, 35, 74, .25);
}
.nx-btn:hover,
.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(232, 35, 74, .4);
}
.nx-btn:active,
.btn-primary:active {
  transform: translateY(0);
  transition: transform .05s;
}
.nx-btn:focus-visible,
.btn-primary:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--cf), 0 6px 18px rgba(232, 35, 74, .4);
}


/* ═══════════════════════════════════════════════════════════════════
   INPUT FOCUS RING (soft crimson halo)
   ═══════════════════════════════════════════════════════════════════ */
.nx-input,
input[type="text"].input,
input[type="search"].input,
input.nx-input {
  transition: border-color var(--dur-fast), box-shadow var(--dur-med);
}
.nx-input:focus,
input.input:focus,
input.nx-input:focus {
  border-color: rgba(232, 35, 74, .4);
  box-shadow: 0 0 0 3px var(--cf);
  outline: none;
}


/* ═══════════════════════════════════════════════════════════════════
   PAGE CONTENT BELOW THE MESH
   Any page that wants its content ABOVE the mesh z:0 can add .nx-content
   or the mesh is z:0 so most positioned content already sits above it.
   ═══════════════════════════════════════════════════════════════════ */
.nx-content,
.app-shell,
.main-wrap,
.page-wrap {
  position: relative;
  z-index: 1;
}
