/* =========================================================================
   livecard.css — THE LIVE DINOSAUR CARD. Canonical, owner-neutral.

   The visual reference is the donor island's parking panel (proposed to the
   owner 2026-08-07, his call outstanding): an eyebrow + LIVE pill, the species in display type with a
   growth ring beside it, VITALS as labelled bars, NUTRIENT DIET as three
   bars, and a nested PRIME STATUS block scored "n of 5".

   OWNER-NEUTRAL BY CONSTRUCTION. Every colour here is a var() with a
   documented fallback, so a site that already publishes design tokens
   (--surface, --line, --moon, --silver, --silver-mut, --display, --ui)
   gets its own look for free, and a site that publishes none still renders
   the donor's dark palette rather than unstyled text. There is not one
   owner name, brand colour or copy string in this file.

   THE MEANING COLOURS ARE NOT THEMEABLE, ON PURPOSE. Health is red and
   thirst is blue on every server, because a player reads the
   colour before the label; a site theme that recoloured health would make
   the card lie faster than it informs. They are still var()s so a species
   with a genuinely different meaning can override one, but the fallbacks
   are the donor's exact values.

   NO LAYOUT DEPENDENCY. The card sizes from its container: it is a grid
   that collapses to one column under 720px and never sets a page width, so
   it drops into a vault page, a live page or a dashboard column unchanged.
   ========================================================================= */

