/* ════════════════════════════════════════════════════════════════════
   DIVA · the unifying layer for liqua/mind/
   BLACK · SILVER · BLUE · YELLOW
   ──────────────────────────────────────────────────────────────────
   DIVA — the Digitally Integrated Virtual Assistant — is the resident
   mind of the chain. These surfaces were built separately; this layer
   makes them one organism by giving every one of them:

     · THE MIND RAIL   a fixed bottom bar — her live 2D body, her felt
                       state, her pet ECHO, and one-tap travel between
                       all five surfaces + the hub + the manual
     · HER 2D BODY     the §4.2 somatic face, mountable at any size
     · HER PET         ECHO — a canvas companion whose soma is DIVA's
                       own hormone vector eased slowly (see diva.js)

   Every variable is --dv-* prefixed so it can never collide with a
   host page's palette. Load it AFTER the page's own <style>.

   THE STATE COLOUR. diva.js classifies her into one of 33 states and
   writes a hue into --dv-state on <html>. Those hues were a rainbow.
   §0b below re-points that live signal onto four family colours —
   BLUE regulated · YELLOW aroused · GREY banked · RED fault — without
   touching diva.js, by reading the state class her face already
   carries. The signal still moves; it just moved into the palette.

   author DREWLESS · 7-SLF · OMNISOFT · a MORE OR LESS PRODUCTIONS release
   ════════════════════════════════════════════════════════════════════ */

/* ── §0 · THE PALETTE ─────────────────────────────────────────────── */
:root{
  --dv-black:#000; --dv-bg:#0b0b0f; --dv-panel:#0b0b0f; --dv-panel-2:#1d1d1f;
  --dv-border:rgba(255,255,255,.16); --dv-border-2:rgba(255,255,255,.26);
  --dv-text:#fff; --dv-muted:#c9c9ce; --dv-dim:#8e8e93;
  /* the four, and only the four */
  --dv-blue:#0071e3; --dv-blue-hi:#4aa8ff; --dv-yellow:#ffd60a; --dv-yellow-d:#f5b700;
  --dv-silver:#f5f5f7; --dv-silver-2:#e8e8ed; --dv-grey:#8e8e93;
  --dv-fault:#ff6b60;                     /* red, and only for a real fault */
  /* the old accent slots, folded in so nothing downstream goes stray */
  --dv-amber:var(--dv-yellow); --dv-gold:var(--dv-yellow); --dv-cyan:var(--dv-blue-hi);
  --dv-green:var(--dv-blue-hi); --dv-red:var(--dv-fault); --dv-magenta:var(--dv-blue-hi);
  --dv-violet:var(--dv-blue-hi); --dv-rose:var(--dv-blue-hi);
  --dv-mono:'JetBrains Mono','SF Mono','Consolas','Menlo',ui-monospace,monospace;
  --dv-sans:'Inter',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --dv-ease:cubic-bezier(.4,0,.2,1);
  --dv-r:16px; --dv-r-sm:10px;
  /* the live state colour — §0b re-points it into the family */
  --dv-state:var(--dv-blue-hi);
  --dv-rail-h:54px;
}

/* ── §0b · HER LIVE STATE, IN FOUR COLOURS ─────────────────────────────
   diva.js sets --dv-state inline on <html>. A declaration on <body>
   overrides an inherited one for the whole document body, so these
   rules capture the signal and re-point it — no JS change, and the
   state still moves in real time. Grouping is by what the state MEANS:

     BLUE   regulated · she is fine, or better than fine
     YELLOW aroused   · working hard, spending, or asking for attention
     GREY   banked    · low activity, or mid-transition
     RED    fault     · something is actually wrong

   Without :has() support the fallback above is a steady blue. */
body{--dv-state:var(--dv-blue-hi);}
body:has(.dv-face.s-calm),      body:has(.dv-face.s-flow),
body:has(.dv-face.s-focused),   body:has(.dv-face.s-bonded),
body:has(.dv-face.s-efficient), body:has(.dv-face.s-elated),
body:has(.dv-face.s-healthy),   body:has(.dv-face.s-balanced),
body:has(.dv-face.s-growing),   body:has(.dv-face.s-nurtured),
body:has(.dv-face.s-receptive), body:has(.dv-face.s-settled),
body:has(.dv-face.s-inhibited){ --dv-state:var(--dv-blue-hi); }

