/* Forever Warlocking - the screen around the 3D scene.
   Quiet on purpose: dark glass, one accent colour (violet), and colour only where it means something
   (health, mana, hostile, a crit). You, your pet and your target sit in the bottom centre above the action bar. */

:root {
  --glass: rgba(20, 11, 30, 0.74);
  --glass-solid: rgba(17, 9, 26, 0.96);
  --line: rgba(205, 170, 255, 0.14);
  --line-bright: rgba(205, 170, 255, 0.42);
  --ink: #f2ecf8;
  --ink-dim: #a999bd;
  --accent: #b98aff;
  --gold: #f0cf7a;
  --health: #3fae5f;
  --mana: #4a78e0;
  --hostile: #cf4038;
  --bad: #ff8478;
  --slot: rgba(255, 255, 255, 0.05);
}

* { box-sizing: border-box; }
/* Anything marked hidden stays hidden, whatever layout it has. */
[hidden] { display: none !important; }

html, body { height: 100%; margin: 0; overflow: hidden; background: #0e0716; color: var(--ink); }
body { font: 13px/1.35 "Segoe UI", system-ui, sans-serif; }

#scene { position: fixed; inset: 0; width: 100%; height: 100%; display: block; cursor: grab; touch-action: none; }
#scene.steer { cursor: none; }
#scene.look { cursor: grabbing; }

/* Layers, from the back: the scene, plates and damage numbers, the frames and panels, the review, tooltips. */
#hud { position: fixed; inset: 0; z-index: 2; pointer-events: none; user-select: none; }
#hud button, #hud input, #hud textarea, #hud label, #hud form, #hud .aura { pointer-events: auto; }

/* --- Buttons, cards, forms ---------------------------------------------- */
button {
  font: inherit; font-size: 12px; color: var(--ink);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid transparent;
  border-radius: 6px; padding: 4px 9px; cursor: pointer;
}
button:hover { background: rgba(255, 255, 255, 0.13); }
button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
button.on { color: var(--accent); background: rgba(185, 138, 255, 0.14); border-color: rgba(185, 138, 255, 0.35); }
button.wide { display: block; width: 100%; margin-top: 8px; }

.panel { background: var(--glass-solid); border: 1px solid var(--line); border-radius: 10px; padding: 10px; }
.panel h2 { margin: 0 0 6px; font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-dim); }

#hud input, #hud textarea { user-select: text; font: inherit; font-size: 12px; color: var(--ink); background: rgba(0, 0, 0, 0.5); border: 1px solid var(--line); border-radius: 5px; padding: 2px 5px; }
#hud input[type="number"] { width: 62px; }
#hud input:focus, #hud textarea:focus { outline: 1px solid var(--accent); }
#hud textarea { display: block; width: 100%; margin-top: 3px; resize: vertical; font-family: ui-monospace, Consolas, monospace; font-size: 11px; }
.form, #importPanel { display: grid; gap: 8px; }
.form label, #importPanel label { display: block; font-size: 12px; }
.hint { margin: 0; font-size: 11px; color: var(--ink-dim); }
.hint.bad { color: var(--bad); }
.buttons { display: flex; gap: 6px; }

