/* Vigor — combined-pool combat front-end. Torch-lit dark fantasy. */ :root { --bg: #0a0807; --panel: #15110d; --panel-edge: #2a2018; --ink: #e8dcc8; --ink-dim: #9c8a72; --gold: #e8a13a; --ember: #ff7a2a; /* Vigor bar zones */ --fill: #6fd08a; /* current vigor — bright life */ --fill-glow: #b9ffce; --cap: #3a5d50; /* regen headroom (cap - fill) */ --fatigue: #43160f; /* lost ceiling — dark, cracked */ --ceiling: #ffd98a; --hit: #ff5b4a; --heal: #7dffb0; --curse: #c77dff; --daze: #ffd24a; font-size: 16px; } * { box-sizing: border-box; } html, body { margin: 0; height: 100%; background: radial-gradient(120% 90% at 50% -10%, #1c150e 0%, var(--bg) 60%); color: var(--ink); font-family: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif; -webkit-font-smoothing: antialiased; } #app { height: 100%; } .screen { min-height: 100%; display: flex; flex-direction: column; } .hidden { display: none !important; } /* ── Masthead / start ─────────────────────────────────────────────── */ .masthead { text-align: center; padding: 3rem 1rem 1rem; } .masthead h1 { margin: 0; font-size: 4rem; letter-spacing: 0.4rem; color: var(--gold); text-shadow: 0 0 18px rgba(232, 161, 58, 0.45), 0 2px 0 #000; } .tagline { color: var(--ink-dim); font-style: italic; margin: 0.3rem 0 0; } .roster { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 1.1rem; max-width: 1080px; margin: 1.5rem auto; padding: 0 1.5rem; width: 100%; } .foe { background: var(--panel); border: 1px solid var(--panel-edge); border-radius: 10px; overflow: hidden; cursor: pointer; transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease; display: flex; flex-direction: column; } .foe:hover { transform: translateY(-4px); border-color: var(--gold); box-shadow: 0 10px 30px rgba(0,0,0,0.6), 0 0 22px rgba(232,161,58,0.18); } .foe img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; filter: saturate(0.92) contrast(1.04); } .foe .fmeta { padding: 0.6rem 0.75rem 0.85rem; } .foe .fname { font-size: 1.15rem; color: var(--gold); } .foe .fblurb { color: var(--ink-dim); font-size: 0.82rem; margin-top: 0.2rem; line-height: 1.3; } .legend { display: flex; flex-wrap: wrap; gap: 1.2rem; justify-content: center; color: var(--ink-dim); font-size: 0.8rem; padding: 1rem 1rem 2rem; } .swatch { display: inline-block; width: 0.9rem; height: 0.9rem; border-radius: 2px; vertical-align: -1px; margin-right: 0.3rem; } .swatch.fill { background: var(--fill); } .swatch.cap { background: var(--cap); } .swatch.fatigue { background: var(--fatigue); } /* ── Battle arena ─────────────────────────────────────────────────── */ #battle { padding: 1rem; gap: 1rem; } .arena { flex: 1; display: grid; grid-template-rows: 1fr auto 1fr; gap: 0.5rem; max-width: 760px; margin: 0 auto; width: 100%; } .combatant { display: flex; flex-direction: column; gap: 0.5rem; } .combatant.enemy { align-items: center; justify-content: flex-end; } .combatant.player { align-items: center; justify-content: flex-start; } .portrait-wrap { position: relative; } .portrait { width: 184px; height: 184px; object-fit: cover; border-radius: 10px; border: 2px solid var(--panel-edge); box-shadow: 0 8px 28px rgba(0,0,0,0.7), inset 0 0 40px rgba(0,0,0,0.5); filter: saturate(0.95) contrast(1.05); transition: filter 0.2s, transform 0.08s; } .combatant.hurt .portrait { animation: shake 0.18s; } .combatant.down .portrait { filter: grayscale(0.85) brightness(0.5); } @keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } } .nameplate { display: flex; align-items: baseline; gap: 0.5rem; } .cname { font-size: 1.3rem; color: var(--gold); } .clevel { color: var(--ink-dim); font-size: 0.85rem; } /* The signature dual Vigor bar */ .vbar-mount { width: min(440px, 90vw); } .vbar { position: relative; height: 26px; background: var(--fatigue); /* exposed base = lost ceiling */ border: 1px solid #000; border-radius: 5px; overflow: hidden; box-shadow: inset 0 2px 6px rgba(0,0,0,0.6); background-image: repeating-linear-gradient( /* cracked texture on fatigue zone */ -45deg, transparent 0 6px, rgba(0,0,0,0.18) 6px 7px); } .vbar-cap { position: absolute; left: 0; top: 0; bottom: 0; background: linear-gradient(var(--cap), #24403a); transition: width 0.12s linear; } .vbar-fill { position: absolute; left: 0; top: 0; bottom: 0; background: linear-gradient(180deg, var(--fill-glow), var(--fill) 55%, #2f8f57); box-shadow: 0 0 10px rgba(111,208,138,0.5); transition: width 0.12s linear; } .vbar-ceiling { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--ceiling); box-shadow: 0 0 6px var(--ceiling); transition: left 0.12s linear; } .vbar-num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 0.8rem; color: #06140c; font-weight: 700; text-shadow: 0 1px 0 rgba(255,255,255,0.25); font-family: ui-monospace, monospace; } .vbar.dazed .vbar-fill { background: linear-gradient(180deg, #ffe9a0, var(--daze) 60%, #b9821a); } .vbar.down .vbar-fill { background: #555; box-shadow: none; } .statusrow { display: flex; gap: 0.3rem; min-height: 1.5rem; flex-wrap: wrap; justify-content: center; } .chip { font-size: 0.68rem; padding: 0.12rem 0.45rem; border-radius: 999px; background: #241a12; border: 1px solid var(--panel-edge); color: var(--ink-dim); } .chip.dazed { background: #4a3a12; color: var(--daze); border-color: var(--daze); } .chip.dot { color: #9fd06f; } .chip.regen_sabotage, .chip.fatigue_amp { color: var(--curse); } .chip.mitigation { color: #7fd4ff; } .chip.hot { color: var(--heal); } /* cast / telegraph */ .cast { position: absolute; left: 50%; transform: translateX(-50%); bottom: -10px; width: 160px; background: rgba(0,0,0,0.7); border: 1px solid var(--ember); border-radius: 4px; padding: 2px 4px; text-align: center; } .cast-label { font-size: 0.72rem; color: var(--ember); } .cast-fill { height: 4px; background: var(--ember); width: 0%; margin-top: 2px; border-radius: 2px; box-shadow: 0 0 8px var(--ember); } .combatant.enemy.casting .portrait { box-shadow: 0 0 28px rgba(255,122,42,0.6), 0 8px 28px rgba(0,0,0,0.7); } /* ── Midline: floaters + log ──────────────────────────────────────── */ .midline { position: relative; display: flex; align-items: center; justify-content: center; } .vs { color: #3a2c1c; font-size: 2rem; } .floaters { position: absolute; inset: -60px 0; pointer-events: none; } .floater { position: absolute; left: 50%; font-weight: 700; font-family: ui-monospace, monospace; font-size: 1.4rem; text-shadow: 0 2px 3px #000; animation: float-up 1.1s ease-out forwards; } .floater.up { transform: translateX(-50%); top: 10%; } /* damage to enemy (player dealt) */ .floater.down { transform: translateX(-50%); bottom: 10%; } /* damage to player */ .floater.hit { color: var(--hit); } .floater.heal { color: var(--heal); } .floater.curse { color: var(--curse); } .floater.crit { font-size: 2rem; color: var(--daze); } @keyframes float-up { 0% { opacity: 0; transform: translate(-50%, 10px) scale(0.8); } 15% { opacity: 1; transform: translate(-50%, 0) scale(1.1); } 100% { opacity: 0; transform: translate(-50%, -50px) scale(1); } } /* ── HUD ──────────────────────────────────────────────────────────── */ .hud { display: flex; gap: 1rem; max-width: 900px; margin: 0 auto; width: 100%; align-items: stretch; } .actionbar { display: flex; gap: 0.5rem; flex-wrap: wrap; flex: 1; align-content: flex-start; } .ability { min-width: 92px; padding: 0.5rem 0.6rem; border-radius: 8px; cursor: pointer; background: var(--panel); border: 1px solid var(--panel-edge); color: var(--ink); text-align: left; position: relative; transition: border-color 0.1s, transform 0.06s; font-family: inherit; } .ability:hover:not(:disabled) { border-color: var(--gold); transform: translateY(-2px); } .ability:disabled { opacity: 0.4; cursor: not-allowed; } .ability .akey { position: absolute; top: 3px; right: 6px; font-size: 0.7rem; color: var(--ink-dim); } .ability .aname { font-size: 0.9rem; display: block; } .ability .acost { font-size: 0.72rem; color: var(--ink-dim); font-family: ui-monospace, monospace; } .ability .acd { position: absolute; inset: 0; background: rgba(0,0,0,0.6); border-radius: 8px; display: flex; align-items: center; justify-content: center; font-family: ui-monospace, monospace; font-size: 1.1rem; color: var(--ink); } .ability[data-kind="auto"] { border-left: 3px solid #8a8a8a; } .ability[data-kind="skill"] { border-left: 3px solid #b9c6d6; } .ability[data-kind="spell"] { border-left: 3px solid #5aa6ff; } .ability[data-kind="curse"] { border-left: 3px solid var(--curse); } .ability[data-kind="dot"] { border-left: 3px solid #9fd06f; } .ability[data-kind="recovery"] { border-left: 3px solid var(--heal); } .ability[data-kind="defense"] { border-left: 3px solid #7fd4ff; } .hud-side { width: 260px; display: flex; flex-direction: column; gap: 0.5rem; } .auto { padding: 0.35rem; border-radius: 6px; cursor: pointer; font-family: inherit; background: var(--panel); border: 1px solid var(--panel-edge); color: var(--ink-dim); } .auto.on { color: var(--gold); border-color: var(--gold); } .log { flex: 1; min-height: 84px; max-height: 130px; overflow-y: auto; background: #0d0a07; border: 1px solid var(--panel-edge); border-radius: 6px; padding: 0.4rem 0.55rem; font-size: 0.78rem; color: var(--ink-dim); line-height: 1.45; } .log .lhit { color: #e8b98a; } .log .lcurse { color: var(--curse); } .log .lheal { color: var(--heal); } .log .lbig { color: var(--daze); font-weight: 700; } .log .lcast { color: var(--ember); } /* ── Result overlay ───────────────────────────────────────────────── */ .overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.78); display: flex; align-items: center; justify-content: center; z-index: 10; } .result-card { background: var(--panel); border: 1px solid var(--panel-edge); border-radius: 12px; padding: 2rem 2.5rem; text-align: center; box-shadow: 0 20px 60px rgba(0,0,0,0.8); } .result-card h2 { margin: 0 0 0.4rem; font-size: 2.4rem; letter-spacing: 0.1rem; } .result-card.win h2 { color: var(--fill); text-shadow: 0 0 20px rgba(111,208,138,0.4); } .result-card.lose h2 { color: var(--hit); text-shadow: 0 0 20px rgba(255,91,74,0.4); } .result-card p { color: var(--ink-dim); margin: 0 0 1.4rem; } .result-actions { display: flex; gap: 0.75rem; justify-content: center; } .result-actions button { padding: 0.6rem 1.2rem; border-radius: 8px; cursor: pointer; font-family: inherit; font-size: 1rem; background: #241a12; border: 1px solid var(--gold); color: var(--gold); } .result-actions button:hover { background: var(--gold); color: #1a1109; }