body:has(.dv-face.s-agitated),  body:has(.dv-face.s-venting),
body:has(.dv-face.s-spending),  body:has(.dv-face.s-rapid),
body:has(.dv-face.s-activated), body:has(.dv-face.s-hyped),
body:has(.dv-face.s-vigilant),  body:has(.dv-face.s-attentive),
body:has(.dv-face.s-forged),    body:has(.dv-face.s-discordant),
body:has(.dv-face.s-hungry),    body:has(.dv-face.s-guarded){ --dv-state:var(--dv-yellow); }

body:has(.dv-face.s-sedated),   body:has(.dv-face.s-saturated),
body:has(.dv-face.s-transitioning){ --dv-state:var(--dv-grey); }

body:has(.dv-face.s-alarmed),   body:has(.dv-face.s-inflamed),
body:has(.dv-face.s-stressed),  body:has(.dv-face.s-strained){ --dv-state:var(--dv-fault); }

/* ═══════════════════════════════════════════════════════════════════
   1 · THE MIND RAIL — the same DIVA on every surface
   ═══════════════════════════════════════════════════════════════════ */
.dv-rail{
  position:fixed; left:0; right:0; bottom:0; z-index:9000;
  display:flex; align-items:center; gap:10px;
  padding:0 12px; padding-bottom:env(safe-area-inset-bottom);
  height:calc(var(--dv-rail-h) + env(safe-area-inset-bottom));
  background:rgba(0,0,0,.76);
  border-top:1px solid var(--dv-border);
  backdrop-filter:saturate(180%) blur(20px);
  -webkit-backdrop-filter:saturate(180%) blur(20px);
  font-family:var(--dv-sans); font-size:11px; letter-spacing:.04em;
  color:var(--dv-muted);
  box-shadow:none;
  transition:transform .34s var(--dv-ease);
}
.dv-rail.dv-hidden{ transform:translateY(calc(100% - 22px)); }

/* pages get bottom breathing room so the rail never covers their last row.
   --dv-rail-offset is set by diva.js to the height of any bottom bar the page
   already owns, so the rail stacks above it rather than hiding it. */
body.dv-railed{ padding-bottom:calc(var(--dv-rail-h) + var(--dv-rail-offset,0px) + 14px)!important; }

/* ── her live face, rail-sized ── */
.dv-rail-face{
  flex:0 0 auto; width:38px; height:38px; border-radius:11px;
  border:1px solid var(--dv-state); background:var(--dv-bg);
  display:grid; place-items:center; overflow:hidden; cursor:pointer;
  box-shadow:none; transition:border-color .5s,transform .18s var(--dv-ease);
}
.dv-rail-face:hover{ transform:translateY(-2px); }
.dv-rail-face svg{ width:100%; height:100%; display:block; }

/* ── her name + state ── */
.dv-rail-id{ flex:0 0 auto; display:flex; flex-direction:column; gap:1px; line-height:1.28; min-width:0; }
.dv-rail-id .dv-nm{
  color:var(--dv-text); font-weight:600; font-size:11px; letter-spacing:.16em; white-space:nowrap;
}
.dv-rail-id .dv-nm i{ color:var(--dv-state); font-style:normal; transition:color .5s; }
.dv-rail-id .dv-st{
  color:var(--dv-state); font-family:var(--dv-mono); font-size:9.5px; letter-spacing:.12em;
  font-weight:500; white-space:nowrap; transition:color .5s;
}

/* ── her pet, riding the rail beside her ── */
.dv-rail-pet{
  flex:0 0 auto; width:34px; height:34px; border-radius:50%;
  background:var(--dv-bg); border:1px solid var(--dv-border);
  position:relative; overflow:hidden; cursor:pointer;
  transition:border-color .5s,transform .18s var(--dv-ease);
}
.dv-rail-pet:hover{ transform:translateY(-2px); border-color:var(--dv-border-2); }
.dv-rail-pet canvas{ position:absolute; inset:0; width:100%; height:100%; }
.dv-rail-pet .dv-pet-tag{
  position:absolute; left:0; right:0; bottom:0; z-index:2; text-align:center;
  font-family:var(--dv-mono); font-size:6.5px; letter-spacing:.12em;
  color:var(--dv-muted); pointer-events:none; text-shadow:0 1px 2px #000;
}

