/* ── Fonts ────────────────────────────────────────────────────────────────────── */
@import url('https://fonts.googleapis.com/css2?family=Cinzel+Decorative:wght@700&family=IM+Fell+English:ital@0;1&display=swap');

/* ── Reset & Base ─────────────────────────────────────────────────────────── */

*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  /* Dark frame — oiled wood table */
  --bg:           #0d0b08;
  --bg-panel:     #16100a;   /* dark leather */
  --bg-slot:      #1e1510;   /* deep leather */
  --bg-log:       #ede0c4;   /* aged parchment */

  /* Borders */
  --border:       #3a2a18;   /* leather crease */
  --border-gold:  #8a6a28;   /* aged gold trim */
  --border-parch: #b8906a;   /* parchment ink border */

  /* Text on dark panels (inventory side) */
  --text:         #c8b890;
  --text-dim:     #6a5840;
  --text-gold:    #c89a18;
  --text-magic:   #7858b0;
  --text-danger:  #983030;
  --text-good:    #3a6830;

  /* Ink on parchment (log side) */
  --ink:          #1c130a;
  --ink-dim:      #8a7050;
  --ink-gold:     #7a5010;
  --ink-magic:    #3c1a60;
  --ink-danger:   #780c0c;
  --ink-good:     #1a4818;

  /* Typography */
  --font-serif:  'IM Fell English', 'Palatino Linotype', 'Book Antiqua', serif;
  --font-title:  'Cinzel Decorative', 'Palatino Linotype', serif;
  --font-mono:   'Courier New', Courier, monospace;
}

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-serif);
  font-size: 15px;
  line-height: 1.6;
  overflow: hidden;
}


/* ── Game layout ────────────────────────────────────────────────────────────── */

#game {
  display: flex;
  flex-direction: column;
  height: 100vh;
}


/* ── Terrain strip ──────────────────────────────────────────────────────────── */

#terrain-strip {
  position: relative;
  height: 76px;
  flex-shrink: 0;
  overflow: hidden;
  border-bottom: 2px solid var(--border-gold);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.6);
}

#terrain-bg {
  position: absolute;
  inset: 0;
  transition: background 2s ease;
}

