MosswartOverlord/static/style.css
2025-06-10 19:21:21 +00:00

721 lines
14 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* style.css - Core styles for Dereth Tracker Single-Page Application
*
* Defines CSS variables for theming, layout rules for sidebar and map,
* interactive element styling (buttons, inputs), and responsive considerations.
*/
/* CSS Custom Properties for theme colors and sizing */
:root {
--sidebar-width: 340px;
--bg-main: #111;
--bg-side: #1a1a1a;
--card: #222;
--card-hov:#333;
--text: #eee;
--accent: #88f;
}
/*
* style.css - Styling for Dereth Tracker SPA frontend.
* Defines layout, theming variables, and component styles (sidebar, map, controls).
*/
/* Placeholder text in chat input should be white */
.chat-input::placeholder {
color: #fff;
opacity: 0.7;
}
html {
margin: 0;
height: 100%;
width: 100%;
}
body {
margin: 0;
height: 100%;
display: flex;
overflow: hidden;
font-family: "Segoe UI", sans-serif;
background: var(--bg-main);
color: var(--text);
}
.sort-buttons {
/* Container for sorting controls; uses flex layout to distribute buttons equally */
display: flex;
gap: 2px;
margin: 12px 16px 8px;
}
.sort-buttons .btn {
/* Compact styling for sort buttons to fit 6 options */
flex: 1;
padding: 4px 6px;
background: #333;
color: #ccc;
border: 1px solid #666;
border-radius: 3px;
text-align: center;
cursor: pointer;
user-select: none;
font-size: 0.75rem;
font-weight: 500;
transition: all 0.15s;
min-width: 0;
white-space: nowrap;
overflow: hidden;
}
.sort-buttons .btn:hover {
background: #444;
color: #fff;
border-color: #777;
}
.sort-buttons .btn.active {
/* Active sort button highlighted with accent color */
background: var(--accent);
color: #111;
border-color: var(--accent);
position: relative;
}
.sort-buttons .btn.active:hover {
background: var(--accent);
color: #111;
}
/* Sort direction indicators */
.sort-buttons .btn.active::after {
content: '';
position: absolute;
top: 2px;
right: 2px;
width: 0;
height: 0;
border-left: 3px solid transparent;
border-right: 3px solid transparent;
}
/* Most sorts are descending (down arrow) */
.sort-buttons .btn.active::after {
border-top: 4px solid #111;
}
/* Name and KPR are ascending (up arrow) */
.sort-buttons .btn.active[data-value="name"]::after,
.sort-buttons .btn.active[data-value="kpr"]::after {
border-top: none;
border-bottom: 4px solid #111;
}
/* ---------- sidebar --------------------------------------------- */
#sidebar {
width: var(--sidebar-width);
scrollbar-width: none;
background: var(--bg-side);
border-right: 2px solid #333;
box-sizing: border-box;
padding: 18px 16px;
overflow-y: auto;
}
#sidebar h2 {
margin: 8px 0 12px;
font-size: 1.25rem;
color: var(--accent);
}
#playerList {
list-style: none;
margin: 0;
padding: 0;
}
/* Filter input in sidebar for player list */
.player-filter {
width: 100%;
padding: 6px 8px;
margin-bottom: 12px;
background: var(--card);
color: var(--text);
border: 1px solid #555;
border-radius: 4px;
font-size: 0.9rem;
box-sizing: border-box;
}
#playerList li {
margin: 4px 0;
padding: 6px 8px;
background: var(--card);
border-left: 4px solid #555;
cursor: pointer;
}
#playerList li:hover {
background: var(--card-hov);
}
#playerList li.selected {
background: #454545;
}
/* ---------- map container --------------------------------------- */
#mapContainer {
flex: 1;
min-width: 0;
min-height: 0;
position: relative;
overflow: hidden;
background: #000;
cursor: grab;
}
#mapContainer.dragging {
cursor: grabbing;
}
#mapGroup {
position: absolute;
top: 0;
left: 0;
transform-origin: 0 0;
}
#map {
display: block;
user-select: none;
pointer-events: none;
}
/* ---------- dots ------------------------------------------------ */
#dots {
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
.dot {
position: absolute;
width: 6px;
height: 6px;
border-radius: 50%;
border: 1px solid #000;
transform: translate(-50%, -50%);
/* enable events on each dot */
pointer-events: auto;
cursor: pointer;
}
.dot.highlight {
width: 10px;
height: 10px;
animation: blink 0.6s step-end infinite;
}
@keyframes blink {
50% { opacity: 0; }
}
/* ---------- tooltip --------------------------------------------- */
.tooltip {
position: absolute;
display: none;
background: rgba(0, 0, 0, 0.8);
color: #fff;
padding: 4px 8px;
border-radius: 4px;
font-size: 0.8rem;
pointer-events: none;
white-space: nowrap;
z-index: 1000;
}
/* ---------- coordinate display ---------------------------------- */
.coordinates {
position: absolute;
display: none;
background: rgba(0, 50, 100, 0.9);
color: #fff;
padding: 3px 6px;
border-radius: 3px;
font-size: 0.75rem;
font-family: monospace;
pointer-events: none;
white-space: nowrap;
z-index: 999;
border: 1px solid rgba(100, 150, 200, 0.5);
}
/* make each row a flex container */
/* 2-column flex layout for each player row */
/* make each row a flex container */
/* make each row a vertical stack */
/* make each player row into a 3×2 grid */
#playerList li {
display: grid;
grid-template-columns: 1fr auto auto auto auto auto;
grid-template-rows: auto auto auto auto;
grid-template-areas:
"name name name name name name"
"kills totalkills kph kph kph kph"
"rares kpr meta meta meta meta"
"onlinetime deaths tapers tapers tapers tapers";
gap: 4px 8px;
margin: 6px 0;
padding: 8px 10px;
background: var(--card);
border-left: 4px solid transparent;
transition: background 0.15s;
font-size: 0.85rem;
}
/* assign each span into its grid cell */
.player-name { grid-area: name; font-weight: 600; color: var(--text); }
.coordinates-inline { font-size: 0.75rem; color: #aaa; font-weight: 400; margin-left: 8px; }
.stat.kills { grid-area: kills; }
.stat.total-kills { grid-area: totalkills; }
.stat.kph { grid-area: kph; }
.stat.rares { grid-area: rares; }
.stat.kpr { grid-area: kpr; }
.stat.meta { grid-area: meta; }
.stat.onlinetime { grid-area: onlinetime; }
.stat.deaths { grid-area: deaths; }
.stat.tapers { grid-area: tapers; }
/* pill styling */
#playerList li .stat {
background: rgba(255,255,255,0.1);
padding: 4px 8px;
border-radius: 12px;
display: inline-block;
font-size: 0.75rem;
white-space: nowrap;
color: var(--text);
}
/* icons & suffixes */
.stat.kills::before { content: "⚔️ "; }
.stat.total-kills::before { content: "🏆 "; }
.stat.kph::after { content: " KPH"; font-size:0.7em; color:#aaa; }
.stat.rares::before { content: "💎 "; }
.stat.rares::after { content: " Rares"; font-size:0.7em; color:#aaa; }
.stat.kpr::before { content: "📊 "; }
.stat.kpr::after { content: " KPR"; font-size:0.7em; color:#aaa; }
/* metastate pill colors are assigned dynamically: green for “good” states, red otherwise */
#playerList li .stat.meta {
/* fallback */
background: var(--accent);
color: #111;
}
#playerList li .stat.meta.green {
background: #2ecc71; /* pleasant green */
color: #111;
}
#playerList li .stat.meta.red {
background: #e74c3c; /* vivid red */
color: #fff;
}
/* ---------- chat window styling ------------------------------- */
.chat-btn, .stats-btn, .inventory-btn {
margin-top: 4px;
padding: 2px 6px;
background: var(--accent);
color: #111;
border: none;
border-radius: 3px;
font-size: 0.75rem;
cursor: pointer;
}
.chat-window, .stats-window, .inventory-window {
position: absolute;
top: 10px;
/* position window to start just right of the sidebar */
left: calc(var(--sidebar-width) + 10px);
/* increase default size for better usability */
width: 760px; /* increased width for larger terminal area */
height: 300px;
background: var(--card);
border: 1px solid #555;
display: flex;
flex-direction: column;
z-index: 10000;
}
.chat-header {
display: flex;
justify-content: space-between;
align-items: center;
background: var(--accent);
padding: 4px;
color: #111;
cursor: move; /* indicates the header is draggable */
}
.chat-close-btn {
background: transparent;
border: none;
font-size: 1.2rem;
line-height: 1;
cursor: pointer;
}
.chat-messages {
flex: 1;
overflow-y: auto;
padding: 4px;
font-size: 0.85rem;
color: #fff;
/* reserve space so messages aren't hidden behind the input */
padding-bottom: 40px;
}
.chat-form {
display: flex;
border-top: 1px solid #333;
/* fix input area to the bottom of the chat window */
position: absolute;
left: 0;
right: 0;
bottom: 0;
background: #333;
z-index: 10;
}
.chat-input {
flex: 1;
padding: 4px 6px;
border: none;
background: #333;
color: #fff;
outline: none;
}
/* Prevent text selection while dragging chat windows */
body.noselect, body.noselect * {
user-select: none !important;
}
.stat.onlinetime::before { content: "🕑 "}
.stat.deaths::before { content: "💀 "}
.stat.tapers::before {
content: "";
display: inline-block;
width: 16px;
height: 16px;
background-image: url('prismatic-taper-icon.png');
background-size: contain;
background-repeat: no-repeat;
margin-right: 4px;
vertical-align: text-bottom;
}
/* hover & selected states */
#playerList li:hover { background: var(--card-hov); }
#playerList li.selected { background: #454545; }
/* trails paths */
#trails {
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
.trail-path {
fill: none;
stroke-width: 2px;
stroke-opacity: 0.7;
stroke-linecap: round;
stroke-linejoin: round;
}
/* -------------------------------------------------------- */
/* Stats window: 2×2 iframe grid and flexible height */
.stats-window {
/* allow height to expand to fit two rows of panels */
height: auto;
}
.stats-window .chat-messages {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: auto;
gap: 10px;
padding: 10px;
overflow: visible;
background: #f7f7f7;
color: #000;
}
.stats-window iframe {
width: 350px;
height: 200px;
border: none;
}
/* ---------- stats window time controls --------------------------- */
.stats-controls {
display: flex;
gap: 8px;
padding: 10px 15px;
background: #333;
border-bottom: 1px solid #555;
}
.time-range-btn {
padding: 6px 12px;
background: #444;
color: #ccc;
border: 1px solid #666;
border-radius: 4px;
font-size: 0.85rem;
cursor: pointer;
transition: all 0.2s;
}
.time-range-btn:hover {
background: #555;
color: #fff;
}
.time-range-btn.active {
background: var(--accent);
color: #111;
border-color: var(--accent);
}
/* ---------- inventory window styling ----------------------------- */
.inventory-content {
flex: 1;
padding: 15px;
background: var(--card);
color: var(--text);
overflow-y: auto;
}
.inventory-placeholder {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 1.1rem;
color: #888;
font-style: italic;
}
/* Inventory window specific styles */
.inventory-window {
position: fixed;
top: 100px;
left: 400px;
width: 600px;
height: 500px;
background: var(--card);
border: 1px solid #555;
border-radius: 8px;
display: flex;
flex-direction: column;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
z-index: 1000;
}
.inventory-loading {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
font-size: 1.1rem;
color: #888;
}
/* Inventory grid layout - matches AC original */
.inventory-grid {
display: grid;
grid-template-columns: repeat(8, 36px);
gap: 0px;
padding: 8px;
background:
linear-gradient(90deg, #333 1px, transparent 1px),
linear-gradient(180deg, #333 1px, transparent 1px),
#111;
background-size: 36px 36px;
max-height: 450px;
overflow-y: auto;
border: 1px solid #444;
}
/* Individual inventory slots - no borders like AC original */
.inventory-slot {
width: 36px;
height: 36px;
background: transparent;
border: none;
border-radius: 0;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: background 0.1s ease;
padding: 0;
margin: 0;
}
.inventory-slot:hover {
background: rgba(136, 136, 255, 0.3);
}
.inventory-icon {
width: 36px;
height: 36px;
object-fit: contain;
image-rendering: pixelated;
/* Improve icon appearance - make background match slot */
border: none;
outline: none;
background: #1a1a1a;
border-radius: 2px;
}
/* Icon compositing for overlays/underlays - matches AC original */
.item-icon-composite {
position: relative;
width: 36px;
height: 36px;
display: block;
background: transparent;
padding: 0;
margin: 0;
}
.icon-underlay,
.icon-base,
.icon-overlay {
position: absolute;
top: 0;
left: 0;
width: 36px;
height: 36px;
border: none;
outline: none;
background: transparent;
padding: 0;
margin: 0;
}
.icon-underlay {
z-index: 1;
}
.icon-base {
z-index: 2;
}
.icon-overlay {
z-index: 3;
}
/* Item count */
.inventory-count {
text-align: center;
padding: 10px;
color: #888;
font-size: 0.9rem;
}
/* Inventory tooltip */
.inventory-tooltip {
position: fixed;
background: rgba(0, 0, 0, 0.95);
border: 1px solid #555;
border-radius: 4px;
padding: 10px;
pointer-events: none;
z-index: 20000;
display: none;
min-width: 200px;
max-width: 350px;
font-size: 0.9rem;
}
.tooltip-name {
font-weight: bold;
color: var(--accent);
margin-bottom: 8px;
font-size: 1rem;
}
.tooltip-section {
margin-bottom: 6px;
}
.tooltip-section-title {
font-weight: bold;
color: #ffd700;
margin-bottom: 3px;
font-size: 0.85rem;
text-transform: uppercase;
}
.tooltip-stats {
display: flex;
flex-direction: column;
gap: 3px;
font-size: 0.9rem;
}
.tooltip-stat,
.tooltip-requirement,
.tooltip-property {
color: #ddd;
font-size: 0.85rem;
margin-left: 8px;
}
.tooltip-requirement {
color: #ffaa00;
}
.tooltip-property {
color: #88ff88;
}
.tooltip-string {
color: #add8e6;
font-size: 0.8rem;
margin-left: 8px;
}
.tooltip-spell {
color: #dda0dd;
font-size: 0.8rem;
margin-left: 8px;
margin-bottom: 2px;
}
.spell-name {
color: #4a90e2;
font-weight: 500;
}
.spell-school {
font-size: 11px;
color: #888;
font-style: italic;
}
.tooltip-info {
color: #f0e68c;
font-size: 0.8rem;
margin-left: 8px;
}
.tooltip-description {
color: #ccc;
font-style: italic;
margin-top: 8px;
padding-top: 8px;
border-top: 1px solid #444;
}
.tooltip-value {
color: #4CAF50;
}
.tooltip-burden {
color: #FFC107;
}
.tooltip-source {
font-size: 10px;
color: #888;
margin-top: 4px;
text-align: center;
}