Files
cypher-player-assistant/index.html

393 lines
14 KiB
HTML
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.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale: 1">
<title>Cypher Player Assistant</title>
<link rel="stylesheet" type="text/css" href="static/reset.css">
<style>
/* Themes and theme switcher */
:root {
/* Dark Color Scheme */
--dark-bg: #111111;
--dark-text: #eeeeee;
--dark-box-border: #333333;
--dark-hl-box-border: #cccccc;
/* Light Color Scheme */
--light-bg: #eeeeee;
--light-text: #111111;
--light-box-border: #cccccc;
--light-hl-box-border: #333333;
/* Defaults */
--bg: var(--light-bg);
--text: var(--light-text);
--box-border: var(--light-box-border);
--hl-box-border: var(--light-hl-box-border);
}
#color-scheme {
display: none;
}
#color-scheme:checked ~ .color-scheme-wrapper {
--bg: var(--dark-bg);
--text: var(--dark-text);
--box-border: var(--dark-box-border);
--hl-box-border: var(--dark-hl-box-border);
}
#color-scheme:checked ~ .color-scheme-wrapper .dark-mode-hide {
display: none;
}
#color-scheme:checked ~ .color-scheme-wrapper .light-mode-hide {
display: initial;
}
.dark-mode-hide {
display: initial;
}
.light-mode-hide {
display: none;
}
@media(prefers-color-scheme: dark) {
:root {
--bg: var(--dark-bg);
--text: var(--dark-text);
--box-border: var(--dark-box-border);
--hl-box-border: var(--dark-hl-box-border);
}
#color-scheme:checked ~ .color-scheme-wrapper {
--bg: var(--light-bg);
--text: var(--light-text);
--box-border: var(--light-box-border);
--hl-box-border: var(--light-hl-box-border);
}
#color-scheme:checked ~ .color-scheme-wrapper .dark-mode-hide {
display: initial;
}
#color-scheme:checked ~ .color-scheme-wrapper .light-mode-hide {
display: none;
}
.dark-mode-hide {
display: none;
}
.light-mode-hide {
display: initial;
}
}
.color-scheme-wrapper {
min-height: 100vh;
background: var(--bg);
color: var(--text);
}
#color-scheme-changer {
position: fixed;
text-align: center;
top: 0;
right: 0;
font-size: 150%;
width: 1.5em;
cursor: pointer;
}
.color-scheme-toggle {
cursor: pointer;
}
.color-scheme-toggle span {
cursor: pointer;
}
.dark-mode-hide, .light-mode-hide {
cursor: pointer;
}
.dark-mode-hide {
background-color: var(--dark-bg);
color: var(--dark-text);
}
.light-mode-hide {
background-color: var(--light-bg);
color: var(--light-text);
}
/* Outline and generic styles */
body {
background-color: var(--bg);
color: var(--text);
font-family: sans-serif;
}
h1 {
width: 100%;
font-family: serif;
text-align: center;
}
#warn-no-local-storage {
display: none;
color: red;
}
.box {
width: 80%;
border-width: 2px;
border-style: solid;
border-color: var(--box-border);
border-radius: 10px;
margin: 0 auto 1em auto;
padding: 1em;
}
.box h2 {
display: initial;
position: relative;
top: -1.8em;
padding: 0 .5em;
color: var(--hl-box-border);
background-color: var(--bg);
font-size: 100%;
font-weight: normal;
}
.box h2::after {
display: block;
content: "";
margin-bottom: -1.5em;
}
input {
border: 1px solid var(--hl-box-border);
background-color: var(--bg);
color: var(--text);
}
input[type=number] {
width: 4em;
}
input[disabled] {
border-color: var(--box-border);
}
/* No character loaded box (AKA the welcome screen) */
#cont-no-loaded {
text-align: center;
}
.pool-container {
display: inline-block;
border-width: 2px;
border-style: solid;
border-color: var(--box-border);
border-radius: 10px;
width: 32%;
padding: .6em;
}
.pool-container:has(> h3 > input[name=pool-selector]:checked) {
border-color: var(--hl-box-border);
}
input[name=pool-selector] {
display: none;
}
.pool-container h4 {
color: var(--hl-box-border);
font-weight: normal;
font-size: 80%;
}
/* Input unlockers */
.input-unlocker {
display: none;
}
.input-unlocker + label > .input-locked {
display: initial;
cursor: pointer;
}
.input-unlocker + label > .input-unlocked {
display: none;
cursor: pointer;
}
.input-unlocker:checked + label > .input-locked {
display: none;
}
.input-unlocker:checked + label .input-unlocked {
display: initial;
}
</style>
</head>
<body>
<input id="color-scheme" type="checkbox">
<div class="color-scheme-wrapper">
<div id="color-scheme-changer">
<label for="color-scheme" id="color-scheme-toggle">
<span class="dark-mode-hide"></span>
<span class="light-mode-hide"></span>
</label>
</div>
<h1>
Cypher Player Assistant
<span id="warn-no-local-storage" title="Local Storage is not available. You can import/export data, but the app wont save it between sessions!">!</span>
</h1>
<div id="cont-no-loaded" class="box">
No character is loaded.
</div>
<div id="cont-character-sheet">
<div class="box">
<h2>Character data</h2>
<strong>Campaign</strong> <input type="text" id="inp-campaign-name">
<strong>Name</strong> <input type="text" id="inp-character-name">
<strong>Max Effort</strong> <input type="number" id="inp-max-effort" min="1" value="1" disabled>
<input type="checkbox" class="input-unlocker" id="max-effort-unlocker">
<label for="max-effort-unlocker">
<span class="input-locked">🔒</span>
<span class="input-unlocked">🔓</span>
</label>
<strong>Armor</strong> <input type="number" id="inp-armor" min="0" value="0" disabled>
<input type="checkbox" class="input-unlocker" id="armor-unlocker">
<label for="armor-unlocker">
<span class="input-locked">🔒</span>
<span class="input-unlocked">🔓</span>
</label>
</div>
<div class="box">
<h2>Pools</h2>
<div class="pool-container">
<h3>
<input id="pool-selector-might" type="radio" name="pool-selector" value="might">
<label for="pool-selector-might">Might</label>
</h3>
<h4>Pool</h4>
<input type="number" id="inp-pool-value-might" min="0" value="0">
/
<input type="number" id="inp-pool-max-might" min="0" value="0" disabled>
<input type="checkbox" class="input-unlocker" id="pool-max-unlocker-might">
<label for="pool-max-unlocker-might">
<span class="input-locked">🔒</span>
<span class="input-unlocked">🔓</span>
</label>
<h4>Edge</h4>
<input type="number" id="inp-pool-edge-might" min="0" value="0" disabled>
<input type="checkbox" class="input-unlocker" id="pool-edge-unlocker-might">
<label id="pool-edge-unlocker-label-might" for="pool-edge-unlocker-might">
<span class="input-locked">🔒</span>
<span class="input-unlocked">🔓</span>
</label>
</div>
<div class="pool-container">
<h3>
<input id="pool-selector-speed" type="radio" name="pool-selector" value="speed">
<label for="pool-selector-speed">Speed</label>
</h3>
<h4>Pool</h4>
<input type="number" id="inp-pool-value-speed" min="0" value="0">
/
<input type="number" id="inp-pool-max-speed" min="0" value="0" disabled>
<input type="checkbox" class="input-unlocker" id="pool-max-unlocker-speed">
<label for="pool-max-unlocker-speed">
<span class="input-locked">🔒</span>
<span class="input-unlocked">🔓</span>
</label>
<h4>Edge</h4>
<input type="number" id="inp-pool-edge-speed" min="0" value="0" disabled>
<input type="checkbox" class="input-unlocker" id="pool-edge-unlocker-speed">
<label id="pool-edge-unlocker-label-speed" for="pool-edge-unlocker-speed">
<span class="input-locked">🔒</span>
<span class="input-unlocked">🔓</span>
</label>
</div>
<div class="pool-container">
<h3>
<input id="pool-selector-intellect" type="radio" name="pool-selector" value="intellect">
<label for="pool-selector-intellect">Intellect</label>
</h3>
<h4>Pool</h4>
<input type="number" id="inp-pool-value-intellect" min="0" value="0">
/
<input type="number" id="inp-pool-max-intellect" min="0" value="0" disabled>
<input type="checkbox" class="input-unlocker" id="pool-max-unlocker-intellect">
<label for="pool-max-unlocker-intellect">
<span class="input-locked">🔒</span>
<span class="input-unlocked">🔓</span>
</label>
<h4>Edge</h4>
<input type="number" id="inp-pool-edge-intellect" min="0" value="0" disabled>
<input type="checkbox" class="input-unlocker" id="pool-edge-unlocker-intellect">
<label for="pool-edge-unlocker-intellect">
<span class="input-locked">🔒</span>
<span class="input-unlocked">🔓</span>
</label>
</div>
</div>
</div>
</div>
<script>
const checkLocalStorage = () => {
let storage;
try {
storage = window.localStorage;
const x = "__storage_test__";
storage.setItem(x, x);
storage.removeItem(x);
return true;
} catch (e) {
return (
e instanceof DOMException &&
e.name === "QuotaExceededError" &&
// acknowledge QuotaExceededError only if there's something already stored
storage &&
storage.length !== 0
);
}
};
const toggleInputLockedHandler = (evt) => {
let cb = evt.target;
let pool = cb.id.slice(cb.id.lastIndexOf("-") + 1);
let input = cb.previousElementSibling;
let toUnlock = cb.checked;
input.disabled = !toUnlock;
};
document.addEventListener(
"DOMContentLoaded",
() => {
if (!checkLocalStorage()) {
document.getElementById("warn-no-local-storage").style.display = "initial";
alert("Local Storage is not available, saving and loading data will be unavailable.");
}
document
.querySelectorAll(".input-unlocker")
.forEach((elem) => {elem.addEventListener("change", toggleInputLockedHandler)});
},
);
</script>
</body>
</html>