.lvc {
  /* ---- surfaces, from the host site's tokens when it has them ---- */
  --lvc-card:    var(--surface, #0F0F12);
  --lvc-nest:    var(--surface-2, rgba(255,255,255,.03));
  --lvc-line:    var(--line, rgba(180,160,130,.18));
  --lvc-line-2:  var(--line-2, rgba(255,255,255,.06));
  --lvc-head:    var(--moon, #ECE8D8);
  --lvc-text:    var(--silver, #D6D2C4);
  --lvc-mut:     var(--silver-mut, #8C8878);
  --lvc-track:   rgba(255,255,255,.06);

  /* ---- meaning colours (fleet-wide, see header) ---- */
  --lvc-health:   #E23B3B;
  --lvc-stamina:  #FBBF24;
  --lvc-hunger:   #F97316;
  --lvc-thirst:   #60A5FA;
  --lvc-oxygen:   #38BDF8;
  --lvc-bleed:    #EF4444;
  --lvc-sprint:   #A78BFA;
  --lvc-bite:     #FB923C;
  --lvc-fracture: #34D399;
  --lvc-carb:     #FBBF24;
  --lvc-protein:  #F87171;
  --lvc-lipid:    #60A5FA;
  --lvc-ok:       #6BCF6B;
  --lvc-no:       #F87171;
  --lvc-prime:    #FCD34D;
  --lvc-ring:     var(--accent, #A11212);

  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}

@media (max-width: 860px) {
  .lvc { grid-template-columns: minmax(0, 1fr); }
  /* Stacked, a full-width SQUARE well pushes every number below the fold on a
     phone. The specimen keeps its place and gives back the height. */
  .lvc-specimen { aspect-ratio: 16 / 10; }
}

/* =========================================================================
   the specimen well — the player's own animal, or a calm empty frame
   ========================================================================= */
.lvc-specimen {
  position: relative;
  border: 1px solid var(--lvc-line);
  border-radius: 12px;
  background: var(--lvc-card);
  aspect-ratio: 1 / 1;
  overflow: hidden;
  /* A specimen that never loads must still be a deliberate-looking frame
     rather than a collapsed box, so the well keeps its shape with no child. */
  min-height: 200px;
}

/* The side column: the animal, and whatever the host lets you DO with it.
   NOT sticky - the specimen renderer draws into the rectangle this element
   reports, and a box that moves under a page-pinned canvas draws a frame
   behind itself on every scroll. A square well that stays put is honest and
   costs nothing. */
.lvc-side { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

/* The host mounts whatever renderer it owns in here. The card itself never
   loads a mesh, a texture or a 3D library - it only provides the frame and
   tells the host which species class is on screen. */
.lvc-specimen-mount { position: absolute; inset: 0; }

.lvc-specimen-note {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 10px 12px;
  font: 600 10px/1.4 var(--ui, system-ui, sans-serif);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--lvc-mut);
  background: linear-gradient(to top, rgba(0,0,0,.55), rgba(0,0,0,0));
  pointer-events: none;
}

/* =========================================================================
   the stats card
   ========================================================================= */
.lvc-card {
  border: 1px solid var(--lvc-line);
  border-radius: 12px;
  background: var(--lvc-card);
  padding: 22px;
  min-width: 0;
}

@media (max-width: 560px) { .lvc-card { padding: 16px; } }

/* ---- header ---- */
.lvc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
}

.lvc-head-l { display: flex; align-items: center; gap: 10px; min-width: 0; }

.lvc-eyebrow {
  margin: 0;
  font: 700 10px/1 var(--ui, system-ui, sans-serif);
  letter-spacing: .25em;
  text-transform: uppercase;
  color: var(--lvc-mut);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lvc-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  border: 1px solid transparent;
  font: 700 9px/1 var(--ui, system-ui, sans-serif);
  letter-spacing: .12em;
  text-transform: uppercase;
  white-space: nowrap;
}

.lvc-pill-live {
  background: rgba(34,120,34,.2);
  color: var(--lvc-ok);
  border-color: rgba(74,150,74,.35);
}

.lvc-pill-stale {
  background: rgba(227,183,120,.14);
  color: var(--warn, #E3B778);
  border-color: rgba(227,183,120,.3);
}

.lvc-pill-prime {
  background: rgba(245,158,11,.15);
  color: var(--lvc-prime);
  border-color: rgba(245,158,11,.4);
  box-shadow: 0 0 12px rgba(245,158,11,.18);
}

/* Elder is the rung BELOW prime on the game's own ladder, so it reads as a
   quieter version of the same badge rather than a different kind of thing. */
.lvc-pill-elder {
  background: rgba(196,214,228,.1);
  color: var(--lvc-head);
  border-color: rgba(196,214,228,.28);
}

.lvc-pill-plain {
  background: rgba(255,255,255,.06);
  border-color: rgba(255,255,255,.09);
  color: var(--lvc-text);
}

.lvc-dot {
  width: 6px; height: 6px;
  border-radius: 999px;
  background: currentColor;
  animation: lvc-pulse 2s ease-in-out infinite;
}

@keyframes lvc-pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

/* A refresh control is a real button so it is keyboard reachable. It never
   becomes the only way to get fresh numbers - the card polls on its own. */
.lvc-refresh {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px; height: 30px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--lvc-mut);
  cursor: pointer;
  transition: color .16s ease, border-color .16s ease, background .16s ease;
}
.lvc-refresh:hover { color: var(--lvc-head); border-color: var(--lvc-line); }
.lvc-refresh:focus-visible { outline: 2px solid var(--accent, #9FB6C9); outline-offset: 2px; }
.lvc-refresh[disabled] { opacity: .4; cursor: default; }
.lvc-refresh svg { width: 15px; height: 15px; }
.lvc-refresh.is-busy svg { animation: lvc-spin 1s linear infinite; }

@keyframes lvc-spin { to { transform: rotate(360deg); } }

/* ---- species + growth ring ---- */
.lvc-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
}

.lvc-species {
  margin: 0;
  min-width: 0;
  font-family: var(--display, Georgia, serif);
  font-size: clamp(24px, 3.4vw, 34px);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: .01em;
  text-transform: uppercase;
  color: var(--lvc-head);
  overflow-wrap: anywhere;
}

.lvc-ring { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.lvc-ring-svg { position: relative; width: 62px; height: 62px; }
.lvc-ring-svg svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.lvc-ring-num {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font: 700 13px/1 var(--ui, system-ui, sans-serif);
  font-variant-numeric: tabular-nums;
  color: var(--lvc-head);
}
.lvc-ring-stage {
  font: 700 9px/1 var(--ui, system-ui, sans-serif);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--lvc-mut);
  white-space: nowrap;
}

/* ---- section label ---- */
.lvc-sec {
  margin: 0 0 10px;
  font: 700 10px/1 var(--ui, system-ui, sans-serif);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--lvc-mut);
  opacity: .8;
}

/* ---- the bar grid ---- */
.lvc-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px 22px;
  margin-bottom: 22px;
}
.lvc-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

@media (max-width: 1080px) { .lvc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 460px)  { .lvc-grid, .lvc-grid-3 { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 700px)  { .lvc-grid-3 { grid-template-columns: minmax(0, 1fr); } }

.lvc-bar { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

.lvc-bar-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.lvc-bar-label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font: 700 10px/1.3 var(--ui, system-ui, sans-serif);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--lvc-mut);
  min-width: 0;
}
.lvc-bar-label svg { width: 11px; height: 11px; flex: 0 0 auto; color: var(--lvc-bleed); }

.lvc-bar-value {
  font: 600 11.5px/1.3 var(--ui, system-ui, sans-serif);
  font-variant-numeric: tabular-nums;
  color: var(--lvc-text);
  white-space: nowrap;
}
.lvc-bar-value.is-pending { color: var(--lvc-mut); font-style: italic; font-weight: 500; }

.lvc-bar-track {
  height: 8px;
  border-radius: 999px;
  background: var(--lvc-track);
  overflow: hidden;
}

.lvc-bar-fill {
  /* A <span> is inline by default, and an inline box ignores both height and
     a percentage width - the bar rendered as an invisible sliver until this
     line existed. */
  display: block;
  height: 100%;
  border-radius: 999px;
  /* A width transition is the ONLY motion here. The card repaints on a poll,
     and animating anything else would make a steady reading look like it is
     changing when it is not. */
  transition: width .7s cubic-bezier(.22,.61,.36,1);
}
.lvc-bar.is-low .lvc-bar-fill { animation: lvc-pulse 1.6s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  .lvc-bar-fill { transition: none; }
  .lvc-dot, .lvc-bar.is-low .lvc-bar-fill, .lvc-refresh.is-busy svg { animation: none; }
}

/* =========================================================================
   prime status
   ========================================================================= */
.lvc-prime {
  border: 1px solid var(--lvc-line-2);
  border-radius: 12px;
  background: var(--lvc-nest);
  padding: 16px;
}

.lvc-prime-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.lvc-prime-score {
  font: 600 11px/1 var(--ui, system-ui, sans-serif);
  font-variant-numeric: tabular-nums;
  color: var(--lvc-text);
  white-space: nowrap;
}

.lvc-prime-rows { display: flex; flex-direction: column; }

.lvc-prime-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 5px 0;
  font: 400 12px/1.4 var(--ui, system-ui, sans-serif);
  color: var(--lvc-text);
}

.lvc-prime-state {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-weight: 700;
  font-size: 11.5px;
  white-space: nowrap;
}
.lvc-prime-state svg { width: 13px; height: 13px; }
.lvc-prime-state.is-met  { color: var(--lvc-ok); }
.lvc-prime-state.is-unmet { color: var(--lvc-no); }
.lvc-prime-state.is-na, .lvc-prime-state.is-pending { color: var(--lvc-mut); }

.lvc-prime-note {
  margin: 10px 0 0;
  font: 400 10.5px/1.5 var(--ui, system-ui, sans-serif);
  color: var(--lvc-mut);
}

/* =========================================================================
   footer chips + freshness
   ========================================================================= */
.lvc-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--lvc-line-2);
}

