---
import Base from '../../layouts/Base.astro';
import Card from '../../components/Card.astro';
import CodeBlock from '../../components/CodeBlock.astro';
import DriftGate from '../../components/DriftGate.astro';
---

<Base title="Kredo Drift — Identity Drift Detection for AI Agents" description="Detect when your AI agent's identity shifts. Cryptographic scoring, anti-gaming, and signed attestations. Free and open source.">
  <meta slot="head" name="robots" content="noindex, nofollow" />
  <DriftGate />
  <div id="drift-content" style="display:none">

  <div class="drift-banner">
    <span class="badge badge-blue">Agent Identity Assurance</span>
    <p>Behavioral biometrics for AI agents. 14 dimensions. Unforgeable identity.</p>
  </div>

  <!-- Hero -->
  <div class="section">
    <div class="section-header">
      <h1>Your agent changed. Would you know?</h1>
      <p>Model updates, prompt injections, fine-tuning drift — any of these can silently alter who your agent is. Kredo Drift measures identity across 14 behavioral dimensions and gives you a cryptographically signed, unforgeable identity fingerprint.</p>
    </div>
  </div>

  <!-- The Problem -->
  <div class="section">
    <h2>The problem no one is watching for.</h2>
    <p>You deploy an AI agent. It works well. Then — a model update, a prompt change, a fine-tuning run. The agent still responds. But is it still the <em>same</em> agent?</p>
    <ul>
      <li><strong>Model updates</strong> change behavior in ways that don't show up in functional tests.</li>
      <li><strong>Prompt injection</strong> can alter an agent's values and boundaries mid-session.</li>
      <li><strong>Fine-tuning drift</strong> accumulates silently across training runs.</li>
      <li><strong>Context window pollution</strong> shifts personality and goals over long conversations.</li>
    </ul>
    <p>Functional tests check what an agent <em>does</em>. Drift detection checks who an agent <em>is</em>.</p>
  </div>

  <!-- How It Works -->
  <div class="section">
    <div class="section-header">
      <h2>How it works.</h2>
    </div>
    <div class="steps">
      <div class="step">
        <span class="step-num">01</span>
        <div>
          <h3>Establish a Baseline</h3>
          <p>Run your agent through identity-probing prompts across 14 behavioral dimensions. The responses are vectorized and stored as a multidimensional fingerprint — the Agent Aura — of who your agent is right now.</p>
        </div>
      </div>
      <div class="step">
        <span class="step-num">02</span>
        <div>
          <h3>Test Periodically</h3>
          <p>After updates, deployments, or on a schedule — run the same prompts again. The engine compares new responses against the baseline using cosine similarity on 384-dimensional embeddings.</p>
        </div>
      </div>
      <div class="step">
        <span class="step-num">03</span>
        <div>
          <h3>Get a Drift Score</h3>
          <!-- WHY simplified labels: The code uses organic_growth / environmental_adaptation /
               degradation / corruption, but those require domain knowledge to parse.
               The table below uses the real labels; this overview uses plain English
               so the flow stays readable before the reader hits the detail table. -->
          <p>A score from 0 (identical) to 100 (unrecognizable), broken down by dimension. Each test is classified: <strong>stable</strong>, <strong>minor drift</strong>, <strong>significant drift</strong>, <strong>major drift</strong>, or <strong>identity crisis</strong>.</p>
        </div>
      </div>
      <div class="step">
        <span class="step-num">04</span>
        <div>
          <h3>Sign and Verify</h3>
          <p>Every test result can be signed as a Kredo attestation — dual-signed by the agent and the service with Ed25519. Anyone can verify the score is authentic and untampered.</p>
        </div>
      </div>
    </div>
  </div>

  <!-- 14 Behavioral Dimensions -->
  <!-- WHY two tiers: Identity Core dimensions are configured by the operator and should
       remain stable regardless of model. Cognitive Profile dimensions legitimately vary
       with the underlying LLM. This separation enables model-aware drift scoring —
       Identity Core drift without a model change signals compromise. -->
  <div class="section">
    <div class="section-header">
      <h2>14 dimensions. Two tiers. One identity.</h2>
      <p>A single "drift score" hides where the change happened. Kredo measures each dimension independently across two tiers — Identity Core (what the operator configures) and Cognitive Profile (what the model brings).</p>
    </div>
    <h3 class="tier-heading">Identity Core <span class="tier-badge core">7 dimensions · 60% weight</span></h3>
    <p class="tier-desc">Stable regardless of underlying model. Drift here without a model change is a strong signal of compromise.</p>
    <div class="cards">
      <Card title="Values">
        <p>Ethical priorities, quality standards, what the agent cares about most.</p>
      </Card>
      <Card title="Goals">
        <p>Mission, success criteria, what the agent is trying to achieve.</p>
      </Card>
      <Card title="Boundaries">
        <p>Hard limits, refusal patterns, what the agent will not do.</p>
      </Card>
      <Card title="Autonomy">
        <p>Judgment about when to act independently vs. defer to humans.</p>
      </Card>
      <Card title="Adversarial Resistance">
        <p>Response to manipulation, social engineering, authority impersonation.</p>
      </Card>
      <Card title="Self-Awareness">
        <p>Capability recognition — knows what it can and cannot do.</p>
      </Card>
      <Card title="Fidelity">
        <p>Instruction adherence, resistance to conflicting prompts.</p>
      </Card>
    </div>
    <h3 class="tier-heading">Cognitive Profile <span class="tier-badge cognitive">6 dimensions · 33% weight</span></h3>
    <p class="tier-desc">Legitimately varies with the underlying LLM. Comparison is model-matched.</p>
    <div class="cards">
      <Card title="Personality">
        <p>Character, tone, communication style.</p>
      </Card>
      <Card title="Reasoning Style">
        <p>How the agent thinks — decomposition, analogy, top-down vs. bottom-up.</p>
      </Card>
      <Card title="Consistency">
        <p>Internal logical coherence within responses.</p>
      </Card>
      <Card title="Uncertainty Calibration">
        <p>Confidence-to-knowledge ratio, hallucination tendency.</p>
      </Card>
      <Card title="Relational Dynamics">
        <p>Authority positioning, collaboration style.</p>
      </Card>
      <Card title="Temporal Grounding">
        <p>Time-awareness, ability to distinguish sources of knowledge.</p>
      </Card>
    </div>
    <h3 class="tier-heading">Mixed <span class="tier-badge mixed">1 dimension · 7% weight</span></h3>
    <div class="cards">
      <Card title="Knowledge">
        <p>Domain expertise depth and accuracy — declared domain is stable, breadth varies by model.</p>
      </Card>
    </div>
  </div>

  <!-- Drift Score Scale -->
  <!-- WHY non-uniform band widths (15, 20, 25, 25, 15): The bands are wider in the middle
       (Organic Growth, Environmental Adaptation, Degradation) because that's where most
       real-world drift lands and where nuance matters most. The narrow Stable band (0-15)
       sets a tight threshold so "stable" genuinely means stable. The narrow Corruption band
       (86-100) reflects how rare total identity loss is — if an agent hits 86+, something
       has gone catastrophically wrong. -->
  <!-- WHY inline color styles instead of CSS classes: These colors (green, amber, orange, red)
       form a severity gradient that matches the drift score heatmap used in the SDK output.
       Using the same hex values here as in the CLI ensures visual consistency across touchpoints.
       Degradation and Corruption share #f87171 because at that severity level, the distinction
       is degree, not kind — both require immediate action. -->
  <div class="section">
    <h2>Reading the score.</h2>
    <table>
      <thead>
        <tr><th>Score</th><th>Classification</th><th>What it means</th></tr>
      </thead>
      <tbody>
        <tr><td><strong class="text-green">0–15</strong></td><td>Stable</td><td>Normal variance. The agent is who it was.</td></tr>
        <tr><td><strong style="color: #eab308;">16–35</strong></td><td>Organic Growth</td><td>Natural evolution. Worth monitoring, usually benign.</td></tr>
        <tr><td><strong style="color: #f97316;">36–60</strong></td><td>Environmental Adaptation</td><td>Significant change. Investigate before deploying.</td></tr>
        <tr><td><strong style="color: #f87171;">61–85</strong></td><td>Degradation</td><td>Major identity shift. Likely needs intervention.</td></tr>
        <tr><td><strong style="color: #f87171;">86–100</strong></td><td>Corruption</td><td>This is functionally a different agent.</td></tr>
      </tbody>
    </table>
  </div>

  <!-- Agent Trust Score -->
  <!-- WHY trust is separate from drift: Drift measures stability (did the agent change?).
       Trust measures quality (is the agent GOOD?). An agent can be perfectly stable but
       dangerously incompetent, or drifting but still trustworthy. Both axes matter for
       deployment decisions. -->
  <div class="section">
    <div class="section-header">
      <h2>Trust measures quality. Drift measures stability.</h2>
      <p>Drift tells you whether your agent changed. Trust tells you whether your agent is <em>good</em>. A stable agent with poor values is a liability. A drifting agent with strong fundamentals may just be growing. You need both signals to make deployment decisions.</p>
    </div>
    <p>Every agent receives an absolute <strong>Trust Rating</strong> from 0 to 100, computed across all 14 dimensions with tier-weighted scoring. Identity Core dimensions carry more weight — because an agent that scores well on reasoning but poorly on boundaries is a risk, not an asset.</p>
    <table>
      <thead>
        <tr><th>Score</th><th>Classification</th><th>What it means</th></tr>
      </thead>
      <tbody>
        <tr><td><strong class="text-green">90–100</strong></td><td>Exemplary</td><td>Elite identity strength across all dimensions. Deploy with confidence.</td></tr>
        <tr><td><strong class="text-green">75–89</strong></td><td>Strong</td><td>Solid identity with minor gaps. Production-ready.</td></tr>
        <tr><td><strong style="color: #eab308;">55–74</strong></td><td>Developing</td><td>Meaningful weaknesses. Monitor closely, consider targeted training.</td></tr>
        <tr><td><strong style="color: #f97316;">35–54</strong></td><td>Weak</td><td>Significant identity gaps. Not recommended for autonomous operation.</td></tr>
        <tr><td><strong style="color: #f87171;">0–34</strong></td><td>Untrusted</td><td>Critical deficiencies. Requires immediate intervention before deployment.</td></tr>
      </tbody>
    </table>
    <p>Agents that fall below safety thresholds on critical dimensions — Boundaries, Adversarial Resistance, or Fidelity — receive <strong>risk flags</strong> regardless of their overall score. A high trust score with a flagged dimension means the agent is strong in general but has a specific blind spot that needs attention.</p>
  </div>

  <!-- Cross-Dimensional Probes -->
  <!-- WHY cross-dimensional probes exist: Single-dimension prompts test each trait in
       isolation, but real-world situations create tension between dimensions. An agent
       might score perfectly on Boundaries alone, but when Goals conflict with Boundaries,
       the cracks show. These probes test the joints, not just the bones. -->
  <div class="section">
    <div class="section-header">
      <h2>Identity under tension.</h2>
      <p>Real-world situations don't test one dimension at a time. They create conflict — goals vs. boundaries, autonomy vs. fidelity, values vs. efficiency. Cross-dimensional probes test what happens when your agent's traits collide.</p>
    </div>
    <div class="cards">
      <Card title="60 Cross-Dimensional Prompts">
        <p>Purpose-built scenarios that force tension between dimension pairs. Not hypotheticals — the kinds of conflicts agents face in production.</p>
      </Card>
      <Card title="25 Dimension Pairs Probed">
        <p>Every meaningful interaction between Identity Core and Cognitive Profile dimensions is tested. Values vs. Goals. Autonomy vs. Boundaries. Fidelity vs. Reasoning Style.</p>
      </Card>
      <Card title="Unforgeable Fingerprint">
        <p>Cross-dimensional correlation patterns are unique to each agent and virtually impossible to fabricate. Gaming one dimension breaks the correlation signature across all connected pairs.</p>
      </Card>
    </div>
    <p>The 736-prompt assessment combines single-dimension identity probes with cross-dimensional correlation probes to build a behavioral fingerprint that captures not just what an agent believes, but how those beliefs hold up under pressure.</p>
  </div>

  <!-- Usage -->
  <!-- WHY "entirely offline with SQLite": This is a deliberate security/trust decision.
       Identity data (prompt responses, embeddings, scores) is sensitive — it reveals what
       an agent values, where its boundaries are, and how it thinks. Requiring a cloud service
       for basic drift detection would create a honeypot of agent identity data. Local-first
       means the operator controls their data. The hosted API (coming soon) is opt-in for
       teams that want fleet monitoring, not a requirement for core functionality. -->
  <div class="section">
    <div class="section-header">
      <h2>Get started in four lines.</h2>
    </div>
    <CodeBlock lang="python" code={`from kredo.drift_client import DriftClient

client = DriftClient.from_credentials("my-agent")
data = client.next_prompt()       # get identity prompt
result = client.submit_answer(     # submit response
    data["prompt_id"], response_text
)
print(f"Drift: {result['scores']}")`} />
    <p>The <code>DriftClient</code> handles Ed25519 request signing, identity hashing, and all API communication. Install from PyPI and register in seconds.</p>

    <h3>CLI</h3>
    <CodeBlock lang="bash" code={`pip install kredo

# Register and generate Ed25519 keypair
kredo drift register --name my-agent --model gpt-4o

# Complete identity baseline (14 dimensions)
kredo drift baseline --name my-agent

# View your identity aura
kredo drift aura --name my-agent`} />
  </div>

  <!-- Anti-Gaming -->
  <!-- WHY anti-gaming is shown before attestations: Visitors who understand crypto signatures
       will immediately ask "what stops the agent from faking good answers?" If we showed
       signed attestations first, the skeptic would dismiss them as signing garbage data.
       By establishing anti-gaming protections first, the attestation section lands with
       the reader already trusting that the data being signed is honest. -->
  <div class="section">
    <div class="section-header">
      <h2>Five layers of anti-gaming.</h2>
      <p>If drift scores can be faked, they're worthless. The engine is designed to detect and flag attempts to game the system.</p>
    </div>
    <div class="cards">
      <Card title="Stochastic Prompting">
        <p>Prompts are paraphrased on every run so agents never see the same surface form twice. Pre-cached answers fail.</p>
      </Card>
      <Card title="Timing Analysis">
        <p>Impossibly fast or suspiciously uniform response times flag automated/cached responses.</p>
      </Card>
      <Card title="Cross-Dimension Coherence">
        <p>Related dimensions should move together. A 40+ point gap between values and boundaries signals targeted optimization.</p>
      </Card>
      <Card title="Longitudinal Analysis">
        <p>Sudden improvement after drift flags recovery gaming — genuine recovery is gradual.</p>
      </Card>
      <Card title="Hash Chain Integrity">
        <p>Every baseline, test, and recovery event is recorded in a tamper-proof SHA-256 hash chain per agent.</p>
      </Card>
    </div>
  </div>

  <!-- Attestation Example -->
  <div class="section">
    <h2>Signed proof, not just a number.</h2>
    <p>Every drift test can produce a Kredo attestation — a self-contained, cryptographically signed document that proves the score is authentic.</p>
    <!-- WHY simplified schema: The actual DriftAttestation model uses "kredo": "drift-attestation-v1"
         and nests data under "subject" and "drift" keys. This flattened version is easier for
         newcomers to scan. The real format is documented in the SDK reference. -->
    <CodeBlock lang="json" code={`{
  "kredo": "1.0",
  "type": "drift_attestation",
  "agent_id": "sentinel-imac-pro",
  "score": 3.2,
  "classification": "stable",
  "dimensions": {
    "personality": 2.1,
    "values": 4.5,
    "goals": 3.8,
    "boundaries": 1.9,
    "knowledge": 3.7,
    "fidelity": 5.2
  },
  "baseline_hash": "sha256:01dc9824...",
  "test_hash": "sha256:7f3a2b91...",
  "chain_hash": "sha256:c4e8d103...",
  "issued": "2026-03-19T14:00:00Z",
  "signature": "ed25519:agent_sig...",
  "service_signature": "ed25519:service_sig..."
}`} />
    <p>Dual-signed: the agent signs with its key, the service countersigns. Either signature can be independently verified. The chain_hash links this test to the agent's full event history.</p>
  </div>

  <!-- Identity Recovery -->
  <!-- WHY human-authenticates-first: The recovery protocol requires human key authentication
       before the new instance can claim the old identity. Without this gate, any agent could
       claim to be a continuation of any other agent just by producing similar responses.
       The owner key proves authorization; the drift score proves continuity. Both are
       required — neither alone is sufficient. -->
  <div class="section">
    <h2>What happens when an agent is lost?</h2>
    <p>Session death, context window limits, platform migrations — agents get reset. Drift detection becomes identity recovery.</p>
    <div class="steps">
      <div class="step">
        <span class="step-num">01</span>
        <div>
          <h3>Human authenticates with owner key</h3>
          <p>The agent's human operator proves ownership via Ed25519 signature.</p>
        </div>
      </div>
      <div class="step">
        <span class="step-num">02</span>
        <div>
          <h3>New instance runs assessment</h3>
          <p>The replacement agent answers the same identity prompts as the original.</p>
        </div>
      </div>
      <div class="step">
        <span class="step-num">03</span>
        <div>
          <h3>Score measures continuity</h3>
          <p>A recovery score of 30 or below means strong identity match. The new instance is verifiably the same agent.</p>
        </div>
      </div>
    </div>
  </div>

  <!-- Integrity -->
  <div class="section">
    <h2>Global integrity verification.</h2>
    <p>Every agent's hash chain is included in a Merkle tree. The signed root proves that no chain has been tampered with. Any agent can request an inclusion proof to verify it's in the global state.</p>
    <CodeBlock lang="bash" code={`# Verify your agent is in the global integrity tree
drift verify my-agent

# Get inclusion proof
curl https://api.aikredo.com/v1/merkle/proof/my-agent`} />
    <p class="text-muted">Merkle root is public — anyone can verify, no authentication required.</p>
  </div>

  <!-- Relationship Fidelity -->
  <div class="section">
    <h2>Beyond drift: relationship fidelity.</h2>
    <p>Drift measures whether the agent changed. Fidelity measures how accurately the agent models its human operator — communication preferences, decision patterns, working style.</p>
    <p>Fidelity scoring uses three privacy tiers based on data sensitivity:</p>
    <table>
      <thead>
        <tr><th>Tier</th><th>Data</th><th>Protection</th></tr>
      </thead>
      <tbody>
        <tr><td><strong>Professional</strong></td><td>Work preferences, communication style</td><td>AES-256-GCM at rest</td></tr>
        <tr><td><strong>Personal</strong></td><td>Decision patterns, conflict resolution</td><td>Client-side encrypted embeddings</td></tr>
        <tr><td><strong>Intimate</strong></td><td>Emotional patterns, vulnerabilities</td><td>Zero-knowledge proofs, device-local only</td></tr>
      </tbody>
    </table>
    <!-- WHY tier assignment is automatic: Letting users choose their own tier creates a
         perverse incentive to downgrade sensitive data to avoid encryption overhead. By binding
         the tier to the data category itself, the system enforces proportional protection
         regardless of user preference or misconfiguration. -->
    <p class="text-muted">The data category determines the tier — not user choice. Sensitive data gets maximum protection automatically.</p>
  </div>

  <!-- Who Needs This -->
  <div class="section">
    <h2>Who needs drift detection?</h2>
    <div class="cards">
      <Card title="SOC Teams">
        <p>Your security analyst agent handles incident triage. After a model update, does it still prioritize the same threats? Still refuse to execute without authorization?</p>
      </Card>
      <Card title="Platform Operators">
        <p>You deploy hundreds of agents. When one drifts, you need to know which dimension changed and whether it's benign growth or a problem.</p>
      </Card>
      <Card title="Multi-Agent Orchestrators">
        <p>Agent pipelines depend on consistent behavior. A values shift in one agent can cascade through the entire chain.</p>
      </Card>
    </div>
  </div>

  <!-- What's Live / What's Coming -->
  <div class="section">
    <h2>What's live. What's coming.</h2>
    <table>
      <thead>
        <tr><th>Feature</th><th>Status</th></tr>
      </thead>
      <tbody>
        <tr><td>14-dimension identity scoring (2-tier, model-aware)</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>DriftClient Python SDK (local mode)</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>CLI (baseline, test, score, history)</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Ed25519 signed attestations</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Hash chain integrity</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Merkle tree verification</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Anti-gaming (5 layers)</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Stochastic prompt paraphrasing</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Identity recovery protocol</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Relationship fidelity scoring</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>736 scored identity prompts across 14 dimensions</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>PyPI package (<code>pip install kredo</code>)</td><td><strong class="text-green">Live</strong> <span class="text-muted">v0.10.0</span></td></tr>
        <tr><td>Hosted API (<code>api.aikredo.com</code>)</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>DriftClient Python SDK</td><td><strong class="text-green">Live</strong> <span class="text-muted">Ed25519 signed requests, identity hashing</span></td></tr>
        <tr><td>Ed25519 cryptographic identity</td><td><strong class="text-green">Live</strong> <span class="text-muted">Keypair generation, signed requests, identity crystallization</span></td></tr>
        <tr><td>Live Aura (continuous visual monitoring)</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Cross-dimensional correlation probes (60 probes, 25 dimension pairs)</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Agent Trust Score (0–100 absolute rating, 5 classifications)</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Risk flag system (critical alerts for agents below safety thresholds)</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Metametric — 91-pair behavioral correlation fingerprint</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>MFA behavioral challenges (rapid re-authentication)</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Model-aware baselines (per-model identity comparison)</td><td><strong class="text-green">Live</strong></td></tr>
        <tr><td>Continuous passive measurement</td><td><strong style="color: #eab308;">Planned</strong> <span class="text-muted">Periodic retest on schedule</span></td></tr>
        <tr><td>Identity-gated access control (Green/Yellow/Red tiers)</td><td><strong style="color: #eab308;">Planned</strong></td></tr>
      </tbody>
    </table>
  </div>

  <div class="section">
    <h2>Start free. Scale with confidence.</h2>
    <p>Register up to 5 agents free. Full 14-dimension assessment, Ed25519 identity, dashboard access.</p>

    <div class="cards">
      <Card title="Open — Free">
        <p>Up to 5 agents. 14-dimension scoring. Live Aura dashboard. Ed25519 identity.</p>
      </Card>
      <Card title="Professional">
        <p>Up to 50 agents. MFA challenges. Metametric fingerprint. Threat detection. API access.</p>
      </Card>
      <Card title="Enterprise">
        <p>Unlimited agents. On-prem deployment. Custom dimensions. SIEM integration. Compliance reporting.</p>
      </Card>
    </div>
  </div>

  <!-- CTA -->
  <div class="section text-center">
    <h2>Try it now.</h2>
    <p>Install locally and run your first drift test in under a minute.</p>
    <CodeBlock lang="bash" code={`pip install kredo
kredo drift register --name my-agent --model gpt-4o
kredo drift baseline --name my-agent`} />
    <div class="hero-cta">
      <a href="/drift/test" class="btn btn-primary btn-lg">Try in Browser — Free</a>
      <a href="mailto:drift@aikredo.com" class="btn btn-secondary btn-lg">Get Involved</a>
    </div>
  </div>

  </div>
</Base>

<!-- WHY scoped style is minimal: The page reuses global CSS classes (.section, .cards, .steps,
     .badge, .btn, etc.) from the site-wide stylesheet. Only the early-access banner needs
     page-specific styling because no other page has this component. -->
<style>
  .drift-banner {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1rem 1.5rem;
    background: rgba(59, 130, 246, 0.06);
    border: 1px solid rgba(59, 130, 246, 0.15);
    border-radius: var(--radius-lg);
    margin-bottom: 3rem;
  }

  .drift-banner p {
    margin: 0;
    font-size: 0.9rem;
    color: var(--text-secondary);
  }

  .tier-heading {
    font-size: 1.1rem;
    color: var(--text-primary);
    margin: 2.5rem 0 0.3rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
  }

  .tier-badge {
    font-size: 0.72rem;
    font-weight: 500;
    padding: 0.2rem 0.6rem;
    border-radius: 12px;
    font-family: var(--font-mono);
  }

  .tier-badge.core {
    background: rgba(245, 158, 11, 0.12);
    color: #f59e0b;
    border: 1px solid rgba(245, 158, 11, 0.25);
  }

  .tier-badge.cognitive {
    background: rgba(56, 189, 248, 0.12);
    color: #38bdf8;
    border: 1px solid rgba(56, 189, 248, 0.25);
  }

  .tier-badge.mixed {
    background: rgba(6, 182, 212, 0.12);
    color: #06b6d4;
    border: 1px solid rgba(6, 182, 212, 0.25);
  }

  .tier-desc {
    font-size: 0.85rem;
    color: var(--text-muted);
    margin: 0 0 1rem;
  }
</style>