/* Environment gradients */
.env-meadow  { background: linear-gradient(to bottom, #4a90c8 0%, #6ab880 65%, #3a8040 100%); }
.env-forest  { background: linear-gradient(to bottom, #2a4a38 0%, #1a3228 60%, #0e2018 100%); }
.env-plains  { background: linear-gradient(to bottom, #a0b8cc 0%, #c8b060 60%, #907840 100%); }
.env-ruins   { background: linear-gradient(to bottom, #505868 0%, #38404a 60%, #202830 100%); }
.env-cave    { background: linear-gradient(to bottom, #180e06 0%, #0e0804 60%, #060402 100%); }
.env-dungeon { background: linear-gradient(to bottom, #181818 0%, #0e0e0e 60%, #080808 100%); }
.env-castle  { background: linear-gradient(to bottom, #1a1e3c 0%, #10142a 60%, #080c1a 100%); }
.env-temple  { background: linear-gradient(to bottom, #28103c 0%, #180828 60%, #0e0418 100%); }


/* ── Sky / day-night ────────────────────────────────────────────────────────── */
/*
 * Phase classes on #terrain-strip drive all sky transitions.
 * No class  = day   — sun traverses, overlay transparent
 * time-dusk  = dusk  — warm dark overlay, sun fading
 * time-night = night — deep blue overlay, moon + stars appear
 * time-dawn  = dawn  — overlay lifting, moon fading
 * JS: setSkyPhase() in carrier-actions.js
 */

#night-overlay {
  position: absolute;
  inset: 0;
  background: rgba(5, 8, 24, 0);
  transition: background 3.5s ease;
  pointer-events: none;
}
#terrain-strip.time-dusk  #night-overlay { background: rgba(30, 12,  5, 0.42); }
#terrain-strip.time-night #night-overlay { background: rgba( 5,  8, 24, 0.68); }
#terrain-strip.time-dawn  #night-overlay { background: rgba(28, 10,  2, 0.20);
                                           transition: background 1.5s ease; }

#sun {
  position: absolute;
  top: 0;
  left: 0;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: radial-gradient(circle, #fff8c0 0%, #ffc030 55%, rgba(255, 160, 20, 0) 100%);
  pointer-events: none;
  opacity: 1;
  transition: opacity 4s ease;
}
#sun.sun-active                           { animation: sun-arc 108s linear forwards; }
#terrain-strip.time-dusk  #sun            { opacity: 0.35; }
#terrain-strip.time-night #sun,
#terrain-strip.time-dawn  #sun            { opacity: 0; }

/* Sun rises lower-left, peaks high centre, sets lower-right */
@keyframes sun-arc {
  0%   { transform: translate(-20px, 30px); }
  50%  { transform: translate(calc(50vw - 7px), 6px); }
  100% { transform: translate(calc(100vw + 20px), 30px); }
}

#moon {
  position: absolute;
  top: 10px;
  left: 34%;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: radial-gradient(circle, #f0f0e2 0%, #c4c4b0 65%, rgba(176, 176, 160, 0) 100%);
  pointer-events: none;
  opacity: 0;
  transition: opacity 3.5s ease;
}
#terrain-strip.time-night #moon { opacity: 0.88; }
#terrain-strip.time-dawn  #moon { opacity: 0.28; }

#stars {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.star {
  position: absolute;
  border-radius: 50%;
  background: #d8e4d0;
  opacity: 0;
  transition: opacity 4.5s ease;
}
#terrain-strip.time-night .star { opacity: 0.72; }
#terrain-strip.time-dawn  .star { opacity: 0.18; }

/* Star positions — scattered in the sky zone (upper ~30px of strip) */
.star.sa { left:  7%; top: 14px; width: 2px; height: 2px; animation: star-twinkle 2.8s ease-in-out infinite; animation-delay: -0.4s; }
.star.sb { left: 17%; top:  8px; width: 3px; height: 3px; animation: star-twinkle 4.3s ease-in-out infinite; animation-delay: -1.7s; }
.star.sc { left: 31%; top: 20px; width: 2px; height: 2px; animation: star-twinkle 3.6s ease-in-out infinite; animation-delay: -2.9s; }
.star.sd { left: 46%; top: 11px; width: 2px; height: 2px; animation: star-twinkle 5.1s ease-in-out infinite; animation-delay: -0.8s; }
.star.se { left: 60%; top: 22px; width: 2px; height: 2px; animation: star-twinkle 3.9s ease-in-out infinite; animation-delay: -3.3s; }
.star.sf { left: 74%; top:  7px; width: 3px; height: 3px; animation: star-twinkle 4.8s ease-in-out infinite; animation-delay: -1.2s; }
.star.sg { left: 88%; top: 15px; width: 2px; height: 2px; animation: star-twinkle 6.2s ease-in-out infinite; animation-delay: -4.5s; }

@keyframes star-twinkle {
  0%, 100% { transform: scale(1);   }
  50%       { transform: scale(0.3); }
}


/* ── Carrier silhouette ─────────────────────────────────────────────────────── */

#carrier-wrap {
  position: absolute;
  bottom: 8px;
  left: 0;
  animation: traverse 24s linear infinite;
  /* Blur = low awareness. Sharpens as lore is collected. */
  filter: blur(1.4px);
  transition: filter 1.8s ease;
}

#carrier-wrap.hidden {
  display: none;
}

/* Awareness tiers — JS adds these classes as lore fragments accumulate */
#carrier-wrap.aware-1 { filter: blur(0.8px); }
#carrier-wrap.aware-2 { filter: blur(0.3px); }
#carrier-wrap.aware-3 { filter: blur(0px);   }

/* Toggle between silhouette types */
.carrier-sil        { display: block; }
.carrier-sil.hidden { display: none;  }

/* Dark fill, faint outline so it reads on dark terrains */
.sil {
  fill: rgba(0, 0, 0, 0.85);
  stroke: rgba(255, 255, 255, 0.15);
  stroke-width: 0.6;
}

/* Stroke-only elements (tails, tendrils) — no fill */
.sil-stroke {
  fill: none !important;
  stroke: rgba(0, 0, 0, 0.85);
  stroke-linecap: round;
}

/* The bag is you — hint of magic in the outline */
.bag {
  fill: rgba(18, 10, 36, 0.90);
  stroke: rgba(160, 120, 220, 0.55);
  stroke-width: 1;
}


/* ── Humanoid walking animations ────────────────────────────────────────────── */

.leg-l {
  transform-box: fill-box;
  transform-origin: top center;
  animation: step-a 0.52s ease-in-out infinite alternate;
}
.leg-r {
  transform-box: fill-box;
  transform-origin: top center;
  animation: step-b 0.52s ease-in-out infinite alternate;
}
.arm-l {
  transform-box: fill-box;
  transform-origin: right center;
  animation: step-b 0.52s ease-in-out infinite alternate;
}

@keyframes step-a {
  from { transform: rotate(-17deg); }
  to   { transform: rotate( 17deg); }
}
@keyframes step-b {
  from { transform: rotate( 17deg); }
  to   { transform: rotate(-17deg); }
}


/* ── Beast (quadruped) walking animations ───────────────────────────────────── */
/*
 * Diagonal gait: FL+BR move together, FR+BL move together.
 * This matches real quadruped locomotion.
 */

.leg-fl, .leg-br {
  transform-box: fill-box;
  transform-origin: top center;
  animation: step-a 0.46s ease-in-out infinite alternate;
}
.leg-fr, .leg-bl {
  transform-box: fill-box;
  transform-origin: top center;
  animation: step-b 0.46s ease-in-out infinite alternate;
}


/* ── Brute walking animations ──────────────────────────────────────────────── */

.leg-brute-l {
  transform-box: fill-box;
  transform-origin: top center;
  animation: step-a 0.72s ease-in-out infinite alternate;
}
.leg-brute-r {
  transform-box: fill-box;
  transform-origin: top center;
  animation: step-b 0.72s ease-in-out infinite alternate;
}
.arm-brute-l {
  transform-box: fill-box;
  transform-origin: top right;
  animation: step-b 0.72s ease-in-out infinite alternate;
}


/* ── Dragon wing animations ────────────────────────────────────────────────── */

.wing-l {
  transform-box: fill-box;
  transform-origin: bottom center;
  animation: wing-flap 1.6s ease-in-out infinite alternate;
}
.wing-r {
  transform-box: fill-box;
  transform-origin: bottom center;
  animation: wing-flap 1.6s ease-in-out infinite alternate-reverse;
}

@keyframes wing-flap {
  from { transform: rotate(-4deg); }
  to   { transform: rotate(4deg); }
}


/* ── Undead shamble animations ─────────────────────────────────────────────── */

.leg-undead-l {
  transform-box: fill-box;
  transform-origin: top center;
  animation: step-a 0.9s ease-in-out infinite alternate;
}
.leg-undead-r {
  transform-box: fill-box;
  transform-origin: top center;
  animation: step-b 0.9s ease-in-out infinite alternate;
}
.arm-undead-l {
  transform-box: fill-box;
  transform-origin: right center;
  animation: step-b 0.9s ease-in-out infinite alternate;
}


/* ── Arcane float animations ───────────────────────────────────────────────── */

.arcane-core {
  animation: arcane-bob 2.4s ease-in-out infinite alternate;
}
.arcane-wisp-l {
  animation: arcane-bob 3.1s ease-in-out infinite alternate;
}
.arcane-wisp-r {
  animation: arcane-bob 2.7s ease-in-out infinite alternate-reverse;
}

@keyframes arcane-bob {
  from { transform: translateY(-2px); }
  to   { transform: translateY(2px); }
}


/* Carrier traverses left-to-right, loops */
@keyframes traverse {
  from { transform: translateX(-80px); }
  to   { transform: translateX(calc(100vw + 80px)); }
}


/* ── Encounter state ────────────────────────────────────────────────────────── */

/* Freeze all limb/wing/float animations while the carrier readies for combat */
#carrier-wrap.encounter-ready .leg-l,
#carrier-wrap.encounter-ready .leg-r,
#carrier-wrap.encounter-ready .arm-l,
#carrier-wrap.encounter-ready .leg-fl,
#carrier-wrap.encounter-ready .leg-fr,
#carrier-wrap.encounter-ready .leg-bl,
#carrier-wrap.encounter-ready .leg-br,
#carrier-wrap.encounter-ready .leg-brute-l,
#carrier-wrap.encounter-ready .leg-brute-r,
#carrier-wrap.encounter-ready .arm-brute-l,
#carrier-wrap.encounter-ready .wing-l,
#carrier-wrap.encounter-ready .wing-r,
#carrier-wrap.encounter-ready .leg-undead-l,
#carrier-wrap.encounter-ready .leg-undead-r,
#carrier-wrap.encounter-ready .arm-undead-l,
#carrier-wrap.encounter-ready .arcane-core,
#carrier-wrap.encounter-ready .arcane-wisp-l,
#carrier-wrap.encounter-ready .arcane-wisp-r {
  animation-play-state: paused;
}

/* Stop traversal too — they're standing still */
#carrier-wrap.encounter-ready {
  animation-play-state: paused;
}


/* ── Carrier death / departure states ──────────────────────────────────────── */

/* Stopped (abandon) and fallen (death): freeze traversal in place */
#carrier-wrap.carrier-stopped,
#carrier-wrap.carrier-fallen  { animation-play-state: paused; }

/* Freeze all limb/wing/float animations for both states */
#carrier-wrap.carrier-stopped .leg-l,    #carrier-wrap.carrier-stopped .leg-r,
#carrier-wrap.carrier-stopped .arm-l,
#carrier-wrap.carrier-stopped .leg-fl,   #carrier-wrap.carrier-stopped .leg-fr,
#carrier-wrap.carrier-stopped .leg-bl,   #carrier-wrap.carrier-stopped .leg-br,
#carrier-wrap.carrier-stopped .leg-brute-l, #carrier-wrap.carrier-stopped .leg-brute-r,
#carrier-wrap.carrier-stopped .arm-brute-l,
#carrier-wrap.carrier-stopped .wing-l,  #carrier-wrap.carrier-stopped .wing-r,
#carrier-wrap.carrier-stopped .leg-undead-l, #carrier-wrap.carrier-stopped .leg-undead-r,
#carrier-wrap.carrier-stopped .arm-undead-l,
#carrier-wrap.carrier-stopped .arcane-core, #carrier-wrap.carrier-stopped .arcane-wisp-l,
#carrier-wrap.carrier-stopped .arcane-wisp-r,
#carrier-wrap.carrier-fallen  .leg-l,    #carrier-wrap.carrier-fallen  .leg-r,
#carrier-wrap.carrier-fallen  .arm-l,
#carrier-wrap.carrier-fallen  .leg-fl,   #carrier-wrap.carrier-fallen  .leg-fr,
#carrier-wrap.carrier-fallen  .leg-bl,   #carrier-wrap.carrier-fallen  .leg-br,
#carrier-wrap.carrier-fallen  .leg-brute-l, #carrier-wrap.carrier-fallen  .leg-brute-r,
#carrier-wrap.carrier-fallen  .arm-brute-l,
#carrier-wrap.carrier-fallen  .wing-l,  #carrier-wrap.carrier-fallen  .wing-r,
#carrier-wrap.carrier-fallen  .leg-undead-l, #carrier-wrap.carrier-fallen  .leg-undead-r,
#carrier-wrap.carrier-fallen  .arm-undead-l,
#carrier-wrap.carrier-fallen  .arcane-core, #carrier-wrap.carrier-fallen  .arcane-wisp-l,
#carrier-wrap.carrier-fallen  .arcane-wisp-r  { animation-play-state: paused; }

/* Fallen: active silhouette tips forward ~85° pivoting from its feet */
#carrier-wrap.carrier-fallen .carrier-sil:not(.hidden) {
  transform-origin: 50% 100%;
  transform: rotate(85deg);
  transition: transform 0.5s ease-in;
}

/* Bag-only: body parts fade out, .bag element stays visible in place */
#carrier-wrap.carrier-bag-only .sil {
  opacity: 0;
  transition: opacity 0.8s ease;
}


/* Timer bar — drains across the terrain strip during the combat window */
#encounter-timer {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 3px;
  background: rgba(0, 0, 0, 0.35);
  z-index: 10;
  pointer-events: none;
}

#encounter-timer-fill {
  height: 100%;
  background: var(--text-danger);
  opacity: 0.85;
}


/* ── Main area ──────────────────────────────────────────────────────────────── */

#main {
  display: flex;
  flex: 1;
  min-height: 0;
}


/* ── Inventory panel — dark leather ────────────────────────────────────────── */

#inventory-panel {
  width: 210px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px 16px 16px;
  border-right: 2px solid var(--border-gold);
  background: var(--bg-panel);
  /* Subtle leather grain */
  background-image: repeating-linear-gradient(
    145deg,
    transparent,
    transparent 2px,
    rgba(0, 0, 0, 0.05) 2px,
    rgba(0, 0, 0, 0.05) 4px
  );
  gap: 16px;
  box-shadow: inset -4px 0 16px rgba(0, 0, 0, 0.5);
}

#bag-title {
  font-family: var(--font-title);
  font-size: 20px;
  letter-spacing: 0.14em;
  color: var(--text-gold);
  text-align: center;
  user-select: none;
  text-shadow: 0 1px 8px rgba(200, 150, 20, 0.45);
}

#inventory-grid {
  display: grid;
  gap: 8px;
}

#inventory-grid.grid-2 { grid-template-columns: repeat(2, 80px); }
#inventory-grid.grid-3 { grid-template-columns: repeat(3, 80px); }

.slot {
  width: 80px;
  height: 80px;
  background: var(--bg-slot);
  border: 1px solid var(--border-gold);
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: default;
  transition: border-color 0.15s;
  box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.6);
}

.slot:hover {
  border-color: #aa8840;
}

/* New slots appearing during bag expansion */
.slot.slot-new {
  animation: slot-appear 0.8s ease;
}

@keyframes slot-appear {
  from { opacity: 0; transform: scale(0.8); }
  to   { opacity: 1; transform: scale(1); }
}

.slot.drag-over {
  border-color: var(--text-gold);
  background: #221a0c;
}

/* Stack-merge target — same item type, quantities will combine */
.slot.drag-stack {
  border-color: var(--text-good);
  background: rgba(40, 80, 35, 0.30);
}

.slot.drag-stack .item-name::after {
  content: ' +';
  color: var(--text-good);
  font-size: 10px;
}

/* Craft-merge target — recipe match, items will combine into something new */
.slot.drag-craft {
  border-color: var(--text-magic);
  background: rgba(80, 40, 120, 0.25);
}

.slot.drag-craft .item-name::after {
  content: ' ✦';
  color: var(--text-magic);
  font-size: 9px;
}


/* ── Carrier HP display ─────────────────────────────────────────────────────── */

#carrier-info {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

#carrier-info.hidden { display: none; }

#carrier-label {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-dim);
  text-align: center;
  letter-spacing: 0.03em;
}

#hp-bar-wrap {
  width: 100%;
  height: 4px;
  background: var(--border);
  border-radius: 2px;
  overflow: hidden;
}

#hp-bar {
  height: 100%;
  width: 100%;
  background: #4a7a3a;
  border-radius: 2px;
  transition: width 0.6s ease, background-color 0.6s ease;
}


/* ── XP bar ────────────────────────────────────────────────────────────────── */

#xp-bar-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
}

#xp-level-label {
  font-family: var(--font-body);
  font-size: 8px;
  color: var(--text-gold);
  white-space: nowrap;
  min-width: 20px;
}

#xp-bar-outer {
  flex: 1;
  height: 3px;
  background: var(--border);
  border-radius: 1.5px;
  overflow: hidden;
}

#xp-bar {
  height: 100%;
  width: 0%;
  background: var(--text-gold);
  border-radius: 1.5px;
  transition: width 0.6s ease;
}

#xp-bar-wrap.xp-pulse #xp-bar {
  animation: xp-flash 0.8s ease;
}

@keyframes xp-flash {
  0%   { background: var(--text-gold); }
  40%  { background: #f0d060; }
  100% { background: var(--text-gold); }
}


/* ── Bag icon — the stomach, the self ──────────────────────────────────────── */

#bag-icon-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 4px 0 6px;
  border-top: 1px solid var(--border);
  cursor: default;
}

/* The bag body — same class as the carrier SVG bag, same magic hint */
.bag-body {
  fill: rgba(18, 10, 36, 0.90);
  stroke: rgba(160, 120, 220, 0.45);
  stroke-width: 1;
  transition: stroke 0.6s ease, fill 0.6s ease;
}

.bag-clasp {
  fill: rgba(160, 120, 220, 0.25);
  stroke: rgba(160, 120, 220, 0.5);
  stroke-width: 0.8;
  transition: fill 0.6s ease, stroke 0.6s ease;
}

/* Strap — replaces inline stroke attribute */
.bag-strap {
  stroke: rgba(160, 120, 220, 0.40);
  transition: stroke 0.8s ease;
}

/* Inner light — hidden until awareness grows; positioned behind body */
.bag-inner-light {
  fill: rgba(180, 130, 255, 1);
  opacity: 0;
}

/* Seam — stitching line, barely there at rest */
.bag-seam {
  stroke: rgba(160, 120, 220, 0.12);
  stroke-width: 0.6;
  stroke-dasharray: 2 2;
  transition: stroke 0.8s ease, opacity 0.8s ease;
}


/* ── Bag awareness states — the bag comes alive as lore accumulates ──────── */
/*
 * States (cumulative — each tier adds onto the previous):
 *   has-hp   : bag first gains HP — faint heartbeat begins
 *   aware-1  : seams begin to glow, slow breathing (4s)
 *   aware-2  : visible inner light, medium breathing (3s)
 *   aware-3  : unmistakably alive, fast breathing (2.2s), clasp lit
 *
 * Animations run on #bag-icon (SVG root) via filter: drop-shadow.
 * Inner light and seam brightness are animated separately via opacity.
 * Static stroke/fill changes stay on child elements (clean transitions).
 */

/* Stroke evolution — transitions handle the fade */
#bag-icon.aware-1 .bag-body   { stroke: rgba(160, 120, 220, 0.70); }
#bag-icon.aware-1 .bag-strap  { stroke: rgba(160, 120, 220, 0.60); }
#bag-icon.aware-1 .bag-seam   { stroke: rgba(160, 120, 220, 0.28); }

#bag-icon.aware-2 .bag-body   { stroke: rgba(180, 140, 240, 0.85); }
#bag-icon.aware-2 .bag-strap  { stroke: rgba(180, 140, 240, 0.75); }
#bag-icon.aware-2 .bag-seam   { stroke: rgba(180, 140, 240, 0.45); }

#bag-icon.aware-3 .bag-body   { fill: rgba(30, 14, 60, 0.92); stroke: rgba(200, 160, 255, 1); }
#bag-icon.aware-3 .bag-strap  { stroke: rgba(210, 170, 255, 0.95); }
#bag-icon.aware-3 .bag-seam   { stroke: rgba(200, 160, 255, 0.70); opacity: 1; }
#bag-icon.aware-3 .bag-clasp  { fill: rgba(190, 150, 255, 0.40); stroke: rgba(210, 170, 255, 0.85); }