.lvc-foot-when {
  margin-left: auto;
  font: 400 10.5px/1.4 var(--ui, system-ui, sans-serif);
  color: var(--lvc-mut);
}

/* =========================================================================
   the empty states — a rendered answer, never a spinner
   ========================================================================= */
.lvc-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  padding: 34px 16px;
}
.lvc-empty svg { width: 34px; height: 34px; color: var(--lvc-mut); opacity: .5; }
.lvc-empty h3 {
  margin: 0;
  font-family: var(--display, Georgia, serif);
  font-size: clamp(19px, 2.6vw, 24px);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--lvc-head);
}
.lvc-empty p { margin: 0; max-width: 44ch; font-size: 13.5px; color: var(--lvc-text); }
.lvc-empty-act { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 6px; }

/* The skeleton is shown ONCE, before the first answer of the session ever
   lands. Every later state is a real answer, so nothing here can be left on
   screen by a failed poll. */
.lvc-skel { display: flex; flex-direction: column; gap: 12px; animation: lvc-pulse 1.6s ease-in-out infinite; }
.lvc-skel-row { height: 34px; border-radius: 10px; background: rgba(255,255,255,.05); }
.lvc-skel-grid { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 12px; }
.lvc-skel-grid > span { display: block; height: 34px; border-radius: 10px; background: rgba(255,255,255,.035); }
@media (max-width: 1080px) { .lvc-skel-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }
