trimmed ressources

This commit is contained in:
cheetah 2025-04-05 01:37:54 +02:00
parent dba7f12e95
commit fde63704eb
4 changed files with 610 additions and 594 deletions

View file

@ -1,147 +1,14 @@
function promiseXHR(a,b,g){var n="XMLHttpRequest",h="setRequestHeader",k="constructor",t="hasOwnProperty",u="POST",v="content-type",w="x-requested-with",x=Object,y=function(d){return encodeURIComponent(d).replace(/%20/g,"+")},c,e,f,l,z,m;
if(b)switch(b[k]){case self.FormData:l=1;break;case x:for(p in m="_="+(new Date).getTime(),b)if(b[t](p))for(b[p]&&b[p][k]==Array||(b[p]=[b[p]]),c=0;c<b[p].length;c++)m+="&"+y(p)+"="+y(b[p][c]);case Number:g=g||b,b=m}switch(a[k]){case x:e=a.method,f=a.headers,a=a.url;case String:c=a||location.href.split("#")[0];(e=e||(b?u:"GET"))in{GET:1,HEAD:1}&&b&&(c+=(0>c.indexOf("?")?"?":"&")+b);a=new self[n];
a.open(e,c);for(p in f)f[t](p)&&(a[h](c=p.toLowerCase(),f[p]),c==v&&(l=1),c==w&&(z=1));z||a[h](w,n);l||e==u&&a[h](v,"application/x-www-form-urlencoded")}return new Promise(function(A,B){a.onreadystatechange=function(){4==a.readyState&&A(a)};g|0&&setTimeout(function(){B("timeout");a.abort()},g);a.send(b)})}self.Promise||document.write("<script src=//cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js></script>")
//
// TIME=HHMMDDMMYY
const topNav = document.getElementById("topnav")
function selTab(evt, id) {
var tabcontent, tablinks
tablinks = document.getElementsByClassName("tablinks")
tabcontent = document.getElementsByClassName("tabcontent")
for (let tab of tabcontent) {
tab.style.display = "none"
var link = tab.dataset.src
if (link) {
tab.getElementsByTagName("iframe")[0].setAttribute("src", "")
}
}
for(let link of tablinks)
link.className = "tablinks"
var act = document.getElementById(id)
act.style.display = "flex"
evt.currentTarget.className += " active"
var link = act.dataset.src
if(link) {
act.getElementsByTagName("iframe")[0].setAttribute("src", link)
}
topNav.className = "topnav"
}
function toggleResponsive() {
topNav.className = topNav.className === "topnav" ? "topnav responsive" : "topnav"
//topNav.className = ["topnav","responsive"].slice(0,1+(x.className === "topnav")).join(" ")
}
let contactsData = []
function delContact(i) {
contactsData.splice(i, 1);
storeContacts()
window.location.reload()
}
function addContact(doReloadAfter) {
contactsData.push({
r: parseInt(document.querySelector('#newcon_r').value),
f: parseInt(document.querySelector('#newcon_f').value),
tl: parseInt(document.querySelector('#newcon_tl').value),
n: document.querySelector('#newcon_n').value,
t: document.querySelector('#newcon_t').value,
})
storeContacts()
if (doReloadAfter) window.location.reload()
}
function resetContacts() {
if (confirm("do you want to delete all contacts?")) {
promiseXHR("/contacts.json", JSON.stringify([]))
.then(() => alert("reset contacts"))
}
}
function storeContacts() {
promiseXHR("/contacts.json", JSON.stringify(contactsData))
.then(() => alert("stored contacts"))
}
let firstFetch = true
function fetchCfgVals() {
if (!firstFetch) return
firstFetch = false
promiseXHR("/config.json").then(j=>{
const res = JSON.parse(j.responseText)
console.log(res)
for (let key in res) {
let e = document.getElementById(key) || document.getElementsByName(key)[0]
if (!!e) {
if (e.type == 'checkbox') {
e.checked = res[key];
} else {
e.value = res[key]
}
}
}
})
promiseXHR("/contacts.json").then(j=>{
const contactlist = document.getElementById("contactlist")
contactsData = JSON.parse(j.responseText)
console.log("received contacts from esp", contactsData)
for (let contactI in contactsData) {
const contact = contactsData[contactI]
const li = document.createElement("li")
li.innerHTML = `<form action="/page" class="styled-form no-top-margin">
<h3>${ contact.n }</h3>
<input type="hidden" name="ric" value="${ contact.r }" />
<input type="hidden" name="fun" value="${ contact.f }" />
function promiseXHR(a,b,g){var n="XMLHttpRequest",h="setRequestHeader",k="constructor",t="hasOwnProperty",u="POST",v="content-type",w="x-requested-with",x=Object,y=function(d){return encodeURIComponent(d).replace(/%20/g,"+")},c,e,f,l,z,m;if(b){switch(b[k]){case self.FormData:l=1;break;case x:for(p in m="_="+(new Date).getTime(),b){if(b[t](p)){for(b[p]&&b[p][k]==Array||(b[p]=[b[p]]),c=0;c<b[p].length;c+=1){m+="&"+y(p)+"="+y(b[p][c])}}}case Number:g=g||b,b=m}}switch(a[k]){case x:e=a.method,f=a.headers,a=a.url;case String:c=a||location.href.split("#")[0];(e=e||(b?u:"GET"))in{GET:1,HEAD:1}&&b&&(c+=(0>c.indexOf("?")?"?":"&")+b);a=new self[n];a.open(e,c);for(p in f){f[t](p)&&(a[h](c=p.toLowerCase(),f[p]),c==v&&(l=1),c==w&&(z=1))}z||a[h](w,n);l||e==u&&a[h](v,"application/x-www-form-urlencoded")}return new Promise(function(A,B){a.onreadystatechange=function(){4==a.readyState&&A(a)};g|0&&setTimeout(function(){B("timeout");a.abort()},g);a.send(b)})}self.Promise||document.write("<script src=//cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js></script>");const topNav=document.getElementById("topnav");function selTab(evt,id){var tabcontent,tablinks;tablinks=document.getElementsByClassName("tablinks");tabcontent=document.getElementsByClassName("tabcontent");for(let tab of tabcontent){tab.style.display="none";var link=tab.dataset.src;if(link){tab.getElementsByTagName("iframe")[0].setAttribute("src","")}}for(let link of tablinks){link.className="tablinks"}var act=document.getElementById(id);act.style.display="flex";evt.currentTarget.className+=" active";var link=act.dataset.src;if(link){act.getElementsByTagName("iframe")[0].setAttribute("src",link)}topNav.className="topnav"}function toggleResponsive(){topNav.className=topNav.className==="topnav"?"topnav responsive":"topnav";}let contactsData=[];function delContact(i){contactsData.splice(i,1);storeContacts();window.location.reload()}function addContact(doReloadAfter){contactsData.push({r:parseInt(document.querySelector('#newcon_r').value),f:parseInt(document.querySelector('#newcon_f').value),tl:parseInt(document.querySelector('#newcon_tl').value),n:document.querySelector('#newcon_n').value,t:document.querySelector('#newcon_t').value});storeContacts();if(doReloadAfter){window.location.reload()}}function resetContacts(){if(confirm("do you want to delete all contacts?")){promiseXHR("/contacts.json",JSON.stringify([])).then(()=>alert("reset contacts"))}}function storeContacts(){promiseXHR("/contacts.json",JSON.stringify(contactsData)).then(()=>alert("stored contacts"))}let firstFetch=true;function fetchCfgVals(){if(!firstFetch){return}firstFetch=false;promiseXHR("/config.json").then(j=>{const res=JSON.parse(j.responseText);console.log(res);for(let key in res){let e=document.getElementById(key)||document.getElementsByName(key)[0];if(!!e){if(e.type=='checkbox'){e.checked=res[key]}else{e.value=res[key]}}}});promiseXHR("/contacts.json").then(j=>{const contactlist=document.getElementById("contactlist");contactsData=JSON.parse(j.responseText);console.log("received contacts from esp",contactsData);for(let contactI in contactsData){const contact=contactsData[contactI];const li=document.createElement("li");li.innerHTML=`<form action="/page" class="styled-form no-top-margin">
<h3>${contact.n }</h3>
<input type="hidden" name="ric" value="${contact.r }" />
<input type="hidden" name="fun" value="${contact.f }" />
<label for="text">Message</label>
<input type="text" name="text" value="${ contact.t }" />
<pre>RIC=${ contact.r } F=${ contact.f } TL=${ contact.tl }</pre>
<input type="text" name="text" value="${contact.t }" />
<pre>RIC=${contact.r } F=${contact.f } TL=${contact.tl }</pre>
<input class="btn" type="submit" name="add" value="queue" />
<input class="btn" type="submit" name="addtx" value="direct transmit" />
</form>
<div class="styled-form">
<button onClick="delContact(${ contactI })">del contact</button>
</div>
`
contactlist.appendChild(li)
}
})
}
document.getElementById("defaultTab").click()
for (let i of document.getElementsByTagName("input")) i.placeholder = i.name
function calculateTimeToTxTxt(type) {
document.querySelector("input[name='text']").value = calculateTime(type)
}
function calculateTime(type) {
const now = new Date();
// Extract date components
const hh = String(now.getHours()).padStart(2, '0');
const mm = String(now.getMinutes()).padStart(2, '0');
const DD = String(now.getDate()).padStart(2, '0');
const MM = String(now.getMonth() + 1).padStart(2, '0'); // Months are 0-based
const YY = String(now.getFullYear()).slice(-2); // Get last two digits of the year
// Construct the formatted string
const formattedTime = `${hh}${mm}${DD}${MM}${YY}`;
switch (type) {
case 'tpl':
return `#ZEIT=${formattedTime}#ZEIT=${formattedTime}`;
case 'swissphone':
return `;TIME=${formattedTime};TIME=${formattedTime}`;
default:
return 'Invalid type';
}
}
function populateTimezones() {
const timezones = Intl.supportedValuesOf('timeZone');
const select = document.getElementById("time_zone");
timezones.forEach(zone => {
const option = document.createElement("option");
option.value = zone;
option.textContent = zone;
select.appendChild(option);
});
}
populateTimezones();
`;contactlist.appendChild(li)}})}document.getElementById("defaultTab").click();for(let i of document.getElementsByTagName("input")){i.placeholder=i.name}function calculateTimeToTxTxt(type){document.querySelector("input[name='text']").value=calculateTime(type)}function calculateTime(type){const now=new Date();const hh=String(now.getHours()).padStart(2,'0');const mm=String(now.getMinutes()).padStart(2,'0');const DD=String(now.getDate()).padStart(2,'0');const MM=String(now.getMonth()+1).padStart(2,'0');const YY=String(now.getFullYear()).slice(-2);const formattedTime=`${ hh }${ mm }${ DD }${ MM }${ YY }`;switch(type){case 'tpl':return `#ZEIT=${ formattedTime }#ZEIT=${ formattedTime }`;case 'swissphone':return `;TIME=${ formattedTime };TIME=${ formattedTime }`;default:return 'Invalid type'}}function populateTimezones(){const timezones=Intl.supportedValuesOf('timeZone');const select=document.getElementById("time_zone");timezones.forEach(zone=>{const option=document.createElement("option");option.value=zone;option.textContent=zone;select.appendChild(option)})}populateTimezones();

147
data/script.src.js Normal file
View file

@ -0,0 +1,147 @@
function promiseXHR(a,b,g){var n="XMLHttpRequest",h="setRequestHeader",k="constructor",t="hasOwnProperty",u="POST",v="content-type",w="x-requested-with",x=Object,y=function(d){return encodeURIComponent(d).replace(/%20/g,"+")},c,e,f,l,z,m;
if(b)switch(b[k]){case self.FormData:l=1;break;case x:for(p in m="_="+(new Date).getTime(),b)if(b[t](p))for(b[p]&&b[p][k]==Array||(b[p]=[b[p]]),c=0;c<b[p].length;c++)m+="&"+y(p)+"="+y(b[p][c]);case Number:g=g||b,b=m}switch(a[k]){case x:e=a.method,f=a.headers,a=a.url;case String:c=a||location.href.split("#")[0];(e=e||(b?u:"GET"))in{GET:1,HEAD:1}&&b&&(c+=(0>c.indexOf("?")?"?":"&")+b);a=new self[n];
a.open(e,c);for(p in f)f[t](p)&&(a[h](c=p.toLowerCase(),f[p]),c==v&&(l=1),c==w&&(z=1));z||a[h](w,n);l||e==u&&a[h](v,"application/x-www-form-urlencoded")}return new Promise(function(A,B){a.onreadystatechange=function(){4==a.readyState&&A(a)};g|0&&setTimeout(function(){B("timeout");a.abort()},g);a.send(b)})}self.Promise||document.write("<script src=//cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js></script>")
//
// TIME=HHMMDDMMYY
const topNav = document.getElementById("topnav")
function selTab(evt, id) {
var tabcontent, tablinks
tablinks = document.getElementsByClassName("tablinks")
tabcontent = document.getElementsByClassName("tabcontent")
for (let tab of tabcontent) {
tab.style.display = "none"
var link = tab.dataset.src
if (link) {
tab.getElementsByTagName("iframe")[0].setAttribute("src", "")
}
}
for(let link of tablinks)
link.className = "tablinks"
var act = document.getElementById(id)
act.style.display = "flex"
evt.currentTarget.className += " active"
var link = act.dataset.src
if(link) {
act.getElementsByTagName("iframe")[0].setAttribute("src", link)
}
topNav.className = "topnav"
}
function toggleResponsive() {
topNav.className = topNav.className === "topnav" ? "topnav responsive" : "topnav"
//topNav.className = ["topnav","responsive"].slice(0,1+(x.className === "topnav")).join(" ")
}
let contactsData = []
function delContact(i) {
contactsData.splice(i, 1);
storeContacts()
window.location.reload()
}
function addContact(doReloadAfter) {
contactsData.push({
r: parseInt(document.querySelector('#newcon_r').value),
f: parseInt(document.querySelector('#newcon_f').value),
tl: parseInt(document.querySelector('#newcon_tl').value),
n: document.querySelector('#newcon_n').value,
t: document.querySelector('#newcon_t').value,
})
storeContacts()
if (doReloadAfter) window.location.reload()
}
function resetContacts() {
if (confirm("do you want to delete all contacts?")) {
promiseXHR("/contacts.json", JSON.stringify([]))
.then(() => alert("reset contacts"))
}
}
function storeContacts() {
promiseXHR("/contacts.json", JSON.stringify(contactsData))
.then(() => alert("stored contacts"))
}
let firstFetch = true
function fetchCfgVals() {
if (!firstFetch) return
firstFetch = false
promiseXHR("/config.json").then(j=>{
const res = JSON.parse(j.responseText)
console.log(res)
for (let key in res) {
let e = document.getElementById(key) || document.getElementsByName(key)[0]
if (!!e) {
if (e.type == 'checkbox') {
e.checked = res[key];
} else {
e.value = res[key]
}
}
}
})
promiseXHR("/contacts.json").then(j=>{
const contactlist = document.getElementById("contactlist")
contactsData = JSON.parse(j.responseText)
console.log("received contacts from esp", contactsData)
for (let contactI in contactsData) {
const contact = contactsData[contactI]
const li = document.createElement("li")
li.innerHTML = `<form action="/page" class="styled-form no-top-margin">
<h3>${ contact.n }</h3>
<input type="hidden" name="ric" value="${ contact.r }" />
<input type="hidden" name="fun" value="${ contact.f }" />
<label for="text">Message</label>
<input type="text" name="text" value="${ contact.t }" />
<pre>RIC=${ contact.r } F=${ contact.f } TL=${ contact.tl }</pre>
<input class="btn" type="submit" name="add" value="queue" />
<input class="btn" type="submit" name="addtx" value="direct transmit" />
</form>
<div class="styled-form">
<button onClick="delContact(${ contactI })">del contact</button>
</div>
`
contactlist.appendChild(li)
}
})
}
document.getElementById("defaultTab").click()
for (let i of document.getElementsByTagName("input")) i.placeholder = i.name
function calculateTimeToTxTxt(type) {
document.querySelector("input[name='text']").value = calculateTime(type)
}
function calculateTime(type) {
const now = new Date();
// Extract date components
const hh = String(now.getHours()).padStart(2, '0');
const mm = String(now.getMinutes()).padStart(2, '0');
const DD = String(now.getDate()).padStart(2, '0');
const MM = String(now.getMonth() + 1).padStart(2, '0'); // Months are 0-based
const YY = String(now.getFullYear()).slice(-2); // Get last two digits of the year
// Construct the formatted string
const formattedTime = `${hh}${mm}${DD}${MM}${YY}`;
switch (type) {
case 'tpl':
return `#ZEIT=${formattedTime}#ZEIT=${formattedTime}`;
case 'swissphone':
return `;TIME=${formattedTime};TIME=${formattedTime}`;
default:
return 'Invalid type';
}
}
function populateTimezones() {
const timezones = Intl.supportedValuesOf('timeZone');
const select = document.getElementById("time_zone");
timezones.forEach(zone => {
const option = document.createElement("option");
option.value = zone;
option.textContent = zone;
select.appendChild(option);
});
}
populateTimezones();

File diff suppressed because one or more lines are too long

455
data/style.src.css Normal file
View file

@ -0,0 +1,455 @@
:root {
--primary-color: #007bff; /* Blau für den Button */
--primary-hover: #0056b3; /* Dunkleres Blau bei Hover */
--border-radius: 6px;
--padding: 10px 15px;
--font-size: 16px;
--transition: all 0.3s ease-in-out;
}
body, html {
height: 100%;
margin: 0;
font-family: Arial;
}
.system-info {
padding: 20px;
font-family: Arial, sans-serif;
flex-grow: 1;
overflow-y: auto;
}
.system-info p {
margin: 8px 0;
}
.system-info h1 {
font-size: 24px;
margin-bottom: 10px;
}
.status-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
.status-table th, .status-table td {
padding: 10px;
border: 1px solid #ccc;
text-align: left;
vertical-align: top;
}
.status-table th {
background-color: #f4f4f4;
font-weight: bold;
}
#refresh-button {
background: none;
border: none;
cursor: pointer;
}
#refresh-button:hover {
color: #007BFF;
}
h2.external-links {
margin-top: 40px;
text-align: center;
font-size: 20px;
margin-bottom: 15px;
}
.link-buttons {
display: flex;
justify-content: center;
gap: 20px;
}
.link-buttons .button {
background-color: #04AA6D;
color: white;
padding: 15px 20px;
text-decoration: none;
border-radius: 5px;
font-size: 18px;
transition: background-color 0.3s ease;
}
.active, .cfgheader:hover {
background-color: #ccc;
}
.cfgpanel {
}
.cfgpanel:hover td, .cfgpanel:active td{
background-color: #808080 !important;
color: white;
}
th.cfg {
padding:5pt
}
table.stat {
margin:0px 0px 5px 0px;
}
.hamburger {
position: relative;
display: inline-block;
width: 1.25em;
height: 0.8em;
margin-right: 0.3em;
border-top: 0.2em solid #fff;
border-bottom: 0.2em solid #fff;
}
.hamburger:before {
content: "";
position: absolute;
top: 0.3em;
left: 0px;
width: 100%;
border-top: 0.2em solid #fff;
}
.wrapper {
height: 100%;
display: flex;
flex-direction: column;
margin: 0;
}
.tci {
flex-grow: 1; border: none; margin: 0; padding: 0; overflow-y: auto;
}
.footer {
background-color: #333;
display: flex;
justify-content: space-between;
}
td.ch {
text-align: right;
padding: 0px 8px;
}
td.act {
text-align: center;
}
table, th, td {
border: 1px solid black;
border-collapse: collapse;
background-color: #ddd
}
td#caption {
text-align: center;
background-color: #aaa;
font-weight: bold;
}
td#sfreq {
background-color: #ccc;
}
.content {
display: flex;
flex: 1;
flex-direction: column;
overflow: auto;
height: 100%;
}
.tabcontent {
display: none;
flex: 1;
border-top: none;
flex-direction: column;
overflow: auto;
}
html {
font-family: Helvetica;
display: inline-block;
margin: 0px auto;
text-align: left;
}
h1{
color: #0F3376;
font-size: 24px
}
.button2 {
background-color: #f44336;
}
:disabled.save {
opacity: 0.5;
}
.save {
background-color: #CC1111; /* 0F33C6; */
border: white;
border-width: 1;
color: white;
padding: 8px 30px;
text-align: center;
text-decoration: none;
display: block;
font-size: 14px;
margin: 0
}
.ttgoinfo {
color: white;
padding: 8px 10px;
display: block;
font-size: 14px;
margin: 0
}
.ctlbtn {
background-color: #ccc;
border: black;
border-width: 1;
color: black;
padding: 4px 30px;
text-align: center;
text-decoration: none;
display: block;
font-size: 4vh;
margin-top: 0.3em;
margin-left: 0.3em;
margin-right: 0.3em;
}
.update {
margin: 0;
display: block;
}
#map {
height: 100%;
}
.ldot {
height: 15px;
width: 15px;
margin-top: 8px;
margin-left: -1px;
border-radius: 50%;
display: inline-block;
}
.ybg {
background-color: orange;
background-image: -webkit-gradient(linear, left top, left bottom, from(yellow), to(orange));
background-image: linear-gradient(top, yellow, orange);
}
.gbg {
background-color: green;
background-image: -webkit-gradient(linear, left top, left bottom, from(lime), to(green));
background-image: linear-gradient(top, lime, green);
}
.rbg {
background-color: red;
background-image: -webkit-gradient(linear, left top, left bottom, from(orange), to(red));
background-image: linear-gradient(top, orange, red);
}
#sonde_statbar .ldot {
margin-right: 3px;
}
/* Add a black background color to the top navigation */
.topnav {
background-color: #333;
overflow: hidden;
}
/* Style the links inside the navigation bar */
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
/* Change the color of links on hover */
.topnav a:hover {
background-color: #ddd;
color: black;
}
/* Add an active class to highlight the current page */
.topnav a.active {
background-color: #04AA6D;
color: white;
}
/* Hide the link that should open and close the topnav on small screens */
.topnav .icon {
display: none;
padding-bottom: 12px;
padding-top: 11px;
}
/* When the screen is less than 600 pixels wide, hide all links, except for the first one ("Home"). Show the link that contains should open and close the topnav (.icon) */
@media screen and (max-width: 600px) {
.topnav a:not(.active) {display: none;}
.topnav a.icon {
float: right;
display: block;
}
}
/* The "responsive" class is added to the topnav with JavaScript when the user clicks on the icon. This class makes the topnav look good on small screens (display the links vertically instead of horizontally) */
@media screen and (max-width: 600px) {
.topnav.responsive {position: relative;}
.topnav.responsive a.icon {
position: absolute;
right: 0;
top: 0;
}
.topnav.responsive a {
float: none;
display: block;
text-align: left;
}
}
/* Buttons */
button, .btn {
background: var(--primary-color);
color: white;
padding: var(--padding);
border: none;
border-radius: var(--border-radius);
font-size: var(--font-size);
cursor: pointer;
transition: var(--transition);
box-shadow: 0 4px 8px rgba(0, 123, 255, 0.3); /* Schatten hinzufügen */
}
button:hover, .btn:hover {
background: var(--primary-hover);
box-shadow: 0 6px 12px rgba(0, 123, 255, 0.4); /* Stärkerer Schatten bei Hover */
}
button:focus {
outline: none;
box-shadow: 0 0 5px rgba(0, 123, 255, 0.7); /* Deutlicher Fokus-Effekt */
}
/* Zusätzliche Button-Stile für den Fokus */
button:active {
background: #0056b3;
transform: scale(0.98); /* Kleine Verkleinerung beim Klicken */
}
/* Button Group */
.button-group {
display: flex;
gap: 10px;
}
.button-group button {
flex: 1;
font-weight: bold; /* Button-Text fett für mehr Gewicht */
transition: transform 0.2s ease-in-out;
}
/* Hover und Fokus Effekte für Buttons in der Gruppe */
.button-group button:hover {
transform: scale(1.05); /* Leichtes Vergrößern bei Hover */
}
/* Input-Felder */
input, select, textarea {
width: 100%;
padding: var(--padding);
border: 1px solid #ccc;
border-radius: var(--border-radius);
font-size: var(--font-size);
transition: var(--transition);
}
input:focus, select:focus, textarea:focus {
border-color: var(--primary-color);
outline: none;
box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
}
/* Form-Labels */
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
/* Styling für Checkboxen und Radios */
input[type="checkbox"], input[type="radio"] {
width: auto;
margin-right: 5px;
}
/* Disabled-Zustand */
button:disabled, input:disabled {
background: #ccc;
cursor: not-allowed;
}
.styled-form {
max-width: 400px;
margin: auto;
display: flex;
flex-direction: column;
gap: 10px;
}
.no-top-margin {
margin-top: unset;
}
.button-group {
display: flex;
gap: 10px;
}
.button-group button {
flex: 1;
}
/* General styles for headers */
h1, h2, h3 {
font-family: 'Arial', sans-serif; /* A clean font for headers */
font-weight: bold;
margin: 10px 0;
color: #333; /* Dark gray text */
text-align: center; /* Center all headers */
}
/* Specific styles for h1 */
h1 {
font-size: 2.5rem; /* Large font for main title */
color: var(--primary-color); /* Primary color for h1 */
text-align: center; /* Center the main title */
text-transform: uppercase; /* Uppercase letters for emphasis */
letter-spacing: 2px; /* Add some spacing between letters */
margin-top: 20px;
margin-bottom: 20px;
}
/* Specific styles for h2 */
h2 {
font-size: 2rem; /* Slightly smaller than h1 */
color: #444; /* Slightly lighter gray */
/* text-align: left; Align to the left */
text-transform: capitalize; /* Capitalize first letter of each word */
margin-bottom: 15px;
}
/* Specific styles for h3 */
h3 {
font-size: 1.5rem; /* Smaller than h2 */
color: #666; /* Even lighter gray for less emphasis */
/* text-align: left; Align to the left */
margin-bottom: 10px;
font-weight: normal; /* Make it normal weight for less emphasis */
}