/* Breathing animations — on the SVG root, filter controls the outer glow */
/* Ordered so higher tiers override lower: aware-3 > aware-2 > aware-1 > has-hp */
#bag-icon.has-hp  { animation: bag-heartbeat 3.5s ease-in-out infinite; }
#bag-icon.aware-1 { animation: bag-breathe-1 4.0s ease-in-out infinite; }
#bag-icon.aware-2 { animation: bag-breathe-2 3.0s ease-in-out infinite; }
#bag-icon.aware-3 { animation: bag-breathe-3 2.2s ease-in-out infinite; }

/* Inner light — opacity animation per tier */
#bag-icon.aware-1 .bag-inner-light { animation: bag-inner-1 4.0s ease-in-out infinite; }
#bag-icon.aware-2 .bag-inner-light { animation: bag-inner-2 3.0s ease-in-out infinite; }
#bag-icon.aware-3 .bag-inner-light { animation: bag-inner-3 2.2s ease-in-out infinite; }

/* Clasp pulse at aware-3 */
#bag-icon.aware-3 .bag-clasp { animation: bag-clasp-3 2.2s ease-in-out infinite; }

@keyframes bag-heartbeat {
  0%, 100% { filter: drop-shadow(0 0 1px rgba(140,  90, 200, 0.15)); }
  50%      { filter: drop-shadow(0 0 4px rgba(140,  90, 200, 0.32)); }
}
@keyframes bag-breathe-1 {
  0%, 100% { filter: drop-shadow(0 0 2px rgba(140,  90, 200, 0.28)); }
  50%      { filter: drop-shadow(0 0 7px rgba(140,  90, 200, 0.55)); }
}
@keyframes bag-breathe-2 {
  0%, 100% { filter: drop-shadow(0 0 4px rgba(160, 100, 220, 0.45)); }
  50%      { filter: drop-shadow(0 0 12px rgba(160, 100, 220, 0.78)); }
}
@keyframes bag-breathe-3 {
  0%, 100% { filter: drop-shadow(0 0 7px rgba(180, 120, 255, 0.65)); }
  50%      { filter: drop-shadow(0 0 18px rgba(180, 120, 255, 0.95)); }
}

@keyframes bag-inner-1 {
  0%, 100% { opacity: 0.04; }
  50%      { opacity: 0.10; }
}
@keyframes bag-inner-2 {
  0%, 100% { opacity: 0.10; }
  50%      { opacity: 0.20; }
}
@keyframes bag-inner-3 {
  0%, 100% { opacity: 0.18; }
  50%      { opacity: 0.34; }
}

@keyframes bag-clasp-3 {
  0%, 100% { fill: rgba(190, 150, 255, 0.30); stroke: rgba(210, 170, 255, 0.70); }
  50%      { fill: rgba(210, 170, 255, 0.55); stroke: rgba(225, 195, 255, 1.00); }
}

/* Tier unlock flash — brief bright pulse on the wrap when awareness advances */
#bag-icon-wrap.bag-unlock {
  animation: bag-unlock-flash 0.85s ease-out forwards;
}
@keyframes bag-unlock-flash {
  0%   { box-shadow: none; }
  20%  { box-shadow: 0 0 22px rgba(200, 160, 255, 0.80); }
  100% { box-shadow: none; }
}

/* Drag-over state — bag pulses when a valid item hovers over it */
#bag-icon-wrap.bag-drag-over .bag-body {
  stroke: rgba(200, 160, 255, 0.9);
  fill: rgba(40, 20, 70, 0.95);
}

/* Bag HP bar — distinct from carrier bar (purple vs green) */
#bag-hp-wrap {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
#bag-hp-wrap.hidden { display: none; }

#bag-hp-label {
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--text-magic);
  letter-spacing: 0.04em;
}

#bag-hp-bar-outer {
  width: 100%;
  height: 3px;
  background: var(--border);
  border-radius: 2px;
  overflow: hidden;
}

#bag-hp-bar {
  height: 100%;
  width: 100%;
  background: #7040b0;
  border-radius: 2px;
  transition: width 0.5s ease, background-color 0.5s ease;
}


/* ── Lore bar — three segments, one per awareness tier ─────────────────────── */
/*
 * Segment proportions reflect each tier's point range:
 *   seg-0: flex 3  (0→3 pts)
 *   seg-1: flex 5  (3→8 pts)
 *   seg-2: flex 8  (8→16 pts)
 * Each segment fills via --fill CSS custom property until the tier is crossed,
 * then gets .active (fully lit).
 */

#bag-lore-wrap {
  width: 100%;
  margin-top: 2px;
}
#bag-lore-wrap.hidden { display: none; }

#bag-lore-bar-outer {
  display: flex;
  gap: 2px;
  width: 100%;
}

.lore-seg {
  height: 3px;
  background: var(--border);
  border-radius: 2px;
  position: relative;
  overflow: hidden;
}

#lore-seg-0 { flex: 3; }
#lore-seg-1 { flex: 5; }
#lore-seg-2 { flex: 8; }

/* Partial fill — JS sets --fill via style.setProperty */
.lore-seg::after {
  content: '';
  position: absolute;
  left: 0; top: 0;
  height: 100%;
  width: var(--fill, 0%);
  background: var(--ink-gold);
  opacity: 0.85;
  transition: width 0.5s ease;
}

/* Full tier unlocked */
.lore-seg.active::after {
  width: 100%;
}

/* Pulse on tier unlock */
.lore-seg.lore-pulse {
  animation: lore-pulse 1.1s ease;
}
@keyframes lore-pulse {
  0%   { opacity: 1; }
  30%  { opacity: 0.2; }
  60%  { opacity: 1; }
  80%  { opacity: 0.5; }
  100% { opacity: 1; }
}


/* ── Lore fragment bar ───────────────────────────────────────────────────────── */
/*
 * Parallel to the awareness bar above it. Tracks fragment delivery toward
 * the three act milestones. Single continuous fill; three pip markers.
 */

#lore-frag-wrap {
  width: 100%;
  margin-top: 3px;
}
#lore-frag-wrap.hidden { display: none; }

#lore-frag-bar-outer {
  position: relative;
  width: 100%;
  height: 3px;
  background: var(--border);
  border-radius: 2px;
  overflow: visible;
}

#lore-frag-fill {
  position: absolute;
  left: 0; top: 0;
  height: 100%;
  width: 0%;
  background: var(--ink-magic);
  opacity: 0.6;
  border-radius: 2px;
  transition: width 0.8s ease;
}

/* Milestone pip — sits on the bar at a threshold position */
.lore-pip {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--border);
  border: 1px solid var(--text-dim);
  transition: background 0.6s ease, border-color 0.6s ease, box-shadow 0.6s ease;
}

/* Pip lit when its milestone fires */
.lore-pip.reached {
  background: var(--ink-magic);
  border-color: var(--ink-magic);
  box-shadow: 0 0 4px rgba(120, 88, 176, 0.6);
}


/* ── Lore fragment log entry classes ─────────────────────────────────────────── */
/*
 * Four item-category classes (matching fragmentCat 1-4) plus two special:
 *   lore-dream    — Cat 5 recovered memory; surfaces from sleep, no framing
 *   lore-glimmer  — milestone narrator-slip; first-person, deniable
 *   lore-marker   — ✦ / ⋯ / — glyphs preceding a fragment; muted
 *   lore-ellipsis — pause glyph for dream and glimmer sequences
 */

/* Cat 1 — Varek's notes: cold scholarly ink, purple tint (his voice) */
.log-lore-cat1 {
  color: #5a3a78;
  font-style: italic;
  padding-left: 10px;
  border-left: 2px solid rgba(90, 58, 120, 0.35);
  line-height: 1.75;
}

/* Cat 2 — Carrier journals: warm sepia, handwritten feel */
.log-lore-cat2 {
  color: #6b4420;
  font-style: italic;
  padding-left: 10px;
  border-left: 2px solid rgba(107, 68, 32, 0.35);
  line-height: 1.75;
}

/* Cat 3 — Scholarly correspondence: cooler brown, formal */
.log-lore-cat3 {
  color: #4a4030;
  font-style: italic;
  padding-left: 10px;
  border-left: 2px solid rgba(74, 64, 48, 0.35);
  line-height: 1.75;
}

/* Cat 4 — Religious/superstitious: darkest ink, weight of repetition */
.log-lore-cat4 {
  color: #3a3028;
  font-style: italic;
  padding-left: 10px;
  border-left: 2px solid rgba(58, 48, 40, 0.35);
  line-height: 1.75;
}

/* Cat 5 — Recovered memory: no border, no frame; reads as pure interior */
.log-lore-dream {
  color: #4a3060;
  font-style: italic;
  line-height: 1.8;
  letter-spacing: 0.01em;
}

/* Milestone glimmer — narrator slip; slightly lighter than dream */
.log-lore-glimmer {
  color: #5c4070;
  font-style: italic;
  opacity: 0.85;
  line-height: 1.8;
}

/* Glyph prefix — ✦ before item fragments, ⋯ before dream / — for glimmer pauses */
.log-lore-marker {
  color: var(--ink-dim);
  opacity: 0.5;
  font-style: normal;
  user-select: none;
}

/* Ellipsis pause glyph — same as marker but used mid-sequence */
.log-lore-ellipsis {
  color: var(--ink-dim);
  opacity: 0.4;
  font-style: normal;
  user-select: none;
  letter-spacing: 0.15em;
}


/* ── Encounter speech interactivity ─────────────────────────────────────────── */

/* Words in interactive speech have a subtle dotted underline when hoverable */
.encounter-speech-interactive .speech-word {
  cursor: crosshair;
  border-bottom: 1px dotted rgba(120, 80, 40, 0.35);
  transition: background 0.1s;
}

.encounter-speech-interactive .speech-word:hover {
  background: rgba(120, 80, 40, 0.12);
  border-radius: 2px;
}

/* Threat words — faint red tint when interactive */
.encounter-speech-interactive .speech-word[data-role="threat"]:hover {
  background: rgba(150, 40, 40, 0.10);
}

/* Target words — faint gold tint when interactive */
.encounter-speech-interactive .speech-word[data-role="target"]:hover {
  background: rgba(160, 120, 20, 0.12);
}

/* Smudged speech word */
.speech-word.smudged {
  color: var(--ink-dim);
  letter-spacing: -0.5px;
  opacity: 0.7;
  border-bottom-style: none;
  cursor: default;
}

/* Ripped word — hidden */
.speech-word.ripped {
  display: none;
}

/* Falsified word — magic color, dotted underline */
.speech-word.falsified {
  color: var(--ink-magic);
  text-decoration: underline dotted;
  border-bottom-style: none;
}

/* Once window closes, no more crosshair */
.speech-word[style*="pointer-events: none"] {
  cursor: default;
  border-bottom-style: none;
}


/* ── Game over — "Begin again." ─────────────────────────────────────────────── */

.log-begin-again {
  color: var(--ink-dim);
  font-style: italic;
  font-size: 13px;
  margin-top: 24px;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.3s;
  animation: appear 1.2s ease-out both;
}
.log-begin-again:hover {
  opacity: 1;
  color: var(--ink);
}


/* ── Status line ────────────────────────────────────────────────────────────── */

#status-line {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-dim);
  text-align: center;
  line-height: 1.4;
  margin-top: auto;
  padding-top: 8px;
  transition: color 0.4s;
}


/* ── Stats panel ─────────────────────────────────────────────────────────────── */

#stats-panel {
  border-top: 1px solid var(--border);
  padding: 10px 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.stat-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.stat-label {
  font-size: 10px;
  font-family: var(--font-mono);
  color: var(--text-dim);
  letter-spacing: 0.04em;
  text-transform: lowercase;
}

