Die Heizung stand ueber den Tabs und war in jedem Raum sichtbar, auch wenn man wegen der Rollladen gekommen war. Sie ist jetzt eine Gruppe wie die anderen - nur baut sie sich nicht aus einer Geraeteliste, sondern ist ein Regler fuer den Raum. zeichneGruppen() nimmt dafuer fertige Inhalte entgegen. Bei einem Raum mit nur einem Thermostat bleibt die Leiste weg, dort sieht es aus wie vorher. Aus den Pillen sind Reiter geworden - sie sehen jetzt aus wie das, was sie sind, und nicht wie eine Knopfreihe. Position und Neigung standen um 0,35 rem versetzt: die Regel fuer gestapelte Regler (Helligkeit ueber Farbe) griff auch auf die zweite Spalte, die aber danebensteht. Sie gilt jetzt nur noch fuer Regler, die keine Spalte sind - nachgemessen stehen beide Bahnen auf 181/104. Das Fensterbild ist von "so breit wie moeglich" auf 5 rem zurueckgenommen; der uebrige Platz verteilt sich auf die Zwischenraeume, statt das Bild breitzuziehen. Zwischen ihm und den Bedienelementen liegt jetzt Luft. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
377 lines
11 KiB
CSS
377 lines
11 KiB
CSS
.winddir {
|
|
position:absolute;
|
|
left:60%;
|
|
width:25%;
|
|
height:40%;
|
|
padding: 0;
|
|
background-image: url('../assets/img/arrow.svg');
|
|
background-size:contain;
|
|
background-repeat: no-repeat;
|
|
background-position: center;
|
|
}
|
|
|
|
|
|
/* Schieberegler in den Modals (Autoladung, Heizstab, Thermostat).
|
|
Der gefuellte Anteil kommt aus --background-size, gesetzt von
|
|
bindModalSlider() in js/solar/common.js. */
|
|
input[type='range']::-webkit-slider-runnable-track {
|
|
background: linear-gradient(to right, #00788F, #00788F), #D7D7D7;
|
|
background-size: var(--background-size, 0%) 100%;
|
|
background-repeat: no-repeat;
|
|
}
|
|
|
|
/* Diagramme (Chart.js). Die Hoehe kommt aus diesem Container, nicht aus dem
|
|
canvas - die Charts laufen mit maintainAspectRatio: false. Auf dem Handy
|
|
ist der Container nur rund 300 px breit; mit 400 px Hoehe wird aus einer
|
|
Zeitreihe ein Hochformat, in dem die Zeitachse die kurze Seite ist. */
|
|
.chart-container {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 400px;
|
|
}
|
|
|
|
@media (max-width: 767.98px) {
|
|
.chart-container {
|
|
height: 250px;
|
|
}
|
|
}
|
|
|
|
/* Statistik-Kacheln (ajax/getStats.php). Sie lagen in nackten .col ohne
|
|
Breitenangabe - Bootstrap laesst sie dann nach Textlaenge umbrechen, mal
|
|
zwei, mal drei je Zeile und unterschiedlich breit. Die Breite kommt jetzt
|
|
aus row-cols-* in getStats.php; hier sorgt die volle Kartenhoehe dafuer,
|
|
dass die Werte trotz ein- oder zweizeiliger Titel auf einer Linie
|
|
stehen. */
|
|
.card.stats {
|
|
height: 100%;
|
|
}
|
|
|
|
.card.stats .card-body {
|
|
flex: 1 1 auto;
|
|
}
|
|
|
|
/* Auf dem Handy gehen von 375 px rund 75 an Innenabstaende verloren, und
|
|
zwischen den Karten stehen 24 px. Beides wird hier enger gefasst - nur
|
|
im Inhaltsbereich, damit Seitenleiste, Kopfzeile und Modals unberuehrt
|
|
bleiben. Die Abstandsklassen von Bootstrap (mb-4) tragen !important,
|
|
deshalb steht es auch hier. */
|
|
@media (max-width: 767.98px) {
|
|
.app-content {
|
|
padding: 0 .25rem;
|
|
}
|
|
|
|
.app-content-header {
|
|
padding: .5rem .25rem;
|
|
}
|
|
|
|
.app-content .row {
|
|
--bs-gutter-x: .5rem;
|
|
}
|
|
|
|
.app-content .card {
|
|
margin-bottom: .75rem !important;
|
|
}
|
|
|
|
/* Nur der Standardwert wird kleiner; eigene Angaben im Markup (p-0 fuer
|
|
das Realtime-SVG, p-2 fuer die Statistik) gelten weiter. */
|
|
.app-content .card-body {
|
|
padding: .5rem;
|
|
}
|
|
|
|
/* Eine Kachel ist auf dem Handy rund 150 px breit. In voller Schrift
|
|
passt "Verbrauchsersparnis" dort nicht in eine Zeile und wird mitten
|
|
im Wort umbrochen. */
|
|
.card.stats .card-body {
|
|
font-size: .8rem;
|
|
}
|
|
}
|
|
|
|
/* Editor der Automatiken. Eine Bedingungszeile traegt Geraet, Messwert,
|
|
Vergleich, Wert, Einheit und den Papierkorb nebeneinander - auf einem
|
|
Handy bleiben davon "Therm OG Bad" und "te" uebrig, weil die Felder in
|
|
der input-group einfach mitschrumpfen. Unter 576 px bekommen deshalb
|
|
Geraet und Messwert je eine eigene Zeile; Vergleich, Wert und Einheit
|
|
sind kurz genug, um zusammen in die naechste zu passen. */
|
|
@media (max-width: 575.98px) {
|
|
/* Die input-group-Klasse muss mit in den Selektor: solar.css wird vor
|
|
AdminLTE geladen, und Bootstraps ".input-group > .form-select" haette
|
|
sonst dasselbe Gewicht und wuerde als spaeteres Blatt gewinnen. */
|
|
.input-group.auto-zeile > .auto-geraet,
|
|
.input-group.auto-zeile > .auto-messwert {
|
|
flex: 1 1 100%;
|
|
width: auto;
|
|
}
|
|
}
|
|
|
|
/* Raum-Modal. Ein Kommando mit mehreren Parametern ("Position+Neigung")
|
|
traegt Beschriftung, zwei Zahlenfelder und den Ausloeseknopf in einer
|
|
input-group - auf einem Handy schrumpfen die Felder dabei auf Nullbreite.
|
|
Eine Mindestbreite laesst die Zeile stattdessen umbrechen. */
|
|
.input-group.raum-cmd > .form-control,
|
|
.input-group.raum-cmd > .form-select {
|
|
min-width: 5rem;
|
|
}
|
|
|
|
|
|
/* --------------------------------------------------------------------------
|
|
Raum-Modal: Bedienelemente
|
|
Erzeugt von restricted/roomControls.php, verdrahtet in js/solar/homeMQTT.js.
|
|
-------------------------------------------------------------------------- */
|
|
|
|
/* Die Geraetegruppen als Reiter. Auf einem Handy passen fuenf
|
|
Beschriftungen nicht nebeneinander - dann scrollt die Leiste seitwaerts,
|
|
statt die Namen umzubrechen. Die durchgehende Linie unter den Reitern
|
|
darf dabei nicht mitscrollen, sie gehoert an den unteren Rand. */
|
|
.raum-tabs {
|
|
overflow-x: auto;
|
|
overflow-y: hidden;
|
|
scrollbar-width: none;
|
|
flex-wrap: nowrap;
|
|
}
|
|
.raum-tabs::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
.raum-tabs .nav-link {
|
|
padding: 0.3rem 0.7rem;
|
|
font-size: 0.8rem;
|
|
white-space: nowrap;
|
|
border-bottom-color: transparent;
|
|
}
|
|
|
|
/* Waehrend ein Kommando unterwegs ist. Ein "Zu" an einer Jalousie dauert
|
|
ueber eine Minute; ohne sichtbare Sperre tippt man in der Zeit nach. */
|
|
.raum-geraet.raum-warte {
|
|
opacity: 0.55;
|
|
pointer-events: none;
|
|
}
|
|
.raum-geraet.raum-warte::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: 0.5rem;
|
|
right: 0.5rem;
|
|
width: 0.9rem;
|
|
height: 0.9rem;
|
|
border: 2px solid currentColor;
|
|
border-right-color: transparent;
|
|
border-radius: 50%;
|
|
animation: raum-dreht 0.8s linear infinite;
|
|
}
|
|
.raum-geraet {
|
|
position: relative;
|
|
}
|
|
@keyframes raum-dreht {
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* --------------------------------------------------------------------------
|
|
Regler im Raum-Modal
|
|
|
|
Eigenes Aussehen statt des Bootstrap-Standards: dessen weisse Bahn mit dem
|
|
blauen Griff sticht auf den dunklen Karten heraus, und in einem Raum mit
|
|
drei Jalousien sind das sechs helle Balken. Bahn und Griff tragen deshalb
|
|
dasselbe Blaugruen wie der Temperaturregler, und der ungefuellte Teil ist
|
|
ein Grau, das in beiden Themes traegt.
|
|
|
|
Bewusst nur innerhalb von #roomView: die Regler in den Modals fuer
|
|
Autoladung und Heizstab bleiben, wie sie sind.
|
|
-------------------------------------------------------------------------- */
|
|
#roomView input[type='range'] {
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
width: 100%;
|
|
height: 1.5rem;
|
|
padding: 0;
|
|
margin: 0;
|
|
background: transparent;
|
|
}
|
|
#roomView input[type='range']:focus {
|
|
outline: 0;
|
|
}
|
|
/* Getrennt notiert, nicht als Liste: einen Selektor, den er nicht kennt,
|
|
wirft der Browser samt der ganzen Regel weg - und dann bliebe die Bahn
|
|
ungestaltet. */
|
|
#roomView input[type='range']::-webkit-slider-runnable-track {
|
|
height: 0.375rem;
|
|
border: 0;
|
|
border-radius: 0.375rem;
|
|
background: linear-gradient(to right, #00788F, #00788F), rgba(128, 128, 128, 0.32);
|
|
background-size: var(--background-size, 0%) 100%;
|
|
background-repeat: no-repeat;
|
|
}
|
|
#roomView input[type='range']::-moz-range-track {
|
|
height: 0.375rem;
|
|
border: 0;
|
|
border-radius: 0.375rem;
|
|
background: linear-gradient(to right, #00788F, #00788F), rgba(128, 128, 128, 0.32);
|
|
background-size: var(--background-size, 0%) 100%;
|
|
background-repeat: no-repeat;
|
|
}
|
|
#roomView input[type='range']::-webkit-slider-thumb {
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
width: 1.05rem;
|
|
height: 1.05rem;
|
|
/* (Bahnhoehe - Griffhoehe) / 2, damit der Griff auf der Bahn sitzt. */
|
|
margin-top: -0.34rem;
|
|
border: 2px solid #fff;
|
|
border-radius: 50%;
|
|
background: #00788F;
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
|
|
}
|
|
#roomView input[type='range']::-moz-range-thumb {
|
|
width: 1.05rem;
|
|
height: 1.05rem;
|
|
border: 2px solid #fff;
|
|
border-radius: 50%;
|
|
background: #00788F;
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
|
|
}
|
|
|
|
/* Schieberegler stehen dicht untereinander (Helligkeit, Farbe). Ohne den
|
|
Abstand kleben Beschriftung und Bahn aneinander.
|
|
Die senkrechten Spalten stehen dagegen nebeneinander - dort wuerde der
|
|
Abstand die zweite Spalte um genau diese 0,35 rem tiefer setzen. */
|
|
.raum-regler + .raum-regler:not(.raum-spalte) {
|
|
margin-top: 0.35rem;
|
|
}
|
|
|
|
/* Messwerte als Gitter statt als Textwurst: ein Stromzaehler hat sechzehn
|
|
Werte, die in einer Zeile niemand findet. auto-fill statt fester Spalten,
|
|
damit auf dem Handy zwei und auf dem Schirm vier nebeneinander passen. */
|
|
.raum-werte {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
|
|
gap: 0.4rem;
|
|
}
|
|
.raum-wert {
|
|
background: rgba(128, 128, 128, 0.08);
|
|
border-radius: 0.35rem;
|
|
padding: 0.3rem 0.45rem;
|
|
overflow: hidden;
|
|
}
|
|
.raum-wert-zahl {
|
|
font-size: 0.95rem;
|
|
font-weight: 600;
|
|
line-height: 1.2;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
.raum-wert-einheit {
|
|
font-size: 0.7rem;
|
|
font-weight: 400;
|
|
opacity: 0.6;
|
|
}
|
|
.raum-wert-name {
|
|
font-size: 0.68rem;
|
|
opacity: 0.6;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
|
|
/* --------------------------------------------------------------------------
|
|
Raum-Modal: Jalousien
|
|
-------------------------------------------------------------------------- */
|
|
|
|
/* Fahrknoepfe, Hoehe und Neigung nebeneinander. Die Neigung nimmt den Rest -
|
|
sie ist die einzige der drei Spalten, die von Breite profitiert. */
|
|
.raum-jalousie {
|
|
display: flex;
|
|
align-items: stretch;
|
|
justify-content: space-between;
|
|
gap: 0.4rem;
|
|
}
|
|
/* Das Fensterbild steht zwischen Knoepfen und Reglern - schmal, mit Luft
|
|
zu beiden Seiten. Der uebrige Platz verteilt sich auf die Zwischenraeume
|
|
(space-between an .raum-jalousie), statt das Bild breitzuziehen. */
|
|
.raum-jalousie .raum-lamellen {
|
|
flex: 0 1 5rem;
|
|
min-width: 2.2rem;
|
|
margin: 0 0.4rem;
|
|
}
|
|
.raum-jalousie .dropdown {
|
|
align-self: flex-start;
|
|
}
|
|
|
|
/* Auf, Stop, Zu untereinander - die Knoepfe zeigen in die Richtung, in die
|
|
sie fahren. Schmal, weil nur Symbole darin stehen. */
|
|
.raum-fahrt {
|
|
flex: 0 0 auto;
|
|
}
|
|
.raum-fahrt .btn {
|
|
padding: 0.2rem 0.55rem;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
/* Eine Spalte mit senkrechtem Regler: Name, oberes Wort, Bahn, unteres
|
|
Wort, Zahl. Breit genug fuer "Position" in der kleinen Schrift. */
|
|
.raum-spalte {
|
|
flex: 0 0 3.4rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
text-align: center;
|
|
}
|
|
.raum-name {
|
|
font-size: 0.62rem;
|
|
opacity: 0.8;
|
|
white-space: nowrap;
|
|
line-height: 1.2;
|
|
}
|
|
|
|
/* Der Kasten, in dem ein gewoehnlicher Regler auf der Seite liegt.
|
|
Gedreht statt writing-mode: so gebaute Regler lassen sich am Handy kaum
|
|
anfassen - das Ziehen wird als Wischen gelesen und blaettert die Seite.
|
|
Gedreht bewegt sich der Regler in seinen eigenen Koordinaten waagerecht,
|
|
und touch-action haelt die Seite still, solange der Finger auf ihm liegt.
|
|
rotate(90deg) legt den kleinen Wert nach oben: "oben" ist 0 %. */
|
|
.raum-senkrecht {
|
|
position: relative;
|
|
width: 1.6rem;
|
|
height: 6.5rem;
|
|
margin: 0.1rem 0;
|
|
}
|
|
#roomView .raum-senkrecht input[type='range'] {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
width: 6.5rem; /* = Hoehe des Kastens, die Laenge der Bahn */
|
|
height: 1.6rem; /* = Breite des Kastens, die Flaeche zum Treffen */
|
|
transform: translate(-50%, -50%) rotate(90deg);
|
|
touch-action: none;
|
|
}
|
|
|
|
/* Die Endstellungen in Worten statt in Prozent. */
|
|
.raum-ende {
|
|
font-size: 0.68rem;
|
|
opacity: 0.65;
|
|
line-height: 1.1;
|
|
}
|
|
|
|
/* Die Lamellen zur Neigung. Ihre Hoehe setzt lamellenZeichnen() in
|
|
js/solar/homeMQTT.js - schmal mit Luft dazwischen heisst offen,
|
|
aneinanderliegend heisst geschlossen. */
|
|
.raum-lamellen {
|
|
display: block;
|
|
align-self: center;
|
|
height: 6.9rem;
|
|
/* Der Rahmen macht aus dem Streifen ein Fenster - ohne ihn liest sich das
|
|
geschlossene Bild wie eine zweite Reglerbahn. */
|
|
background: rgba(0, 120, 143, 0.14);
|
|
border: 1px solid rgba(128, 128, 128, 0.35);
|
|
border-radius: 0.2rem;
|
|
}
|
|
.raum-lamelle {
|
|
fill: currentColor;
|
|
opacity: 0.6;
|
|
stroke: rgba(0, 0, 0, 0.35);
|
|
stroke-width: 0.6;
|
|
vector-effect: non-scaling-stroke;
|
|
}
|
|
.raum-endschiene {
|
|
fill: currentColor;
|
|
opacity: 0.85;
|
|
}
|