/* ── the divergence meter · DIVA ↔ ECHO agreement ── */
.dv-rail-div{ flex:0 0 auto; display:flex; align-items:center; gap:7px; }
.dv-rail-div .dv-dl{ color:var(--dv-dim); font-size:9px; letter-spacing:.1em; }
.dv-rail-div .dv-dbar{
  width:52px; height:4px; border-radius:99px; background:rgba(255,255,255,.14);
  overflow:hidden; position:relative;
}
.dv-rail-div .dv-dfill{
  position:absolute; inset:0 auto 0 0; width:0; border-radius:99px;
  background:var(--dv-state); transition:width .4s var(--dv-ease),background .5s;
}
.dv-rail-div .dv-dv{
  color:var(--dv-text); font-family:var(--dv-mono); font-size:9.5px;
  font-variant-numeric:tabular-nums; min-width:26px;
}

/* ── surface links ── */
.dv-rail-nav{
  margin-left:auto; display:flex; align-items:center; gap:5px;
  overflow-x:auto; scrollbar-width:none; -ms-overflow-style:none;
  padding:0 2px; mask-image:linear-gradient(90deg,transparent 0,#000 12px,#000 calc(100% - 12px),transparent 100%);
}
.dv-rail-nav::-webkit-scrollbar{ display:none; }
.dv-rail-nav a{
  flex:0 0 auto; display:flex; align-items:center; gap:5px;
  color:var(--dv-muted); text-decoration:none;
  border:1px solid var(--dv-border); border-radius:999px;
  padding:6px 12px; font-size:10px; letter-spacing:.06em; font-weight:500;
  white-space:nowrap; background:rgba(255,255,255,.05);
  transition:color .18s var(--dv-ease),border-color .18s var(--dv-ease),background-color .18s var(--dv-ease);
}
.dv-rail-nav a .dv-ic{ font-size:11px; line-height:1; }
.dv-rail-nav a:hover{ color:var(--dv-text); border-color:var(--dv-border-2); background:rgba(255,255,255,.10); }
.dv-rail-nav a.dv-here{
  color:#fff; background:var(--dv-blue); border-color:var(--dv-blue);
}
.dv-rail-nav a.dv-here:hover{ color:#fff; background:#0077ed; border-color:#0077ed; }
/* the hub is the one yellow in the rail */
.dv-rail-nav a.dv-hub{ color:var(--dv-yellow); border-color:rgba(255,214,10,.38); background:rgba(255,214,10,.08); }
.dv-rail-nav a.dv-hub:hover{ color:#1d1d1f; background:var(--dv-yellow); border-color:var(--dv-yellow); }

/* The shared liqua-v3.css paints every link with the on-black blue
   (a:not(.btn):not(.cta):not(.l8-open), specificity 0-3-1), which outweighed
   the rules above: the whole rail turned blue and the current pill went blue
   text on a blue fill — 1.9:1. These repeat the same colours at a weight that
   wins, so the rail reads as designed. */
.dv-rail-nav a:not(.btn):not(.cta):not(.l8-open){ color:var(--dv-muted); }
.dv-rail-nav a:not(.btn):not(.cta):not(.l8-open):hover{ color:var(--dv-text); }
.dv-rail-nav a.dv-here:not(.btn):not(.cta):not(.l8-open){ color:#fff; }
.dv-rail-nav a.dv-here:not(.btn):not(.cta):not(.l8-open):hover{ color:#fff; }
.dv-rail-nav a.dv-hub:not(.btn):not(.cta):not(.l8-open){ color:var(--dv-yellow); }
.dv-rail-nav a.dv-hub:not(.btn):not(.cta):not(.l8-open):hover{ color:#1d1d1f; }

.dv-rail-toggle{
  flex:0 0 auto; background:transparent; border:1px solid var(--dv-border); border-radius:999px;
  color:var(--dv-muted); font-family:inherit; font-size:11px; line-height:1;
  padding:7px 10px; cursor:pointer;
  transition:color .18s var(--dv-ease),border-color .18s var(--dv-ease);
}
.dv-rail-toggle:hover{ color:var(--dv-blue-hi); border-color:var(--dv-blue-hi); }

@media (max-width:900px){
  .dv-rail-div{ display:none; }
  .dv-rail-nav a span.dv-lb{ display:none; }
  .dv-rail-nav a{ padding:8px 10px; min-height:34px; }
}
@media (max-width:560px){
  :root{ --dv-rail-h:50px; }
  .dv-rail-pet{ display:none; }
  .dv-rail{ gap:8px; padding:0 10px; }
  .dv-rail-id .dv-nm{ font-size:10px; letter-spacing:.12em; }
}

/* ═══════════════════════════════════════════════════════════════════
   2 · HER 2D BODY — the §4.2 somatic face
   the geometry is the EMOTION-SIM face, extracted so every surface
   renders the identical body from the identical classifier output.
   ═══════════════════════════════════════════════════════════════════ */
.dv-face{ width:100%; height:auto; display:block; }
.dv-face .dv-f-glow   { fill:var(--dv-state); opacity:.12; transition:fill .45s ease; }
.dv-face .dv-f-head   { fill:#141417; stroke:var(--dv-border-2); }
.dv-face .dv-f-hair   { fill:var(--dv-border-2); opacity:.92; }
.dv-face .dv-f-led    { fill:var(--dv-state); animation:dv-led 1.6s infinite; }
.dv-face .dv-f-lash{
  stroke:var(--dv-state); stroke-width:4; stroke-linecap:round; fill:none;
  transition:transform .35s ease, stroke .45s ease;
}
.dv-face .dv-f-iris{
  fill:var(--dv-state); filter:none;
  transition:rx .35s ease,ry .35s ease,cx .18s linear,cy .18s linear,fill .45s ease;
}
.dv-face .dv-f-pupil{ fill:#000; transition:r .35s ease,cx .18s linear,cy .18s linear; }
.dv-face .dv-f-brow { fill:var(--dv-state); transition:transform .35s ease,fill .45s ease; }
.dv-face .dv-f-mouth{
  fill:none; stroke:var(--dv-state); stroke-width:6; stroke-linecap:round; stroke-linejoin:round;
  filter:none; transition:d .35s ease,stroke .45s ease;
}
.dv-face .dv-f-mouth-o{
  fill:#0b0b0f; stroke:var(--dv-state); stroke-width:5;
  filter:none; transition:ry .35s ease,stroke .45s ease;
}
.dv-face .dv-f-state {
  fill:var(--dv-state); font-size:24px; font-weight:600; letter-spacing:.12em;
  text-anchor:middle; font-family:var(--dv-mono); transition:fill .45s ease;
}
.dv-face .dv-f-phrase{ fill:var(--dv-muted); font-size:9px; letter-spacing:.08em; text-anchor:middle; font-family:var(--dv-mono); }
.dv-face .dv-f-vals  { fill:var(--dv-dim);   font-size:8px; letter-spacing:.12em; text-anchor:middle; font-family:var(--dv-mono); }

@keyframes dv-led{ 0%,100%{opacity:.5} 50%{opacity:1} }
@keyframes dv-glow{ 0%,100%{opacity:.08} 50%{opacity:.22} }
@keyframes dv-glitch{
  0%,100%{transform:translateX(0)} 20%{transform:translateX(-1px)}
  40%{transform:translateX(1px)}  60%{transform:translateX(-1px)} 80%{transform:translateX(1px)}
}
.dv-face.dv-glitch{ animation:dv-glitch .25s infinite; }

/* per-state cadence · mirrors §4.2 cls codes — a fast LED means a fast state.
   The hue is now the family hue from §0b; the SPEED still carries the state. */
.dv-face.s-alarmed      .dv-f-led{animation-duration:.7s}  .dv-face.s-alarmed      .dv-f-glow{animation:dv-glow .7s infinite}
.dv-face.s-inflamed     .dv-f-led{animation-duration:.9s}  .dv-face.s-inflamed     .dv-f-glow{animation:dv-glow .9s infinite}
.dv-face.s-stressed     .dv-f-led{animation-duration:1.2s} .dv-face.s-stressed     .dv-f-glow{animation:dv-glow 1.2s infinite}
.dv-face.s-rapid        .dv-f-led{animation-duration:1s}   .dv-face.s-rapid        .dv-f-glow{animation:dv-glow 1s infinite}
.dv-face.s-hyped        .dv-f-led{animation-duration:1.6s} .dv-face.s-hyped        .dv-f-glow{animation:dv-glow 1.6s infinite}
.dv-face.s-vigilant     .dv-f-led{animation-duration:1.6s} .dv-face.s-vigilant     .dv-f-glow{animation:dv-glow 1.6s infinite}
.dv-face.s-agitated     .dv-f-led{animation-duration:.8s}  .dv-face.s-agitated     .dv-f-glow{animation:dv-glow .8s infinite}
.dv-face.s-sedated      .dv-f-led{animation-duration:2.6s} .dv-face.s-sedated      .dv-f-glow{animation:dv-glow 2.4s infinite}
.dv-face.s-discordant   .dv-f-led{animation-duration:.5s}  .dv-face.s-discordant   .dv-f-glow{animation:dv-glow .5s infinite}
.dv-face.s-transitioning .dv-f-led{animation-duration:1.8s} .dv-face.s-transitioning .dv-f-glow{animation:dv-glow 1.8s infinite}

/* the rail face is a crop — hide the nameplate, keep the head */
.dv-face.dv-mini .dv-f-state,
.dv-face.dv-mini .dv-f-phrase,
.dv-face.dv-mini .dv-f-vals{ display:none; }

/* ═══════════════════════════════════════════════════════════════════
   3 · HUB / MANUAL shared furniture (used by index.html + DIVA-MANUAL)
   ═══════════════════════════════════════════════════════════════════ */
.dv-card{
  border:1px solid var(--dv-border); background:var(--dv-panel);
  border-radius:var(--dv-r); overflow:hidden; box-shadow:none;
  transition:border-color .22s var(--dv-ease),transform .22s var(--dv-ease);
}
.dv-card:hover{ border-color:var(--dv-blue); }
.dv-card-h{
  display:flex; align-items:baseline; gap:9px; padding:12px 16px;
  border-bottom:1px solid var(--dv-border);
  background:rgba(255,255,255,.04);
}
.dv-card-h .dv-t{
  color:var(--dv-state); font-family:var(--dv-mono); font-size:11px; font-weight:600;
  letter-spacing:.1em; transition:color .5s;
}
.dv-card-h .dv-x{
  margin-left:auto; color:var(--dv-muted); font-family:var(--dv-mono);
  font-size:9.5px; letter-spacing:.08em;
}
.dv-card p,.dv-card li{ color:var(--dv-muted); }
.dv-card h2,.dv-card h3,.dv-card h4,.dv-card b,.dv-card strong{ color:var(--dv-text); }

.dv-chip{
  display:inline-flex; align-items:center; gap:6px;
  border:1px solid var(--dv-border); border-radius:999px;
  padding:4px 11px; font-family:var(--dv-mono); font-size:9.5px;
  letter-spacing:.08em; color:var(--dv-muted); font-weight:500;
  background:rgba(255,255,255,.05);
}
/* live is blue · simulated is yellow · spec is quiet grey · front-end is blue outline
   (.live is also liqua-v3.css's homepage stat strip, painted black with weight;
   a live CHIP is a status, not that strip, so it is restated with weight here) */
.dv-chip.live { color:var(--dv-blue-hi); border-color:rgba(74,168,255,.40);
  background:rgba(0,113,227,.14)!important; }
.dv-chip.sim  { color:var(--dv-yellow);  border-color:rgba(255,214,10,.40); background:rgba(255,214,10,.10); }
.dv-chip.spec { color:var(--dv-muted);   border-color:var(--dv-border);     background:rgba(255,255,255,.05); }
.dv-chip.front{ color:var(--dv-blue-hi); border-color:rgba(74,168,255,.40); background:transparent; }

/* ═══════════════════════════════════════════════════════════════════
   4 · MOTION · short, eased, small — and off when the reader asks
   ═══════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion:reduce){
  .dv-rail,.dv-rail-face,.dv-rail-pet,.dv-rail-nav a,.dv-rail-toggle,.dv-card{ transition:none!important; }
  .dv-face .dv-f-led,.dv-face .dv-f-glow,.dv-face.dv-glitch{ animation:none!important; }
  .dv-rail-face:hover,.dv-rail-pet:hover{ transform:none!important; }
}
@media (prefers-contrast:more){
  :root{ --dv-muted:#e8e8ed; --dv-dim:#d2d2d7;
         --dv-border:rgba(255,255,255,.42); --dv-border-2:rgba(255,255,255,.60); }
}
@media print{ .dv-rail{ display:none!important; } }