.stat-val {
  font-size: 11px;
  font-family: var(--font-mono);
  color: var(--text-gold);
  min-width: 20px;
  text-align: right;
}


/* ── Equipped panel ──────────────────────────────────────────────────────────── */

#equipped-panel {
  border-top: 1px solid var(--border);
  padding: 8px 14px 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  box-sizing: border-box;
}

#equipped-panel.hidden { display: none; }
#stat-absorbed-row.hidden { display: none; }

/* 'none' renders dim; an actual item name renders gold (via .stat-val default) */
#equipped-weapon[data-empty="true"],
#equipped-armor[data-empty="true"]  { color: var(--text-dim); }

/* Truncate long item names cleanly */
#equipped-weapon,
#equipped-armor {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 120px;
}


/* ── Log panel — aged parchment ─────────────────────────────────────────────── */

#log-panel {
  flex: 1;
  overflow-y: auto;
  padding: 24px 32px;
  background: var(--bg-log);
  /* Parchment vignette — subtle darkening at edges */
  box-shadow:
    inset  8px 0 24px rgba(100, 70, 20, 0.10),
    inset -8px 0 24px rgba(100, 70, 20, 0.10),
    inset  0  8px 24px rgba(80,  50, 10, 0.08),
    inset  0 -8px 24px rgba(80,  50, 10, 0.08);
}

#log-panel::-webkit-scrollbar       { width: 5px; }
#log-panel::-webkit-scrollbar-track { background: #d8c8a0; }
#log-panel::-webkit-scrollbar-thumb { background: var(--border-parch); border-radius: 2px; }

#log-entries {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: 680px;
}

.log-entry {
  animation: appear 0.3s ease-out both;
  line-height: 1.7;
  font-family: var(--font-serif);
  font-size: 15px;
}

/* Log types — ink on parchment */
.log-normal  { color: var(--ink); }
.log-dim     { color: var(--ink-dim); font-style: italic; }
.log-gold    { color: var(--ink-gold); }
.log-magic   { color: var(--ink-magic); }
.log-danger  { color: var(--ink-danger); }
.log-good    { color: var(--ink-good); }
.log-lore    {
  color: var(--ink-magic);
  font-style: italic;
  border-left: 2px solid rgba(60, 26, 96, 0.4);
  padding-left: 10px;
}

/* Enemy speech during encounters — heard dialogue, not narration */
.log-encounter {
  color: var(--ink-dim);
  font-style: italic;
  padding-left: 1.4em;
  border-left: 2px solid var(--border-parch);
  opacity: 0.9;
}

/* ── Journal entries — the carrier's handwriting, not the narrator ───────────── */

.log-journal {
  color: #5a3a10;
  font-style: italic;
  padding-left: 14px;
  border-left: 1px solid rgba(90, 58, 16, 0.35);
  line-height: 1.75;
}

/* Glyph prefix — non-interactive */
.journal-glyph {
  opacity: 0.55;
  font-style: normal;
  user-select: none;
}

/* Individual word spans */
.journal-word {
  display: inline;
  border-radius: 2px;
  transition: background 0.1s;
  cursor: default;
}

/* Active window — ink is wet, words are interactive */
.journal-active .journal-word {
  cursor: crosshair;
}
.journal-active .journal-word:hover {
  background: rgba(90, 58, 16, 0.12);
}

/* Rip handle — the ✦ glyph becomes interactive at aware-1 */
/* No tooltip, no label — discoverable by cursor change and hover tint */
.journal-rip-available {
  cursor: pointer;
  transition: color 0.15s, opacity 0.15s;
}

.journal-rip-available:hover {
  color: #7a2020;
  opacity: 0.9;
}

/* Tear animation — plays when the entry is ripped, then element is removed */
@keyframes journal-tear {
  0%   { opacity: 1;   transform: none;                          filter: none;              }
  25%  { opacity: 0.7; transform: skewX(-3deg) translateY(-3px); filter: brightness(0.6);   }
  100% { opacity: 0;   transform: skewX(6deg)  translateY(-12px); filter: brightness(0) sepia(1) hue-rotate(300deg); }
}

.journal-tearing {
  animation: journal-tear 0.38s ease-in forwards;
  pointer-events: none;
}


/* Smudged word — ink blot */
.journal-word.smudged {
  color: #2a1a06;
  background: rgba(40, 20, 5, 0.18);
  border-radius: 2px;
  letter-spacing: 0.04em;
  cursor: default;
}

/* Falsified word — rewritten in slightly different ink */
.journal-word.falsified {
  color: #3a2060;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 3px;
  cursor: default;
}

/* Dry state — window closed, words no longer interactive */
.journal-dry .journal-word {
  cursor: default;
}
.journal-dry .journal-word:hover {
  background: none;
}

/* Undead entry — cold, washed out, wrong */
.journal-undead {
  color: #6a7060;
  letter-spacing: 0.04em;
}

/* Aberration entry — something is wrong with the ink itself */
.journal-aberration {
  color: #3a2848;
  filter: blur(0.4px);
  letter-spacing: 0.06em;
}
.journal-aberration .journal-word:hover {
  background: rgba(80, 20, 120, 0.12);
  filter: blur(0px);
  cursor: crosshair;
}

/* Inline falsify input */
.journal-falsify-input {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 15px;
  color: #3a2060;
  background: rgba(200, 180, 240, 0.15);
  border: none;
  border-bottom: 1px solid #3a2060;
  outline: none;
  width: 7ch;
  padding: 0 2px;
  line-height: 1.75;
}

/* Decorative separator — ornamental rule with center diamond */
.log-sep {
  border: none;
  border-top: 1px solid var(--border-parch);
  margin: 8px 0;
  position: relative;
  height: 1px;
  overflow: visible;
}
.log-sep::before {
  content: '◆';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: var(--bg-log);
  color: var(--border-parch);
  font-size: 9px;
  padding: 0 7px;
  line-height: 1;
}

