.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 Tabs. Auf einem Handy passen fuenf Beschriftungen nicht nebeneinander - dann scrollt die Leiste seitwaerts, statt die Namen umzubrechen. */ .raum-tabs { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; } .raum-tabs::-webkit-scrollbar { display: none; } .raum-tabs .nav-link { padding: 0.25rem 0.6rem; font-size: 0.8rem; white-space: nowrap; } /* 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. */ .raum-regler + .raum-regler { 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; gap: 0.6rem; } /* Das Fensterbild nimmt den Platz zwischen Knoepfen und Reglern. */ .raum-jalousie .raum-lamellen { flex: 1 1 auto; min-width: 2.5rem; } .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; }