/* --- Top right: one slim bar; its panels open under it -------------------- */
#topBar { position: absolute; right: 14px; top: 12px; z-index: 2; display: grid; gap: 6px; justify-items: end; }
.toolbar { display: flex; align-items: center; padding: 4px 0; background: var(--glass); border: 1px solid var(--line); border-radius: 10px; }
.toolbar .group { display: flex; align-items: center; gap: 2px; padding: 0 8px; }
.toolbar .group + .group { border-left: 1px solid var(--line); }
#topBar .toolbar .group { padding: 0 6px; }   /* a little tighter than 8, so the Spellbook button fits next to the links at 1280 wide */
.toolbar button { background: none; }
.toolbar button:hover { background: rgba(255, 255, 255, 0.1); }
.toolbar button.on { background: rgba(185, 138, 255, 0.14); }
.label { font-size: 11px; color: var(--ink-dim); margin-right: 4px; }
/* Top left: buttons that open this project's code and the Warlock SIM. */
#links { position: absolute; left: 14px; top: 12px; z-index: 2; }
#links button:has(svg.gh) { padding: 4px 5px; }
#links svg.gh { display: block; width: 14px; height: 14px; margin: 1px 0; }   /* GitHub's mark in place of the word */
#links .group { padding: 0 4px; }   /* tighter than the other bars, so the Twitch and Discord buttons fit */
#links button.twitch { padding: 4px 5px; background: #772ce8; color: #fff; border-color: #772ce8; }   /* Xn's live stream, in Twitch's purple */
#links button.discord { padding: 4px 5px; background: #5865f2; color: #fff; border-color: #5865f2; }   /* Xn's Discord, in Discord's blurple */
#links button.discord:hover { background: #4752c4; border-color: #4752c4; }
#links button.twitch:hover { background: #6420c9; border-color: #6420c9; }
#links button.twitch svg, #links button.discord svg { display: block; width: 14px; height: 14px; margin: 1px 0; }
#links .logo { display: block; width: 30px; height: 30px; border-radius: 7px; margin: -4px 4px -4px -3px; }   /* the logo stands for this page */
#challengeBar { position: absolute; left: 14px; top: 54px; z-index: 2; }
#bossBar { position: absolute; left: 14px; top: 98px; z-index: 2; }
#bossBar button.on { color: var(--gold); border-color: rgba(240, 207, 122, 0.6); }
.cards.boss-cards { grid-template-columns: 1fr; }   /* (two classes: .cards later in this file would win) */
.boss-cards .card.locked h4 { color: var(--ink-dim); font-weight: 500; font-style: italic; }
.boss-cards .card .best { font-size: 12px; color: var(--ink-dim); }
.boss-cards .card.reward h4 { align-items: center; }
.boss-cards .card.reward .swatch { width: 22px; height: 22px; border-radius: 50%; border: 2px solid #fff4d6; background: radial-gradient(circle at 35% 35%, #fff2c4, #e8c060 45%, #9a7420); }
.boss-cards .card p { font-size: 13px; line-height: 1.45; }
.boss-cards .card .where { color: var(--ink-dim); font-size: 12px; font-weight: 400; }
#moveBanner.emote { background: rgba(90, 20, 10, 0.78); border-color: rgba(255, 120, 60, 0.7); color: #ffd2a8; font-size: 18px; }
.plate.small .tag { width: 40px; padding: 2px 3px 3px; }
.plate.small .tag span { display: none; }
.plate.small .tag i { margin-top: 0; }
#buildLabel { max-width: 186px; margin-right: 6px; font-size: 12px; font-weight: 600; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.seg { display: flex; gap: 2px; }
.seg button { min-width: 24px; padding: 4px 0; font-weight: 600; }

.picker { width: 340px; }
.options { display: grid; gap: 2px; }
.options button { display: flex; align-items: center; gap: 8px; text-align: left; padding: 3px 8px; background: none; }
.options button:hover { background: rgba(255, 255, 255, 0.1); }
.options button.on { background: rgba(185, 138, 255, 0.14); }
.options button img, .options button .no-icon { width: 18px; height: 18px; border-radius: 4px; flex: none; }
.options button small { margin-left: auto; color: var(--ink-dim); font-size: 11px; }

.keys { width: 470px; display: grid; gap: 8px; }
.binds { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.bind { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 1px 0; font-size: 12px; }
.bind span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bind button { flex: none; min-width: 58px; padding: 1px 6px; font-weight: 600; color: var(--gold); }
.bind button.waiting { color: var(--accent); border-color: var(--accent); }
.bind button.unset { color: var(--ink-dim); font-weight: 400; }

/* --- Right: the bar of switches and things to open; left: the rotation panel; top centre: drill tag and callouts --- */
#hud summary, #hud .side { pointer-events: auto; }
.side { position: absolute; right: 14px; top: 56px; width: 232px; max-height: calc(100% - 56px - 370px); overflow-y: auto; padding: 4px 10px; background: var(--glass); scrollbar-width: thin; }
.side details { padding: 5px 0; }
.side details + details { border-top: 1px solid var(--line); }
.side summary { cursor: pointer; list-style: none; font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-dim); }
.side summary::-webkit-details-marker { display: none; }
.side summary::after { content: '+'; float: right; font-weight: 400; }
.side details[open] summary::after { content: '\2212'; }
.side details[open] summary { margin-bottom: 5px; }
.side label { display: block; font-size: 12px; }
.side .hint { margin: 4px 0; }
.switch { display: flex !important; align-items: center; gap: 8px; padding: 2px 0; cursor: pointer; }
.switch input { appearance: none; flex: none; width: 28px !important; height: 16px; margin: 0; padding: 0 !important; border-radius: 8px !important; background: rgba(255, 255, 255, 0.12) !important; border: 0 !important; position: relative; cursor: pointer; }
.switch input::after { content: ''; position: absolute; left: 2px; top: 2px; width: 12px; height: 12px; border-radius: 50%; background: var(--ink-dim); transition: left 0.12s; }
.switch input:checked { background: rgba(185, 138, 255, 0.45) !important; }
.switch input:checked::after { left: 14px; background: #fff; }
.stack { display: grid; gap: 3px; }
#side label.range { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
#side label.range input { flex: 1; min-width: 0; padding: 0; border: 0; background: none; accent-color: var(--accent); }
#side label.range b { flex: none; width: 34px; text-align: right; font-weight: 400; font-variant-numeric: tabular-nums; color: var(--ink-dim); }
.touch #uiScaleLabel { display: none !important; }        /* a phone's layout sets its own size */
.stack button { text-align: left; }
.seed { display: flex; gap: 4px; }
.seed input { flex: 1; min-width: 0; }

.rotation { position: absolute; left: 14px; top: 142px; width: 270px; max-height: calc(100% - 142px - 232px); overflow: hidden; background: rgba(20, 11, 30, 0.5); border-color: transparent; }
.rotation ol { list-style: none; margin: 0 0 6px; padding: 0; display: grid; gap: 3px; counter-reset: step; }
.rotation li { display: flex; align-items: center; gap: 6px; font-size: 11px; line-height: 1.25; color: var(--ink); counter-increment: step; }
.rotation li::before { content: counter(step); flex: none; width: 12px; text-align: right; color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.rotation li img, .rotation li .no-icon { flex: none; width: 18px; height: 18px; border-radius: 4px; }

#topCentre { position: absolute; left: 50%; top: 56px; transform: translateX(-50%); display: grid; gap: 6px; justify-items: center; }
.boss-frame { display: grid; gap: 3px; width: 280px; padding: 6px 10px 7px; text-align: left; background: var(--glass); border: 1px solid var(--line); border-radius: 10px; cursor: pointer; }
.boss-frame:hover { border-color: var(--line-bright); }
.boss-frame.current { border-color: rgba(240, 207, 122, 0.75); box-shadow: 0 0 0 1px rgba(240, 207, 122, 0.35); }
.boss-frame .bf-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 13px; }
.boss-frame .bf-top span { font-size: 11px; color: var(--ink-dim); }
.boss-frame .bf-bar { position: relative; display: block; height: 14px; border-radius: 4px; background: rgba(0, 0, 0, 0.55); overflow: hidden; }
.boss-frame .bf-bar i { position: absolute; inset: 0 auto 0 0; background: linear-gradient(#d9473c, #9c2a22); }
.boss-frame .bf-bar span { position: relative; display: block; text-align: center; font-size: 11px; line-height: 14px; font-weight: 600; text-shadow: 0 1px 2px #000; }
.boss-frame .bf-cast { min-height: 14px; font-size: 11px; color: #ffcf9a; }
.boss-frame.dead { opacity: 0.6; }
.chip { display: flex; align-items: center; gap: 10px; padding: 4px 6px 4px 12px; max-width: 520px; background: var(--glass); border-color: rgba(240, 207, 122, 0.45); font-size: 12px; }
.callout { min-height: 18px; font-size: 14px; font-weight: 600; color: var(--gold); text-shadow: 0 1px 2px #000, 0 0 3px #000; opacity: 0; transition: opacity 0.5s; }
.callout.show { opacity: 1; transition: none; }

.rotation li.now { color: #7dffc0; font-weight: 600; }
.rotation li.now::before { content: '\25B6'; color: #7dffc0; }

/* The sim's next cast: a line above the cast bar, and a green edge on the spell's button. */
.sim-hint { display: flex; align-items: center; gap: 6px; height: 22px; padding: 0 10px; border-radius: 11px; background: rgba(13, 7, 20, 0.72); box-shadow: 0 0 0 1px rgba(125, 255, 192, 0.4); font-size: 12px; color: var(--ink-dim); white-space: nowrap; }
.sim-hint img { width: 16px; height: 16px; border-radius: 3px; }
.sim-hint b { color: #7dffc0; font-weight: 600; }
.sim-hint small { font-size: 11px; color: var(--ink-dim); }
.touch .sim-hint small { display: none; }                  /* no room for the reason on a phone */
.slot.hint { border-color: #7dffc0; box-shadow: 0 0 0 2px #7dffc0 inset, 0 0 9px rgba(125, 255, 192, 0.55); }

/* The opener trainer: the sim's first casts in a row; yours tick them off. */
.opener { display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 10px; border-radius: 15px; background: rgba(13, 7, 20, 0.72); box-shadow: 0 0 0 1px var(--line-bright); font-size: 12px; color: var(--ink-dim); white-space: nowrap; }
.opener div { display: flex; gap: 4px; }
.opener i { position: relative; display: block; width: 22px; height: 22px; border-radius: 4px; background: #1b1226 center / cover; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.7); opacity: 0.55; }
.opener i.next { opacity: 1; box-shadow: 0 0 0 2px #fff; }
.opener i.right { opacity: 1; box-shadow: 0 0 0 2px #7dffc0; }
.opener i.wrong { opacity: 1; box-shadow: 0 0 0 2px #ff5b4f; }
.opener i.right::after, .opener i.wrong::after { position: absolute; right: -4px; bottom: -5px; font: 700 12px/1 "Segoe UI", system-ui, sans-serif; text-shadow: 0 0 2px #000, 0 0 2px #000; }
.opener i.right::after { content: '\2713'; color: #7dffc0; }
.opener i.wrong::after { content: '\2717'; color: #ff5b4f; }
.opener b { color: var(--ink); font-weight: 600; }
.touch .opener { position: absolute; left: var(--mid); bottom: calc(94px + var(--sb)); transform: translateX(-50%); }
@media (orientation: portrait) { .touch .opener { bottom: calc(268px + var(--sb)); } }

/* DoT timers: a stack of bars above your target's debuffs, growing upward. */
#auraRow { position: relative; }
.dotbars { position: absolute; right: 0; bottom: 36px; width: 186px; display: flex; flex-direction: column-reverse; gap: 2px; pointer-events: none; }
/* The spell's picture stands beside its bar; the bar itself holds the fill, the name and the seconds. */
.dotbar { display: flex; align-items: center; gap: 3px; height: 16px; font-size: 11px; line-height: 16px; text-shadow: 0 1px 1px #000; }
.dotbar img { flex: none; width: 16px; height: 16px; border-radius: 3px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.7); }
.dotbar-track { position: relative; flex: 1; min-width: 0; display: flex; align-items: center; gap: 5px; height: 100%; padding: 0 5px; border-radius: 4px; background: rgba(0, 0, 0, 0.6); overflow: hidden; }
.dotbar i { position: absolute; inset: 0 auto 0 0; background: rgba(140, 90, 230, 0.62); }
.dotbar.fire i { background: rgba(225, 115, 45, 0.62); }
.dotbar span { position: relative; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dotbar b { position: relative; flex: none; font-variant-numeric: tabular-nums; }
.dotbar.other { opacity: 0.72; }
/* Gold: cast it again now (it lands as the old one ends). A pale edge: it is due after your next cast. */
.dotbar.now .dotbar-track { box-shadow: 0 0 0 1px var(--gold) inset; }
.dotbar.now b { color: var(--gold); }
.dotbar.next .dotbar-track { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.45) inset; }

/* The race against the sim, in the damage meter. */
.race { margin-top: 8px; display: grid; gap: 3px; }
.race-row { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--ink-dim); }
.race-row span { width: 24px; }
.race-row i { flex: 1; height: 6px; border-radius: 3px; background: rgba(0, 0, 0, 0.5); overflow: hidden; }
.race-row b { display: block; height: 100%; width: 0; border-radius: 3px; background: var(--accent); }
.race-row.sim b { background: rgba(255, 255, 255, 0.55); }
.race-row.best b { background: var(--gold); }
#raceBestText { color: var(--ink-dim); }
.race p { margin: 0; font-size: 11px; color: var(--ink); }

/* --- Bottom centre: cast bar, buffs and debuffs, the three frames, action bar --- */
#bottomCentre { position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); width: 668px; display: flex; flex-direction: column; align-items: center; gap: 6px; }

.error-text { height: 18px; font-size: 14px; font-weight: 600; color: #ff5b4f; text-shadow: 0 1px 2px #000, 0 0 3px #000; opacity: 0; transition: opacity 0.4s; }
.error-text.show { opacity: 1; transition: none; }

.castbar { position: relative; width: 280px; height: 18px; border-radius: 9px; background: rgba(0, 0, 0, 0.62); box-shadow: 0 0 0 1px var(--line-bright); overflow: hidden; }
.castbar i { position: absolute; inset: 0 auto 0 0; width: 0; background: #e2ae36; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3); }
.castbar b { position: relative; display: block; text-align: center; font-size: 12px; line-height: 18px; font-weight: 600; text-shadow: 0 1px 1px #000; }
.castbar.idle { visibility: hidden; }
.castbar.channel i { background: #43b96c; }
.castbar.interrupted { box-shadow: 0 0 0 1px #ff5b4f; }
.castbar.interrupted i { width: 100% !important; background: #b3261e; }

/* Buffs on the left (above you), what is on your target on the right (above it): an icon with the seconds left. */
#auraRow { width: 100%; min-height: 30px; display: flex; justify-content: space-between; align-items: flex-end; gap: 16px; }
.auras { display: flex; gap: 3px; align-items: center; }
#playerBuffs { flex-wrap: wrap; max-width: 380px; }
#targetDebuffs { flex-wrap: wrap; justify-content: flex-end; }
.aura { position: relative; width: 22px; height: 22px; border-radius: 5px; overflow: hidden; background: #1b1226; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.7), 0 1px 3px rgba(0, 0, 0, 0.6); }
.aura img { display: block; width: 100%; height: 100%; }
.aura i.aura-stack { position: absolute; left: 0; right: 0; top: -1px; text-align: center; font-style: normal; font-size: 10px; line-height: 11px; font-weight: 700; color: #fff; text-shadow: 0 0 2px #000, 0 0 2px #000, 0 1px 1px #000; }   /* stacks or charges (Demonic Brand); the time is at the bottom */
.aura b { position: absolute; left: 0; right: 0; bottom: -1px; text-align: center; font-size: 11px; line-height: 12px; font-weight: 700; font-variant-numeric: tabular-nums; color: #fff; text-shadow: 0 0 2px #000, 0 0 2px #000, 0 1px 1px #000; }
.auras.large .aura { width: 30px; height: 30px; border-radius: 6px; }
.auras.large .aura b { font-size: 12px; line-height: 13px; }
.auras.large .aura i.aura-stack { font-size: 11px; line-height: 12px; }

/* The frames: you, your pet, your target. */
#frames { width: 100%; display: grid; grid-template-columns: 1fr 158px 1fr; gap: 6px; align-items: stretch; }
.unit { min-width: 0; display: flex; align-items: center; gap: 11px; padding: 8px 11px; background: var(--glass); border: 1px solid var(--line); border-radius: 12px; }
.portrait { flex: none; width: 44px; height: 44px; border-radius: 50%; object-fit: cover; background: #1b1226; box-shadow: 0 0 0 1.5px rgba(205, 170, 255, 0.55), 0 0 0 4px rgba(0, 0, 0, 0.35); }
.hostile .portrait { box-shadow: 0 0 0 1.5px rgba(255, 130, 118, 0.65), 0 0 0 4px rgba(0, 0, 0, 0.35); }
.portrait.small { width: 18px; height: 18px; box-shadow: 0 0 0 1px rgba(205, 170, 255, 0.55); }
.unit-body { flex: 1; min-width: 0; display: grid; gap: 4px; }
.unit-name { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: 13px; font-weight: 600; color: var(--ink); white-space: nowrap; }
.hostile .unit-name { color: #ffb4aa; }
.unit-sub { font-weight: 400; font-size: 11px; color: var(--ink-dim); overflow: hidden; text-overflow: ellipsis; }
.distance { font-variant-numeric: tabular-nums; color: var(--ink); }
.distance.far { color: var(--bad); font-weight: 600; }

/* A name is a button: click it to type a new one. */
button.name { font: inherit; color: inherit; background: none; border: 0; border-bottom: 1px dashed transparent; border-radius: 0; padding: 0; cursor: text; overflow: hidden; text-overflow: ellipsis; }
button.name:hover { background: none; border-bottom-color: currentColor; }
#hud input.name-edit { font: inherit; color: inherit; width: 110px; min-width: 0; padding: 0 3px; background: rgba(0, 0, 0, 0.65); border: 1px solid var(--accent); border-radius: 4px; outline: none; }

.bar { --h: 15px; position: relative; height: var(--h); border-radius: 5px; background: rgba(0, 0, 0, 0.58); overflow: hidden; }
.bar i { position: absolute; inset: 0 auto 0 0; width: 100%; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), inset 0 -6px 6px rgba(0, 0, 0, 0.16); }
.bar b { position: relative; display: block; text-align: center; font-size: 11px; line-height: var(--h); font-weight: 600; font-variant-numeric: tabular-nums; text-shadow: 0 1px 1px #000; }
.bar.health i { background: var(--health); }
.bar.health.low i { background: #c9a12e; }               /* not much left for Life Taps */
.bar.mana { --h: 12px; }
.bar.mana i { background: var(--mana); }
.bar.mana b { font-size: 10px; }
.bar.mana.regen { box-shadow: 0 0 0 1px rgba(160, 195, 255, 0.85), 0 0 6px rgba(120, 165, 255, 0.5); }   /* Spirit is giving mana back */
.bar.empty i { width: 0; }
.hostile .bar.health { --h: 20px; }
.hostile .bar.health i { background: var(--hostile); }
.execute .bar.health i { background: #e0662f; }
/* The target's health number is a button (click to change the pool); a mark shows where execute starts. */
.bar s { position: absolute; top: 0; bottom: 0; width: 1px; background: rgba(255, 255, 255, 0.75); }
.bar button { position: relative; display: block; width: 100%; height: 100%; padding: 0; border: 0; border-radius: 0; background: none; color: var(--ink); font-size: 11px; line-height: var(--h); font-weight: 600; font-variant-numeric: tabular-nums; text-shadow: 0 1px 1px #000; cursor: text; }
.bar button:hover { background: rgba(255, 255, 255, 0.12); }
#hud .bar input { position: relative; display: block; width: 100%; height: 100%; padding: 0 4px; border: 0; border-radius: 0; outline: 1px solid var(--accent); background: rgba(0, 0, 0, 0.8); font: 600 11px/1 "Segoe UI", system-ui, sans-serif; text-align: center; }

.pet { padding: 6px 9px; }
.pet .unit-body { gap: 3px; }
.pet .unit-name { align-items: center; justify-content: flex-start; gap: 6px; font-size: 12px; color: #dcc6ff; }
.pet .unit-sub { margin-left: auto; }
.pet .bar { --h: 4px; border-radius: 3px; }
.pet .bar.mana { --h: 11px; }                 /* the pet's mana carries its numbers; its health never changes */
.pet .bar.mana b { font-size: 9px; }
.pet-buttons { display: flex; gap: 4px; margin-top: 2px; }
.pet-buttons button { flex: 1; padding: 1px 0; font-size: 11px; }
.pet.none .bar, .pet.none .pet-buttons, .pet.none .portrait { display: none; }
.pet.none .unit-sub { margin: 0 auto; }

/* Action bar. */
.actionbar { display: flex; gap: 4px; padding: 5px; background: var(--glass); border: 1px solid var(--line); border-radius: 12px; }
.slot { position: relative; width: 40px; height: 40px; padding: 0; overflow: hidden; border-radius: 7px; background: var(--slot); border: 1px solid rgba(0, 0, 0, 0.65); cursor: pointer; }
.slot:hover { background: var(--slot); border-color: var(--line-bright); }
.slot.empty { cursor: default; }
.slot img { display: block; width: 100%; height: 100%; }
.slot kbd { position: absolute; right: 3px; top: 1px; z-index: 1; font: 600 11px/1.2 "Segoe UI", system-ui, sans-serif; color: #fff; text-shadow: 0 0 2px #000, 0 1px 1px #000; }
/* The global cooldown and spell cooldowns sweep round the button like a clock hand, as in the game. */
.slot .cool { position: absolute; inset: 0; background: conic-gradient(transparent calc((1 - var(--left, 0)) * 360deg), rgba(8, 4, 14, 0.76) 0); }
.slot .cool.none { display: none; }
.slot .secs { position: absolute; inset: 0; display: grid; place-items: center; font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; color: #fff; text-shadow: 0 0 3px #000, 0 1px 2px #000; }
.slot .count { position: absolute; right: 3px; bottom: 1px; font-size: 11px; font-weight: 700; color: #fff; text-shadow: 0 0 2px #000, 0 1px 1px #000; }
.slot.no-mana img { filter: saturate(0.4) brightness(0.55) sepia(1) hue-rotate(180deg) saturate(3); }
.slot.no-range img { filter: saturate(0.4) brightness(0.55) sepia(1) hue-rotate(-50deg) saturate(4); }
.slot.unusable img { filter: grayscale(1) brightness(0.45); }
.slot.active { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold) inset; }
.slot.queued { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.slot.proc { border-color: var(--gold); box-shadow: 0 0 8px 1px var(--gold); }

/* Edit bar. */
.edit-strip { display: flex; align-items: center; gap: 8px; padding: 5px 8px; font-size: 12px; }
.editing .slot { border-style: dashed; border-color: var(--line-bright); cursor: grab; }
.editing .slot.picked { border-style: solid; border-color: var(--gold); box-shadow: 0 0 0 2px var(--gold) inset; }
.editing .slot { touch-action: none; }
.editing .slot.drop { border-style: solid; border-color: var(--gold); box-shadow: 0 0 0 2px var(--gold) inset, 0 0 10px rgba(240, 207, 122, 0.5); }
/* The spellbook: every spell, dragged onto the bar from here. */
.spellbook { width: 100%; box-sizing: border-box; padding: 8px 10px 10px; display: grid; gap: 8px; }
.spellbook header { display: flex; align-items: baseline; gap: 10px; }
.spellbook h2 { margin: 0; font-size: 14px; }
.spellbook header span { flex: 1; font-size: 11px; color: var(--ink-dim); }
.book-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(68px, 1fr)); gap: 5px; max-height: min(40vh, 320px); overflow-y: auto; }
.book-spell { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 5px 3px 4px; border-radius: 8px; background: rgba(0, 0, 0, 0.25); border: 1px solid transparent; cursor: grab; touch-action: none; }
.book-spell:hover { border-color: var(--line-bright); }
.book-spell img { width: 36px; height: 36px; border-radius: 6px; border: 1px solid rgba(0, 0, 0, 0.65); pointer-events: none; }
.book-spell span { font-size: 10.5px; line-height: 1.15; text-align: center; color: var(--ink); }
.book-spell.on-bar img { opacity: 0.55; }
.book-spell.on-bar span { color: var(--ink-dim); }
.book-spell.picked { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold) inset; }
.book-ghost { position: fixed; z-index: 40; width: 40px; height: 40px; margin: -20px 0 0 -20px; border-radius: 7px; border: 1px solid var(--gold); pointer-events: none; opacity: 0.9; box-shadow: 0 2px 10px #000; }
body.book-dragging, body.book-dragging * { cursor: grabbing !important; }

/* --- Bottom corners: combat log and damage meter ------------------------- */
.log { position: absolute; left: 14px; bottom: 14px; width: 270px; height: 196px; display: flex; flex-direction: column; background: rgba(20, 11, 30, 0.5); border-color: transparent; }
.log ol { list-style: none; margin: 0; padding: 0; flex: 1; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end; gap: 2px; font-size: 12px; color: var(--ink-dim); }
.log li { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.log li.note { color: var(--ink); }
.log li.crit { color: var(--gold); }
.log li.miss { color: #8f869f; }
.log li.gain { color: #8fb2ff; }
.log li.proc { color: #cfb0ff; }

.meter { position: absolute; right: 14px; bottom: 14px; width: 230px; background: var(--glass); }
.meter-main { display: flex; align-items: baseline; gap: 6px; margin-bottom: 6px; }
.meter-main b { font-size: 30px; line-height: 1; font-weight: 600; font-variant-numeric: tabular-nums; }
.meter-main span { font-size: 11px; letter-spacing: 0.08em; color: var(--ink-dim); }
.meter dl { margin: 0; display: grid; grid-template-columns: 1fr max-content; gap: 2px 12px; font-size: 12px; }
.meter dt { color: var(--ink-dim); }
.meter dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
#meterDummies { font-size: 11px; }
.meter dt.wide, .meter dd.wide { grid-column: 1 / -1; }
.meter dd.wide { text-align: left; white-space: pre-line; padding-left: 8px; line-height: 1.4; }
.meter ol { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 3px; }
.meter li { position: relative; display: flex; justify-content: space-between; gap: 8px; padding: 1px 6px; font-size: 11px; border-radius: 4px; overflow: hidden; background: rgba(255, 255, 255, 0.04); }
.meter li i { position: absolute; inset: 0 auto 0 0; background: rgba(160, 110, 240, 0.5); }
.meter li.fire i { background: rgba(230, 120, 50, 0.5); }
.meter li.pet i { background: rgba(110, 170, 120, 0.45); }
.meter li span { position: relative; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.meter li span + span { flex: none; font-variant-numeric: tabular-nums; color: var(--ink); }

/* --- Over the scene: plates above the dummies, damage numbers, "Move!" --- */
#plates { position: fixed; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.plate { position: absolute; transform: translate(-50%, -100%); color: #ffb4aa; font: 600 11px/1.3 "Segoe UI", system-ui, sans-serif; text-align: center; white-space: nowrap; cursor: pointer; pointer-events: auto; }
.plate .auras { justify-content: center; gap: 2px; margin-bottom: 2px; }
.plate .aura { width: 26px; height: 26px; }
.plate .aura b { font-size: 12px; line-height: 13px; }
.plate .aura i.aura-stack { font-size: 11px; line-height: 12px; }
.plate .tag { display: block; width: 110px; margin: 0 auto; padding: 2px 5px 4px; border-radius: 6px; background: rgba(20, 11, 30, 0.74); border: 1px solid var(--line); overflow: hidden; text-overflow: ellipsis; }
.plate .tag i { display: block; height: 5px; margin-top: 2px; border-radius: 3px; background: rgba(0, 0, 0, 0.6); overflow: hidden; }
.plate .tag i b { display: block; height: 100%; width: 100%; background: var(--hostile); }
.plate.current { color: var(--gold); }
.plate.current .tag { border-color: var(--gold); }
.plate.called .tag { border-color: #ff6a5e; box-shadow: 0 0 9px 1px #ff6a5e; }       /* a scripted fight calls this dummy out */
.plate.called .tag::before { content: '\25BC '; color: #ff6a5e; }
.plate.dead { opacity: 0.45; }
.plate.solo .tag { display: none; }
.plate.solo { pointer-events: none; }

/* Damage numbers: placed every picture above their dummy, so they stay with it when the camera moves. */
#floaters { position: fixed; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.float { position: absolute; left: 0; top: 0; will-change: transform, opacity; white-space: nowrap; font: 700 24px/1 "Friz Quadrata TT", "Friz Quadrata", "Palatino Linotype", "Book Antiqua", Palatino, Georgia, serif; color: #ffd100; -webkit-text-stroke: 1px #000; paint-order: stroke fill; text-shadow: 0 0 2px #000, 1px 2px 0 #000, 0 0 5px rgba(0, 0, 0, 0.9); letter-spacing: 0.5px; }
.float.crit { font-size: 38px; }
.float.small { font-size: 18px; }
.float.small.crit { font-size: 25px; }
.float.pet { font-size: 17px; color: #fff; }
.float.pet.crit { font-size: 24px; }
.float.miss { font-size: 20px; color: #fff; }

#moveBanner { position: fixed; z-index: 3; left: 50%; top: 22%; transform: translateX(-50%); padding: 6px 18px; border-radius: 8px; background: rgba(120, 20, 16, 0.85); border: 1px solid #ff6a5e; color: #fff; font: 700 22px/1.2 "Segoe UI", system-ui, sans-serif; text-shadow: 0 1px 2px #000; pointer-events: none; }
#moveBanner.soon { background: var(--glass); border-color: var(--line-bright); font-size: 14px; font-weight: 600; color: var(--ink-dim); }

/* --- Tooltips: appear at once next to what the pointer is on -------------- */
#tip { position: fixed; left: 0; top: 0; z-index: 30; max-width: 310px; padding: 9px 12px 10px; background: rgba(13, 7, 20, 0.97); border: 1px solid var(--line-bright); border-radius: 9px; box-shadow: 0 8px 26px rgba(0, 0, 0, 0.55); pointer-events: none; font: 12px/1.4 "Segoe UI", system-ui, sans-serif; color: var(--ink); }
#tip .tip-title { display: flex; justify-content: space-between; align-items: baseline; gap: 18px; font-size: 14px; font-weight: 600; color: #fff; }
#tip .tip-title span { font-size: 11px; font-weight: 400; color: var(--ink-dim); white-space: nowrap; }
#tip .tip-row { display: flex; justify-content: space-between; gap: 18px; white-space: nowrap; }
#tip .tip-text { margin-top: 5px; color: var(--gold); white-space: pre-line; }
#tip .tip-note { margin-top: 5px; color: var(--ink-dim); }
#tip .tip-note.yours { color: #9fe0b4; }
#tip .tip-plain { white-space: pre-line; }

/* --- Fight review ------------------------------------------------------- */
.review { position: fixed; z-index: 10; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(640px, 92vw); max-height: 84vh; overflow: auto; padding: 14px 16px; background: var(--glass-solid); border: 1px solid var(--line-bright); border-radius: 12px; color: var(--ink); font: 13px/1.4 "Segoe UI", system-ui, sans-serif; }
.review header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.review h2 { margin: 0; font-size: 16px; font-weight: 600; }
.review h3 { margin: 14px 0 4px; font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-dim); }
.review-head { margin: 0; font-size: 14px; }
.review-head b { font-size: 20px; }
.review table { width: 100%; border-collapse: collapse; font-size: 12px; }
.review th { text-align: left; font-weight: 600; color: var(--ink-dim); padding: 2px 6px; border-bottom: 1px solid var(--line); }
.review td { padding: 2px 6px; border-bottom: 1px solid rgba(255, 255, 255, 0.05); }
.review .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.review tr.behind td { color: #ffb3a8; }
.review .hint { margin-top: 12px; }

/* The sheets (character, talents, buffs) use the review's box. */
.sheet { width: min(760px, 94vw); z-index: 11; }
.sheet header { gap: 12px; }
.sheet .tabs { display: flex; gap: 3px; margin-right: auto; }
.from-sim { margin: 0 0 10px !important; padding: 5px 8px; border-radius: 6px; background: rgba(185, 138, 255, 0.1); color: var(--ink) !important; }
.sheet td.from { color: var(--ink-dim); font-size: 11px; }
.trees { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.tree-grid { display: grid; grid-template-columns: repeat(4, 40px); grid-auto-rows: 40px; gap: 7px; justify-content: center; }
.talent { position: relative; border-radius: 7px; overflow: hidden; background: #1b1226; box-shadow: 0 0 0 1px rgba(205, 170, 255, 0.35); }
.talent img { display: block; width: 100%; height: 100%; }
.talent b { position: absolute; right: 0; bottom: 0; padding: 0 3px; border-radius: 5px 0 0 0; background: rgba(8, 4, 14, 0.85); font-size: 10px; line-height: 13px; font-weight: 700; color: #9fe0b4; }
.talent.full { box-shadow: 0 0 0 1px var(--gold); }
.talent.full b { color: var(--gold); }
.talent.none { box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08); }
.talent.none img { filter: grayscale(1) brightness(0.4); }
.talent.none b { color: var(--ink-dim); }
.onoff { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.onoff li { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.onoff li i { flex: none; width: 26px; font-style: normal; font-size: 10px; font-weight: 700; text-transform: uppercase; text-align: center; border-radius: 4px; color: #9fe0b4; background: rgba(110, 200, 140, 0.14); }
.onoff li.off { color: var(--ink-dim); }
.onoff li.off i { color: var(--ink-dim); background: rgba(255, 255, 255, 0.06); }
.onoff li.off img { filter: grayscale(1) brightness(0.5); }
.onoff img, .onoff .no-icon { flex: none; width: 18px; height: 18px; border-radius: 4px; }
.onoff small { margin-left: auto; text-align: right; font-size: 11px; color: var(--ink-dim); }
/* The Challenges window: a card per drill, and the seeded fight. */
.toolbar button.gold { color: var(--gold); font-weight: 600; }
.toolbar button.gold.on { background: rgba(240, 207, 122, 0.14); border-color: rgba(240, 207, 122, 0.45); }
#challenges .seed { max-width: 320px; }
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.card { display: flex; flex-direction: column; gap: 6px; padding: 10px 12px; border-radius: 10px; background: rgba(255, 255, 255, 0.04); border: 1px solid var(--line); }
.card.on { border-color: rgba(240, 207, 122, 0.6); background: rgba(240, 207, 122, 0.07); }
.card h4 { margin: 0; display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 14px; font-weight: 600; }
.card h4 b { font-size: 18px; color: var(--gold); }
.card p { margin: 0; flex: 1; font-size: 12px; color: var(--ink-dim); }
.card small { font-size: 11px; color: var(--ink-dim); }
.card button { align-self: flex-start; }
.wide-card { max-width: 100%; }
.card.robe h4 { align-items: center; }
.swatch { flex: none; width: 26px; height: 26px; border-radius: 50%; border: 2px solid; }
.card.locked { opacity: 0.6; }
.card button:disabled { cursor: default; color: var(--ink-dim); background: none; }
.card-line { display: flex; gap: 6px; margin: 8px 0 0; }
#challenges input { user-select: text; font: inherit; font-size: 12px; color: var(--ink); background: rgba(0, 0, 0, 0.5); border: 1px solid var(--line); border-radius: 5px; padding: 3px 6px; }
#challenges input:focus { outline: 1px solid var(--accent); }
/* The timeline in the review: names on the left, the fight scrolling sideways on the right. */
.timeline { display: grid; grid-template-columns: 112px 1fr; margin-top: 4px; border-radius: 6px; background: rgba(0, 0, 0, 0.3); overflow: hidden; }
.tl-names { padding: 4px 0 12px; border-right: 1px solid var(--line); }
.tl-name { display: flex; align-items: center; padding: 0 6px; font-size: 10px; color: var(--ink-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tl-scroll { overflow-x: auto; overflow-y: hidden; padding: 4px 0 4px 8px; scrollbar-width: thin; }
.tl-inner { position: relative; }
.tl-row { position: absolute; left: 0; right: 0; }
.tl-row i { position: absolute; display: block; }
.tl-axis span { position: absolute; top: 1px; padding-left: 3px; border-left: 1px solid var(--line-bright); font-size: 9px; line-height: 12px; color: var(--ink-dim); }
.tl-casts img, .tl-casts b { position: absolute; top: 4px; width: 17px; height: 17px; border-radius: 3px; box-shadow: 0 0 0 1px #000; z-index: 1; }
.tl-casts b { background: #3a2a4c; font-size: 10px; line-height: 17px; text-align: center; }
.tl-casts img.off { top: 14px; width: 13px; height: 13px; z-index: 2; }
.tl-casts img.stopped { filter: grayscale(1) brightness(0.55); }
.tl-casts img:hover { z-index: 3; box-shadow: 0 0 0 1px var(--gold); }
.tl-casts i { top: 24px; height: 5px; border-radius: 2px; background: #e2ae36; }
.tl-casts i.chan { background: #43b96c; }
.tl-casts i.stopped { background: #7a4a44; }
.tl-casts i.tick { top: 21px; height: 11px; border-radius: 1px; background: #f4fff6; box-shadow: 0 0 3px rgba(120, 255, 160, 0.8); z-index: 1; }
.tl-casts i.tick.empty { background: #8a8a8a; box-shadow: none; }
.tl-casts i.idle { top: 2px; height: 28px; border-radius: 3px; background: rgba(255, 70, 60, 0.28); box-shadow: 0 0 0 1px rgba(255, 110, 100, 0.5) inset; }
.tl-casts i.moved { top: 2px; height: 28px; border-radius: 3px; background: repeating-linear-gradient(135deg, rgba(200, 200, 215, 0.22) 0 4px, transparent 4px 8px); }
.tl-casts.sim img { opacity: 0.8; }
.tl-casts.sim i { opacity: 0.6; }
.tl-aura i { top: 3px; height: 7px; border-radius: 3px; background: rgba(160, 110, 240, 0.85); }
.tl-aura.fire i { background: rgba(230, 120, 50, 0.85); }
.tl-aura i.clip, .tl-aura.fire i.clip { top: 0; height: 13px; border-radius: 1px; background: #ff5b4f; z-index: 1; }
.best-line { margin: 4px 0 0; font-size: 12px; color: var(--ink-dim); }
.best-line.record { color: var(--gold); font-weight: 600; }
.challenge-line button { flex: none; }
/* The graph and the challenge line in the review. */
.graph { display: block; width: 100%; height: 150px; margin-top: 4px; border-radius: 6px; background: rgba(0, 0, 0, 0.3); }
.graph-key { display: flex; flex-wrap: wrap; gap: 0 14px; margin: 3px 0 0; font-size: 11px; color: var(--ink-dim); }
.graph-key i { display: inline-block; width: 14px; height: 3px; margin-right: 5px; vertical-align: middle; border-radius: 2px; background: var(--accent); }
.graph-key i.sim { background: rgba(255, 255, 255, 0.6); }
.graph-key i.top { height: 0; border-radius: 0; background: none; border-top: 1px dashed rgba(255, 255, 255, 0.45); }
.graph-key i.mana { background: #6f9bff; }
.graph-key i.tap { width: 2px; height: 10px; background: rgba(240, 207, 122, 0.8); }
.mana-graph { height: 70px; }
.history-graph { height: 70px; }
.graph-key i.gold { background: rgba(240, 207, 122, 0.8); }
/* "What it cost you": the middle column is the explanation and may wrap. */
.review table.cost td:nth-child(2) { text-align: left; white-space: normal; color: var(--ink-dim); }
.review table.cost th:nth-child(2) { text-align: left; }
.review table.cost td:first-child { white-space: nowrap; }
.review table.cost td:last-child { color: #ffb3a8; }
.challenge-line { display: flex; align-items: center; gap: 12px; margin: 0 0 8px; padding: 6px 10px; border-radius: 8px; background: rgba(240, 207, 122, 0.1); font-size: 13px; }
.challenge-line b { font-size: 26px; line-height: 1; color: var(--gold); }
.challenge-note { margin: -4px 0 8px; font-size: 12px; color: var(--ink); }
.challenge-line span { flex: 1; }

/* --- Lessons, Progress, today's fight, the ghost, proc alerts, watching a fight again ------------------------ */
/* Lessons: one card a lesson, a row each; its test under the text. */
.lesson-cards { grid-template-columns: 1fr; }
/* Fight history: one row per kept fight; the review of a kept fight says so and has its combat log at the end */
.history-list { display: grid; gap: 4px; margin: 6px 0 10px; }
.history-row { display: flex; gap: 4px; }
.history-open { flex: 1; display: grid; grid-template-columns: 96px 1fr auto 76px 40px; gap: 10px; align-items: baseline; text-align: left; padding: 6px 10px; }
.history-open .when, .history-open .who { color: var(--ink-dim); font-size: 12px; }
.history-open .what { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.history-open b, .history-open .pct { text-align: right; }
.history-open .pct { color: var(--ink-dim); }
.history-del { padding: 4px 10px; color: var(--ink-dim); }
.stored-line { margin: 0 0 8px; padding: 6px 10px; font-size: 12px; color: var(--ink); background: rgba(185, 138, 255, 0.1); border-radius: 8px; }
.review-log-fold { margin-top: 10px; }
.review-log-fold summary { cursor: pointer; font-weight: 600; }
.review-log-fold > button { margin: 6px 0; }
.review-log { max-height: 320px; overflow: auto; margin: 0; padding: 6px 8px; list-style: none; font-size: 12px; background: rgba(0, 0, 0, 0.25); border-radius: 8px; }
.review-log li { color: var(--ink-dim); }
.review-log li.note { color: var(--ink); } .review-log li.crit { color: var(--gold); } .review-log li.miss { color: #8f869f; }
.review-log li.gain { color: #8fb2ff; } .review-log li.proc { color: #cfb0ff; }
.review-log li i { display: inline-block; min-width: 44px; color: var(--ink-dim); font-style: normal; font-variant-numeric: tabular-nums; }
.card.lesson h4 b { font-size: 12px; font-weight: 600; color: var(--ink-dim); }
.card.lesson.passed h4 b { color: #9fe0b4; }
.card.lesson.passed h4 b::before { content: '\2713  '; }
.card.lesson p { flex: none; }
.lesson-test { font-size: 12px; color: var(--ink); padding: 6px 8px; border-radius: 6px; background: rgba(0, 0, 0, 0.25); }
.lesson-test ul { margin: 4px 0 0; padding-left: 18px; color: var(--ink-dim); }
.challenge-line.lesson-line b { font-size: 16px; }
.challenge-line b.pass { color: #9fe0b4; }
.challenge-line b.fail { color: #ffb3a8; }
.lesson-checks { list-style: none; margin: -2px 0 10px; padding: 0; display: grid; gap: 3px; font-size: 12px; }
.lesson-checks li { display: flex; align-items: baseline; gap: 8px; }
.lesson-checks li i { flex: none; width: 14px; font-style: normal; font-weight: 700; }
.lesson-checks li.ok i { color: #9fe0b4; }
.lesson-checks li.bad i { color: #ff8478; }
.lesson-checks li span { flex: 1; }
.lesson-checks li b { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Today's fight: one wide card at the top of the Challenges window. */
#daily { grid-template-columns: 1fr; }
.card.daily .streak { color: var(--gold); }
/* Progress: tiles with the headline numbers, the chart, the table of mistakes. */
.progress-tabs { display: flex; flex-wrap: wrap; gap: 3px; margin: 0 0 10px; }
.tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.tile { display: grid; gap: 1px; padding: 8px 12px; border-radius: 10px; background: rgba(255, 255, 255, 0.04); border: 1px solid var(--line); }
.tile b { font-size: 22px; font-weight: 600; font-variant-numeric: tabular-nums; }
.tile span { font-size: 12px; color: var(--ink); }
.tile small { font-size: 11px; color: var(--ink-dim); }
.progress-graph { height: auto; aspect-ratio: 600 / 170; }
.progress-graph text.axis { font-size: 10px; fill: var(--ink-dim); }
.graph-key i.range { height: 6px; background: rgba(185, 138, 255, 0.35); }
.review table.progress-table td.trend { color: var(--ink-dim); }
.review table.progress-table td.trend.good { color: #9fe0b4; }
.review table.progress-table td.trend.bad { color: #ffb3a8; }
.review table.progress-table td.trend.good::before { content: '\2193  '; }
.review table.progress-table td.trend.bad::before { content: '\2191  '; }
/* The items you wear, on the character sheet; their colour by quality, as in the game. */
.sheet table.gear td.item { color: var(--ink); }
.sheet table.gear td.q-uncommon { color: #4fd36a; } .sheet table.gear td.q-rare { color: #5b9dff; } .sheet table.gear td.q-epic { color: #b56bff; }
.sheet table.gear td.q-legendary { color: #ff9a2e; } .sheet table.gear td.q-poor { color: #9d9d9d; }
/* The ghost's name over its head, with what it casts and how far along it is. */
.ghost-tag { position: absolute; transform: translate(-50%, -100%); display: grid; grid-template-columns: auto auto 1fr; align-items: center; gap: 4px; padding: 2px 7px 4px; border-radius: 8px;
  background: rgba(20, 12, 32, 0.55); color: #ddd0ff; font: 600 11px/1.2 "Segoe UI", system-ui, sans-serif; white-space: nowrap; pointer-events: none; box-shadow: 0 0 0 1px rgba(205, 184, 255, 0.25); }
.ghost-tag b { font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: #b9a5ef; }
.ghost-tag img { width: 14px; height: 14px; border-radius: 3px; opacity: 0.9; }
.ghost-tag span { font-weight: 400; color: #eee6ff; }
.ghost-tag i { grid-column: 1 / -1; display: block; height: 2px; border-radius: 1px; background: #cdb8ff; }
/* Proc alerts: a word at the top of the screen, and a strong pulsing glow on the button to press. */
.proc-alert { font-size: 18px; font-weight: 700; color: #ffe6a8; text-shadow: 0 1px 3px #000, 0 0 12px rgba(240, 207, 122, 0.7); opacity: 0; transform: scale(0.9); transition: opacity 0.4s, transform 0.4s; pointer-events: none; }
.proc-alert:empty { display: none; }
.proc-alert.show { opacity: 1; transform: scale(1); transition: opacity 0.08s, transform 0.12s; }
@keyframes procGlow { 0%, 100% { box-shadow: 0 0 0 2px var(--gold) inset, 0 0 8px 2px var(--gold); } 50% { box-shadow: 0 0 0 2px #fff4cc inset, 0 0 18px 6px var(--gold); } }
.alerts .slot.proc { border-color: #fff4cc; animation: procGlow 0.7s ease-in-out infinite; }
/* Watching a fight again: the frames and bars step aside for the play bar. */
.replaying #hud, .replaying .plate { display: none !important; }
.replay-bar { position: fixed; z-index: 3; left: 50%; bottom: 18px; transform: translateX(-50%); width: min(720px, calc(100vw - 32px)); box-sizing: border-box; display: grid; gap: 4px; zoom: var(--ui, 1); }
.replay-row { display: flex; align-items: center; gap: 8px; }
.replay-row input[type="range"] { flex: 1; min-width: 60px; accent-color: var(--accent); }
#replayTime { flex: none; font-size: 12px; font-variant-numeric: tabular-nums; color: var(--ink); }
.speeds { display: flex; gap: 2px; }
.speeds button { padding: 2px 6px; }
#replayWhat { margin: 0; font-size: 12px; color: var(--ink-dim); text-align: center; }
#replayPlay { min-width: 92px; }

/* --- Touch screens (phones, tablets without a mouse) ---------------------------------------------------------
   html gets the class "touch" (js/touch.js). The same pieces as on a desktop, placed for thumbs: you and your
   target at the top, the stick bottom left, the spells in a grid bottom right, the cast bar between them, and one
   Menu button that holds the bars from the top and the right. Sizes are in the screen's own units; the whole layer
   is scaled so that a phone's short side is 390 of them. */
#touch { display: none; }
.touch #touch { display: contents; }
.touch #hud { --st: env(safe-area-inset-top, 0px); --sb: env(safe-area-inset-bottom, 0px); --sl: env(safe-area-inset-left, 0px); --sr: env(safe-area-inset-right, 0px);
  --mid: calc(146px + var(--sl) + (100% - 146px - 330px - var(--sl) - var(--sr)) / 2); --top-width: min(400px, calc(100% - 260px)); }
.touch, .touch body { overscroll-behavior: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.touch #hud button, .touch #hud .aura, .touch #hud label, .touch #meter { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.touch .slot img, .touch .aura img { pointer-events: none; }
.touch #combatLog, .touch #petFrame, .touch #editStrip, .touch #btnKeys, .touch #keysPanel, .touch .slot kbd, .touch .slot.empty { display: none !important; }
.touch .editing .slot.empty { display: block !important; }   /* the spellbook is open: empty slots take a spell too */

/* Top: your DPS (tap it for the review), you and your target, the Menu button. */
.touch #bottomCentre { display: contents; }
.touch .spellbook { position: absolute; left: calc(8px + var(--sl)); right: calc(280px + var(--sr)); top: calc(64px + var(--st)); width: auto; z-index: 4; }   /* left of the action bar, so slots stay free to drop on */
.touch .book-list { max-height: 34vh; }
.touch .book-spell { touch-action: pan-y; }   /* a finger moving up or down scrolls the book; sideways it drags the spell */
.touch #frames { position: absolute; left: 50%; top: calc(6px + var(--st)); transform: translateX(-50%); width: var(--top-width); grid-template-columns: 1fr 1fr; gap: 5px; }
.touch .unit { padding: 4px 8px 6px; gap: 6px; border-radius: 9px; }
.touch .portrait { display: none; }
.touch #playerFrame .bar.health { --h: 10px; }
.touch #playerFrame .bar.health b { font-size: 9px; }
.touch .unit-name { font-size: 11px; }
.touch .unit-sub { font-size: 10px; }
.touch .unit-body { gap: 3px; }
.touch #playerFrame .bar.mana { --h: 10px; }
.touch #playerFrame .bar.mana b { font-size: 9px; }
.touch #playerFrame .unit-body { gap: 2px; }
.touch .hostile .bar.health { --h: 16px; }
.touch #auraRow { position: absolute; left: 50%; top: calc(60px + var(--st)); transform: translateX(-50%); width: var(--top-width); min-height: 0; align-items: flex-start; gap: 8px; pointer-events: none; }
.touch #playerBuffs { max-width: 48%; }
.touch .aura { width: 18px; height: 18px; border-radius: 4px; }
.touch .aura b { font-size: 9px; line-height: 10px; }
.touch .aura i.aura-stack { font-size: 8px; line-height: 9px; }
.touch .auras.large .aura { width: 26px; height: 26px; }
.touch .auras.large .aura b { font-size: 11px; line-height: 12px; }
.touch .dotbars { bottom: auto; top: 30px; width: 150px; flex-direction: column; }
.touch #topCentre { top: calc(96px + var(--st)); width: var(--top-width); }
.touch .chip { max-width: 100%; font-size: 11px; }
.touch .meter { left: calc(8px + var(--sl)); top: calc(6px + var(--st)); right: auto; bottom: auto; width: auto; padding: 5px 10px; display: flex; align-items: baseline; gap: 8px; pointer-events: auto; }
.touch .meter-main { margin: 0; gap: 4px; }
.touch .meter-main b { font-size: 20px; }
.touch .meter dl { display: block; font-size: 10px; }
.touch .meter dt, .touch .meter dd, .touch .meter ol, .touch #race { display: none; }
.touch .meter #meterSim { display: block; color: var(--ink-dim); }
.touch .meter #meterSim::before { content: 'sim '; }
.touch .rotation { left: calc(8px + var(--sl)); top: calc(46px + var(--st)); width: 200px; max-height: 44%; }
.touch .rotation .hint { display: none; }
.touch label:has(#swRace) { display: none !important; }              /* the race against the sim has no room on a phone */
#btnMenu { position: absolute; right: calc(8px + var(--sr)); top: calc(6px + var(--st)); padding: 8px 14px; font-size: 13px; font-weight: 600; background: var(--glass); border: 1px solid var(--line); border-radius: 10px; }

/* Bottom: the stick, the cast bar, the spells. */
#stick { position: absolute; left: calc(18px + var(--sl)); bottom: calc(18px + var(--sb)); width: 118px; height: 118px; border-radius: 50%; background: rgba(20, 11, 30, 0.42); border: 1px solid var(--line-bright); pointer-events: auto; touch-action: none; }
#stick i { position: absolute; left: 50%; top: 50%; width: 50px; height: 50px; margin: -25px 0 0 -25px; border-radius: 50%; background: rgba(185, 138, 255, 0.5); border: 1px solid rgba(255, 255, 255, 0.55); pointer-events: none; }
.touch .actionbar { position: absolute; right: calc(8px + var(--sr)); bottom: calc(8px + var(--sb)); display: grid; grid-template-columns: repeat(5, 46px); gap: 4px; padding: 5px; }
.touch .slot { width: 46px; height: 46px; }
.touch .slot .secs { font-size: 17px; }
#touchKeys { position: absolute; right: calc(278px + var(--sr)); bottom: calc(8px + var(--sb)); display: flex; flex-direction: column; gap: 5px; }
#touchKeys button { width: 46px; height: 46px; padding: 0; border-radius: 50%; font-size: 11px; font-weight: 600; background: var(--glass); border: 1px solid var(--line-bright); }
#touchKeys button:active, #btnMenu:active { background: rgba(185, 138, 255, 0.3); }
.touch .castbar { position: absolute; left: var(--mid); bottom: calc(16px + var(--sb)); transform: translateX(-50%); width: min(210px, calc(100% - 500px - var(--sl) - var(--sr))); min-width: 150px; }
.touch .sim-hint { position: absolute; left: var(--mid); bottom: calc(42px + var(--sb)); transform: translateX(-50%); }
.touch .error-text { position: absolute; left: var(--mid); bottom: calc(68px + var(--sb)); transform: translateX(-50%); white-space: nowrap; font-size: 13px; }

/* A phone held upright: one more row at the top, the cast bar above the spells. */
@media (orientation: portrait) {
  .touch #hud { --mid: 50%; --top-width: calc(100% - 16px - var(--sl) - var(--sr)); }
  .touch #frames { top: calc(48px + var(--st)); }
  .touch #auraRow { top: calc(102px + var(--st)); }
  .touch #topCentre { top: calc(140px + var(--st)); }
  .touch .rotation { top: calc(140px + var(--st)); }
  #stick { left: calc(10px + var(--sl)); bottom: calc(14px + var(--sb)); width: 104px; height: 104px; }
  #stick i { width: 44px; height: 44px; margin: -22px 0 0 -22px; }
  .touch .actionbar { grid-template-columns: repeat(5, 43px); }
  .touch .slot { width: 43px; height: 43px; }
  #touchKeys { left: calc(10px + var(--sl)); right: auto; bottom: calc(128px + var(--sb)); flex-direction: row; gap: 4px; }
  #touchKeys button { width: 40px; height: 40px; font-size: 10px; }
  .touch .castbar { bottom: calc(190px + var(--sb)); width: 230px; }
  .touch .sim-hint { bottom: calc(216px + var(--sb)); }
  .touch .error-text { bottom: calc(242px + var(--sb)); }
  .touch .spellbook { right: calc(8px + var(--sr)); top: calc(140px + var(--st)); }
  .touch .book-list { max-height: 26vh; }
}

/* The menu: everything you set up before a fight, one under the other. */
#touchMenu { position: absolute; inset: 0; z-index: 5; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: calc(10px + var(--st)) calc(12px + var(--sr)) calc(24px + var(--sb)) calc(12px + var(--sl)); background: var(--glass-solid); pointer-events: auto; }
#touchMenu header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
#touchMenu h2 { margin: 0; font-size: 16px; font-weight: 600; }
#touchMenuBody { display: grid; gap: 10px; }
.touch #touchMenu #links, .touch #touchMenu #challengeBar, .touch #touchMenu #bossBar, .touch #touchMenu #topBar, .touch #touchMenu #side { position: static; width: auto; max-height: none; overflow: visible; justify-items: stretch; }
.touch #touchMenu .toolbar { flex-wrap: wrap; row-gap: 6px; padding: 6px 2px; }
.touch #touchMenu .toolbar .group { flex-wrap: wrap; row-gap: 6px; }
.touch #touchMenu .toolbar .group + .group { border-left: 0; }
.touch #touchMenu button { padding: 8px 12px; font-size: 14px; }
.touch #touchMenu .seg button { min-width: 40px; }
.touch #touchMenu #btnReview { display: inline-block; width: auto; margin: 0; }
.touch #touchMenu #buildLabel { max-width: 60vw; font-size: 14px; }
.touch #touchMenu .picker { width: auto; }
.touch #touchMenu .options button { padding: 8px 10px; }
.touch #touchMenu .side summary { font-size: 12px; padding: 4px 0; }
.touch #touchMenu .side label, .touch #touchMenu .hint { font-size: 13px; }
.touch #touchMenu .switch { padding: 6px 0; }
.touch #hud input, .touch #hud textarea, .touch #challenges input { font-size: 16px; }      /* smaller text makes a phone zoom in when you type */
.touch #hud input[type="number"] { width: 80px; }
#touchHelp { position: absolute; left: 50%; top: 42%; transform: translate(-50%, -50%); z-index: 4; width: min(320px, calc(100% - 40px)); display: grid; gap: 6px; padding: 12px 14px; text-align: center; font-size: 13px; border-color: var(--line-bright); pointer-events: auto; }
#touchHelp b { font-size: 14px; }
#touchHelp small { color: var(--ink-dim); }

/* The windows (review, Challenges, sheets) on a narrow screen. */
@media (max-width: 620px) {
  .cards { grid-template-columns: 1fr 1fr; }
  .trees { grid-template-columns: 1fr; }
  .review { padding: 12px; }
  .challenge-line { flex-wrap: wrap; }
  .tiles { grid-template-columns: 1fr 1fr; }
  .speeds { display: none; }
}
.touch .review { max-height: calc(100% - 16px); -webkit-overflow-scrolling: touch; }
.touch .review button { padding: 7px 12px; font-size: 13px; }

/* --- Interface size: the windows over the game and the tooltips follow it (js/hud.js sets --ui) --- */
.review { zoom: var(--ui, 1); width: min(640px, calc(92vw / var(--ui, 1))); max-height: calc(84vh / var(--ui, 1)); }
.sheet { width: min(760px, calc(94vw / var(--ui, 1))); }
#tip, #moveBanner { zoom: var(--ui, 1); }
.touch .review { max-height: calc(100% - 16px); }

/* --- Colour-blind colours: html gets the class "cb". Nothing is told apart by red against green alone; marks
       that matter get a shape as well. Blue, orange, yellow and pink are the colours of the Okabe-Ito set. --- */
.cb { --health: #009e73; --mana: #0072b2; --hostile: #d55e00; --bad: #f0b27a; }
.cb .execute .bar.health i { background: #f0e442; }
.cb .execute .bar.health button { color: #17101f; text-shadow: none; }
.cb .bar.health.low i { background: #cc79a7; }
.cb .castbar.channel i { background: #56b4e9; }
.cb .castbar.interrupted { box-shadow: 0 0 0 2px #fff; }
.cb .castbar.interrupted i { background: #7a3a00; }
.cb .error-text, .cb .distance.far { color: #f0b27a; }
.cb .dotbar i { background: rgba(204, 121, 167, 0.75); }
.cb .dotbar.fire i { background: rgba(230, 159, 0, 0.8); }
.cb .dotbar.now .dotbar-track { box-shadow: 0 0 0 2px #f0e442 inset; }
.cb .dotbar.now b { color: #f0e442; }
.cb .dotbar.now b::before { content: '! '; }
.cb .dotbar.next .dotbar-track { box-shadow: none; outline: 1px dashed #fff; outline-offset: -1px; }
.cb .sim-hint { box-shadow: 0 0 0 1px #56b4e9; }
.cb .sim-hint b, .cb .rotation li.now, .cb .rotation li.now::before { color: #56b4e9; }
.cb .slot.hint { border-color: #56b4e9; box-shadow: 0 0 0 2px #56b4e9 inset, 0 0 9px rgba(86, 180, 233, 0.6); outline: 2px dashed #fff; outline-offset: -6px; }
.cb .opener i.right { box-shadow: 0 0 0 2px #56b4e9; }
.cb .opener i.right::after { color: #56b4e9; }
.cb .opener i.wrong { box-shadow: 0 0 0 2px #e69f00; outline: 1px dashed #fff; outline-offset: 2px; }
.cb .opener i.wrong::after { color: #e69f00; }
.cb .meter li i { background: rgba(204, 121, 167, 0.55); }
.cb .meter li.fire i { background: rgba(230, 159, 0, 0.6); }
.cb .meter li.pet i { background: rgba(86, 180, 233, 0.5); }
.cb .plate, .cb .hostile .unit-name { color: #f3c08f; }
.cb .plate.called .tag { border-color: #f0e442; box-shadow: 0 0 9px 1px #f0e442; }
.cb .plate.called .tag::before { color: #f0e442; }
.cb #moveBanner { background: rgba(120, 62, 0, 0.92); border-color: #e69f00; }
.cb .review tr.behind td, .cb .review table.cost td:last-child { color: #f3c08f; }
.cb .review tr.behind td:first-child::before { content: '\25BC  '; font-size: 9px; }
.cb .tl-casts i.idle { background: repeating-linear-gradient(45deg, rgba(230, 159, 0, 0.55) 0 3px, transparent 3px 7px); box-shadow: 0 0 0 1px #e69f00 inset; }
.cb .tl-casts i { background: #f0e442; }
.cb .tl-casts i.chan { background: #56b4e9; }
.cb .tl-casts i.stopped { background: #8a8a8a; }
.cb .tl-aura i { background: #cc79a7; }
.cb .tl-aura.fire i { background: #e69f00; }
.cb .tl-aura i.clip, .cb .tl-aura.fire i.clip { background: #fff; }
.cb .log li.miss { color: #9aa0b5; }
.cb .float.miss { color: #cfe6ff; }
.cb .lesson-checks li.ok i, .cb .challenge-line b.pass, .cb .card.lesson.passed h4 b, .cb .review table.progress-table td.trend.good { color: #56b4e9; }
.cb .lesson-checks li.bad i, .cb .challenge-line b.fail, .cb .review table.progress-table td.trend.bad { color: #e69f00; }

/* --- Start-up failure ---------------------------------------------------- */
#fatal { position: fixed; z-index: 40; left: 50%; top: 40%; transform: translate(-50%, -50%); max-width: 480px; padding: 16px 20px; background: #2a1014; border: 1px solid var(--hostile); border-radius: 8px; color: #ffd9d5; font-size: 14px; text-align: center; }