@keyframes appear {
  from { opacity: 0; transform: translateY(3px); }
  to   { opacity: 1; transform: translateY(0); }
}


/* ── Item display inside inventory slots ────────────────────────────────────── */

.item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  gap: 3px;
  cursor: grab;
  animation: appear 0.3s ease-out both;
}

.item:active { cursor: grabbing; }

/* ── Enchantment visual tells ────────────────────────────────────────────────
   Subtle enough that a new player won't notice immediately.
   Experienced players learn to read the tint before committing a slot.    */

.item.item-enchanted {
  background: rgba(50, 80, 20, 0.30);
}
.item.item-enchanted .item-symbol {
  filter: drop-shadow(0 0 4px rgba(100, 155, 40, 0.45));
}

.item.item-cursed {
  background: rgba(70, 12, 8, 0.30);
}
.item.item-cursed .item-symbol {
  filter: drop-shadow(0 0 4px rgba(150, 35, 20, 0.35));
}

.item-symbol {
  font-size: 28px;
  line-height: 1;
  user-select: none;
}

.item-name {
  font-family: var(--font-mono);
  font-size: 8px;
  text-align: center;
  color: var(--text-dim);
  max-width: 72px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.2;
  user-select: none;
}

/* Stack quantity badge — anchored top-right so it never truncates with the name */
.item-qty {
  position: absolute;
  top: 2px;
  right: 3px;
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--text-gold);
  line-height: 1;
  pointer-events: none;
}

/* Attribute indicator dots */
.item-tags {
  display: flex;
  gap: 3px;
}

/* Subtle ink shifts for item attributes — no dots, just slightly different ink */
.item-name.ink-damage     { color: #7a4a3a; }
.item-name.ink-protection { color: #4a5a6a; }
.item-name.ink-magic      { color: #6a5070; }
.item-name.ink-lore       { color: #5a5848; }

/* ── Item context menu (right-click) ──────────────────────────────────────── */
#item-ctx-menu {
  position: fixed;
  z-index: 200;
  background: var(--bg-leather);
  border: 1px solid var(--border-gold);
  border-radius: 3px;
  padding: 2px 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
  min-width: 90px;
}

.ctx-option {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-dim);
  padding: 5px 10px;
  cursor: pointer;
  white-space: nowrap;
}

.ctx-option:hover {
  color: var(--text-gold);
  background: rgba(60, 40, 10, 0.40);
}

/* Source slot while dragging — dims to show item has "left" */
.slot.dragging {
  opacity: 0.35;
}

/* Item arrival animation — pops in when item first appears */
@keyframes item-arrive {
  0%   { opacity: 0; transform: scale(0.6); }
  70%  { transform: scale(1.08); }
  100% { opacity: 1; transform: scale(1); }
}

.item.arriving {
  animation: item-arrive 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}


/* ── Navigation items (maps) ────────────────────────────────────────────────── */

/* Subtle cursor hint — maps are clickable */
.item.item-nav {
  cursor: pointer;
}

.item.item-nav:hover {
  background: rgba(60, 40, 10, 0.40);
  outline: 1px solid var(--border-gold);
}


/* ── Minimap ─────────────────────────────────────────────────────────────────── */

#minimap {
  position: absolute;
  top: 6px;
  right: 10px;
  font-family: var(--font-serif);
  font-size: 10px;
  color: rgba(200, 184, 144, 0.55);
  letter-spacing: 0.03em;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.8s ease;
  white-space: nowrap;
}

#minimap.hidden {
  display: none;
}

#minimap.revealed {
  opacity: 1;
}

.mm-here {
  color: rgba(200, 184, 144, 0.80);
}

.mm-arrow {
  color: rgba(138, 106, 40, 0.60);
  margin: 0 2px;
}

.mm-dest {
  color: rgba(200, 184, 144, 0.55);
}

/* Folded map — destination unknowable */
.mm-dest.mm-folded {
  color: rgba(100, 80, 50, 0.60);
  font-style: italic;
}

/* Torn map — destination uncertain */
.mm-dest.mm-torn {
  color: rgba(150, 120, 70, 0.60);
}

/* Map destroyed — destination still shows but faded, memory only */
.mm-arrow.mm-gone,
.mm-dest.mm-gone {
  color: rgba(100, 80, 50, 0.40);
}


/* ── Map inspect panel ───────────────────────────────────────────────────────── */

#map-inspect {
  position: relative;
  margin: 8px 0 4px;
  padding: 10px 12px 10px;
  background: rgba(14, 8, 4, 0.85);
  border: 1px solid var(--border-gold);
  border-radius: 3px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

#map-inspect.hidden {
  display: none;
}

#map-inspect-name {
  font-family: var(--font-serif);
  font-size: 11px;
  color: var(--text-gold);
  letter-spacing: 0.05em;
  font-style: italic;
}

#map-inspect-actions {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.map-action {
  background: none;
  border: 1px solid var(--border);
  border-radius: 2px;
  color: var(--text-dim);
  font-family: var(--font-serif);
  font-size: 10px;
  padding: 4px 8px;
  cursor: pointer;
  text-align: left;
  transition: border-color 0.15s, color 0.15s;
}

.map-action:hover:not(:disabled) {
  border-color: var(--border-gold);
  color: var(--text);
}

.map-action:disabled {
  opacity: 0.30;
  cursor: default;
}

/* Destroy is slightly more emphatic */
#map-action-destroy {
  border-color: rgba(100, 30, 20, 0.50);
  color: rgba(152, 48, 48, 0.65);
}

#map-action-destroy:hover:not(:disabled) {
  border-color: var(--text-danger);
  color: var(--text-danger);
}

#map-inspect-close {
  position: absolute;
  top: 6px;
  right: 8px;
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 10px;
  cursor: pointer;
  line-height: 1;
  padding: 2px 4px;
  opacity: 0.6;
}

#map-inspect-close:hover {
  opacity: 1;
  color: var(--text);
}
