[Kachel-Skin] für f18

Begonnen von schwatter, 31 Juli 2026, 10:35:35

Vorheriges Thema - Nächstes Thema

schwatter

Du darfst diesen Dateianhang nicht ansehen.

Tag,

ich habe mir Gedanken über die Nutzung des Bildschirms gemacht. Für die Administration ist die aktuelle Standarddarstellung sehr sinnvoll.
Für die eigentliche Bedienung halte ich die aktuelle Aufteilung jedoch für eine weitgehende Platzverschwendung.

Der Style wird einfach in "Additional CSS" eingefügt.
Es gibt eine helle und dunkle Farbrichtung. Bei modernen Browsern würde es reichen,
:root, direkt über dem Farbstil zu platzieren. Da Fully das nicht unter Android9
händeln kann, habe ich den hellen Farbstil für mich auskommentiert.

Der Skin sortiert alles nach der Größe in den Gruppen und packt es in Kacheln. Möchte man ein Device mit in die
Sortierung packen, muss der subType identisch sein. Dazu in global subType hinzufügen.
attr global userattr subType
Für kleine  Bildschirme wie z.B Handy muss "Wrap columms on small screen" an sein.

Tip, durch
  im subType, kann dieser versteckt werden und es sieht noch cleaner aus.

/* ==========================================================================
  FARBSCHEMA & THEME SWITCH (DARK / LIGHT)
  ========================================================================== */

/* 1. STANDARDFARBEN (DARK MODE - DEFAULT) */
:root,
body.theme-dark {
    --accentColors: #d97300;    /* Akzentfarben */
   
    /* Hintergründe */
    --bg-main: #121214;          /* FHEM Gesamthintergrund */
    --bg-card: #1c1c1c;          /* Kacheln & Menüeinträge */
    --bg-card-hover: #252528;    /* Kachel Hover */
    --bg-card-active: #222224;  /* Aktiver Menüpunkt */
    --bg-sidebar: #141416;      /* Seitenmenü Hintergrund */
    --bg-button: #383838;        /* Buttons & Eingabefelder */
   
    /* Rahmenelemente */
    --border-card: #3d3d3d;      /* Kachel-Rand */
    --border-button: #555555;    /* Button-Rand */
   
    /* Textfarben */
    --myTitle: #ffffff;          /* Titel & Device-Namen */
    --myMenuText: #dddddd;      /* Standard Text */
    --text-muted: #888888;      /* Kategorie-Header */
   
    /* Popups / Dialoge */
    --bg-dialog: #1c1c1c;
    --btn-dialog-bg: #ffffff;
    --btn-dialog-text: #000000;
}

/* 2. LIGHT MODE */
/*body.theme-light {
    --accentColors: #459617;
   
    /* Hintergründe*/
    --bg-main: #e5e7eb;
    --bg-card: #f0f2f5;
    --bg-card-hover: #e2e5ea;
    --bg-card-active: #dbe4f0;
    --bg-sidebar: #dadde2;
    --bg-button: #d4d8de;
   
    /* Rahmenelemente */
    --border-card: #c4c8d0;
    --border-button: #a3a8b2;
   
    /* Textfarben */
    --myTitle: #000000;
    --myMenuText: #000000;
    --text-muted: #000000;
   
    /* Popups / Dialoge */
    --bg-dialog: #f0f2f5;
    --btn-dialog-bg: #d4d8de;
    --btn-dialog-text: #000000;
}*/

/* Globaler Seitenhintergrund basierend auf Variable */
body {
    background-color: var(--bg-main) !important;
    color: var(--myMenuText) !important;
}

/* ==========================================================================
  F18 TILE CARD LAYOUT (DYNAMIC THEME & RESPONSIVE)
  ========================================================================== */

/* 1. Container & Tabellen-Reset */
div#content {
    padding-left: 0 !important;
    padding-right: 0 !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
    box-sizing: border-box !important;
}

div#content div.makeTable,
div#content fieldset,
div#content table.block,
div#content table.block.wide,
div#content .block {
    background: transparent !important;
    background-color: transparent !important;
    border: none !important;
    box-shadow: none !important;
    padding: 0 !important;
    margin: 0 !important;
}

div#content table.room,
div#content table.block.wide {
    border-collapse: collapse !important;
    border-spacing: 0 !important;
    border: none !important;
    background: transparent !important;
    margin-left: 0 !important;
    padding-left: 0 !important;
    width: 100% !important;
}

/* 2. Flexbox Container */
div#content table.room > tbody,
div#content table.block.wide > tbody {
    display: flex !important;
    flex-wrap: wrap !important;
    gap: 10px !important;
    width: 100% !important;
    padding-left: 0 !important;
    margin-left: 0 !important;
    background: transparent !important;
    box-sizing: border-box !important;
}

/* ==========================================================================
  3. DEVICE KACHELN & HOVER (FÜR ALLE KACHELTYPEN)
  ========================================================================== */
div#content table.room > tbody > tr,
div#content table.block.wide > tbody > tr {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: wrap !important;
    align-items: center !important;
    justify-content: flex-start !important;
    gap: 8px !important;
   
    flex: 1 1 auto !important;
    width: auto !important;
    max-width: 100% !important;
    min-width: 0 !important;
   
    background-color: var(--bg-card) !important;
    border-radius: 12px !important;
    border: 1px solid var(--border-card) !important;
    padding: 8px 12px !important;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15) !important;
    box-sizing: border-box !important;
    min-height: 55px;
    overflow: hidden !important;
    transition: all 0.2s ease !important;
}

/* Hover- & Touch-Effekt für ALLE Geräte (PC + Mobil) */

/* 1. Kacheln */
div#content table.room > tbody > tr:not(.header):not(:has(.col_header)):not(:has(.pinHeader)):hover,
div#content table.block.wide > tbody > tr:not(.header):not(:has(.col_header)):not(:has(.pinHeader)):hover,
div#content table.room > tbody > tr:not(.header):not(:has(.col_header)):not(:has(.pinHeader)):active,
div#content table.block.wide > tbody > tr:not(.header):not(:has(.col_header)):not(:has(.pinHeader)):active {
    border-color: var(--accentColors) !important;
    background-color: var(--bg-card-hover) !important;
    transform: translateY(-2px) !important;
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.2) !important;
}

/* 2. Buttons, Dropdowns & Inputs */
div#content input[type="submit"]:hover,
div#content select:hover,
div#content input[type="text"]:focus,
div#content .set:hover,
div#content a.btn:hover,
div#content input[type="submit"]:active,
div#content select:active,
div#content .set:active,
div#content a.btn:active {
    border-color: var(--accentColors) !important;
    background-color: var(--bg-card-hover) !important;
    transform: translateY(-1px) !important;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2) !important;
}

/* Speziell für Submit-Buttons */
div#content input[type="submit"]:hover,
div#content input[type="submit"]:active {
    background-color: var(--accentColors) !important;
    color: #ffffff !important;
}

/* 4. Inhalte innerhalb der Kachel (TDs) */
div#content table.room tr > td {
    max-width: 100% !important;
    min-width: 0 !important;
    padding-left: 0 !important;
    margin-left: 0 !important;
    border: none !important;
    background: transparent !important;
    box-sizing: border-box !important;
}

div#content table.room tr > td:nth-child(1) {
    display: flex !important;
    align-items: center !important;
    gap: 8px !important;
    font-weight: 500 !important;
    color: var(--myTitle) !important;
    font-size: 14px !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    flex: 0 1 auto !important;
}

div#content table.room tr > td:nth-child(1) svg {
    width: 24px !important;
    height: 24px !important;
    min-width: 24px !important;
    padding-right: 0 !important;
    flex-shrink: 0 !important;
    fill: var(--myTitle) !important;
}

div#content table.room tr > td:nth-child(n+2) {
    display: flex !important;
    align-items: center !important;
    gap: 6px !important;
    flex-shrink: 0 !important;
    overflow: hidden !important;
    color: var(--myMenuText) !important;
}

@media screen and (min-width: 601px) {
    div#content table.room tr > td:nth-child(n+2) {
        margin-left: auto !important;
        padding-left: 10px !important;
    }
}

/* ==========================================================================
  BUTTONS, DROPDOWNS & INPUTS HOVER
  ========================================================================== */
div#content table.room input[type="submit"],
div#content table.room select,
div#content table.room input[type="text"],
div#content table.room .set,
div#content table.room a.btn,
div#content table.block.wide input[type="submit"],
div#content table.block.wide select,
div#content table.block.wide input[type="text"],
div#content table.block.wide .set,
div#content table.block.wide a.btn {
    background-color: var(--bg-button) !important;
    color: var(--myTitle) !important;
    border: 1px solid var(--border-button) !important;
    border-radius: 6px !important;
    padding: 3px 8px !important;
    font-size: 12px !important;
    cursor: pointer;
    max-width: 100% !important;
    box-sizing: border-box !important;
    text-overflow: ellipsis !important;
    overflow: hidden !important;
    white-space: nowrap !important;
    transition: all 0.2s ease !important;
}

/* Hover-Effekt für interaktive Elemente */
@media screen and (min-width: 601px) {
    div#content input[type="submit"]:hover,
    div#content select:hover,
    div#content input[type="text"]:focus,
    div#content .set:hover,
    div#content a.btn:hover {
        border-color: var(--accentColors) !important;
        background-color: var(--bg-card-hover) !important;
        transform: translateY(-1px) !important;
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2) !important;
    }

    /* Speziell für Submit-Buttons beim Drüberfahren */
    div#content input[type="submit"]:hover {
        background-color: var(--accentColors) !important;
        color: #ffffff !important;
    }
}

/* 5. Mobil-Optimierung */
@media screen and (max-width: 600px) {
    div#content table.room > tbody > tr,
    div#content table.block.wide > tbody > tr {
        width: 100% !important;
        flex: 1 1 100% !important;
        padding: 8px 10px !important;
    }

    div#content table.room tr > td:nth-child(n+2) {
        margin-left: 0 !important;
        padding-left: 0 !important;
    }
}

/* ==========================================================================
  6. PLOTS, PINHEADER & HEADER
  ========================================================================== */
div#content table.room tr.header,
div#content table.room tr:has(.col_header),
div#content table.room tr:has(.pinHeader) {
    width: 100% !important;
    flex: 1 1 100% !important;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    font-weight: bold;
    font-size: 18px;
    padding: 10px 0 0 0 !important;
    overflow: visible !important;
}

.pinHeader,
.col_header,
div.fileList.col_header {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    color: var(--myTitle) !important;
}

div#content table.room tr:has(svg.SVGplot),
div#content table.room tr:has(.echarts),
div#content table.room tr:has(iframe),
div#content table.room tr:has(embed) {
    width: 100% !important;
    flex: 1 1 100% !important;
    flex-direction: column !important;
    align-items: stretch !important;
    overflow: hidden !important;
}

.SVGplot, .echarts, iframe, embed {
    max-width: 100% !important;
    width: 100% !important;
    height: auto !important;
    box-sizing: border-box !important;
}

/* ==========================================================================
  SLIDER & COLORPICKER FIX
  ========================================================================== */
.colorpicker_bri .slider,
div#content table.room .colorpicker_bri .slider {
    background-image: linear-gradient(to right, rgb(0, 0, 0), rgb(255, 255, 255)) !important;
}

.colorpicker_ct .slider,
div#content table.room .colorpicker_ct .slider {
    background-image: linear-gradient(to right, rgb(255, 180, 107), rgb(255, 255, 255)) !important;
}

.colorpicker_hue .slider,
div#content table.room .colorpicker_hue .slider {
    background-image: linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00) !important;
}

.slider,
div#content table.room .slider {
    background-color: var(--accentColors) !important;
    border-radius: 5px !important;
    height: 6px !important;
    margin: 8px 10px !important;
    min-width: 120px !important;
    max-width: 200px !important;
    flex: 1 1 auto !important;
    position: relative !important;
    display: inline-block !important;
    vertical-align: middle !important;
}

.slider .handle,
.slider .ui-slider-handle,
div#content table.room .slider .handle {
    min-width: 40px !important;
    height: 22px !important;
    top: -8px !important;
    padding: 0 8px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    color: #000000 !important;
    font-weight: 600 !important;
    font-size: 12px !important;
    line-height: 1 !important;
    text-align: center !important;
    background-color: #ffffff !important;
    border: 1px solid var(--accentColors) !important;
    border-radius: 12px !important;
    box-shadow: 0 2px 5px rgba(0,0,0,0.3) !important;
    cursor: pointer !important;
    z-index: 10 !important;
    box-sizing: border-box !important;
    white-space: nowrap !important;
}

/* ==========================================================================
  POPUP / DIALOG SKINNING (.ui-dialog)
  ========================================================================== */
.ui-dialog {
    background-color: var(--bg-dialog) !important;
    border: 1px solid var(--border-card) !important;
    border-radius: 16px !important;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4) !important;
    padding: 15px !important;
    color: var(--myTitle) !important;
    box-sizing: border-box !important;
    min-width: 300px !important;
    min-height: 180px !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: visible !important;
    position: absolute !important;
}

.ui-dialog .ui-dialog-titlebar {
    background: transparent !important;
    border: none !important;
    padding: 0 !important;
    min-height: 0 !important;
    height: 0 !important;
    margin: 0 !important;
}

.ui-dialog .ui-dialog-title {
    display: none !important;
}

.ui-dialog .ui-dialog-titlebar-close {
    position: absolute !important;
    top: 10px !important;
    right: 10px !important;
    background: var(--bg-button) !important;
    border: 1px solid var(--border-button) !important;
    border-radius: 50% !important;
    width: 26px !important;
    height: 26px !important;
    cursor: pointer !important;
    z-index: 20 !important;
    margin: 0 !important;
    padding: 0 !important;
}

.ui-dialog .ui-dialog-titlebar-close:hover {
    background-color: var(--accentColors) !important;
    border-color: var(--accentColors) !important;
}

.ui-dialog .ui-dialog-content {
    background: transparent !important;
    color: var(--myTitle) !important;
    padding: 10px 5px !important;
    text-align: center !important;
    flex: 1 1 auto !important;
    box-sizing: border-box !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    height: 100% !important;
    width: 100% !important;
    max-height: none !important;
}

.ui-dialog .ui-dialog-content p {
    margin: 6px 0 !important;
}

.ui-dialog .ui-dialog-buttonpane {
    background: transparent !important;
    border: none !important;
    margin: 10px 0 0 0 !important;
    padding: 0 !important;
    text-align: center !important;
   
    flex: 0 0 auto !important;
    width: 100% !important;
    box-sizing: border-box !important;
}

.ui-dialog .ui-dialog-buttonset {
    float: none !important;
    display: flex !important;
    justify-content: center !important;
    gap: 10px !important;
    flex-wrap: wrap !important;
}

.ui-dialog .ui-dialog-buttonpane button,
.ui-dialog .ui-button {
    background-color: var(--btn-dialog-bg) !important;
    border: 1px solid var(--border-button) !important;
    border-radius: 20px !important;
    color: var(--btn-dialog-text) !important;
    font-weight: 700 !important;
    font-size: 13px !important;
    padding: 6px 20px !important;
    min-width: 70px !important;
    cursor: pointer !important;
    box-shadow: 0 2px 6px rgba(0,0,0,0.2) !important;
    transition: all 0.2s ease !important;
}

.ui-dialog .ui-dialog-buttonpane button .ui-button-text,
.ui-dialog .ui-button .ui-button-text {
    color: var(--btn-dialog-text) !important;
    font-weight: 700 !important;
}

.ui-dialog .ui-dialog-buttonpane button:hover {
    background-color: var(--accentColors) !important;
    border-color: var(--accentColors) !important;
    color: #ffffff !important;
    transform: translateY(-1px);
}

.ui-dialog input[type="text"],
.ui-dialog select,
.ui-dialog .select_widget {
    background-color: var(--bg-button) !important;
    color: var(--myTitle) !important;
    border: 1px solid var(--border-button) !important;
    border-radius: 20px !important;
    padding: 5px 12px !important;
    font-size: 13px !important;
    outline: none !important;
    text-align: center !important;
}

.ui-dialog select option {
    background-color: var(--bg-card) !important;
    color: var(--myTitle) !important;
}

.ui-dialog .ui-resizable-handle {
    z-index: 30 !important;
}

/* ==========================================================================
  SIDEBAR / SEITENMENÜ
  ========================================================================== */

div#menu {
    background: var(--bg-sidebar) !important;
    border-right: 1px solid var(--border-card) !important;
    padding: 12px 8px !important;
    box-sizing: border-box !important;
    max-height: 100vh !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
}

div#menu::-webkit-scrollbar {
    width: 5px !important;
}
div#menu::-webkit-scrollbar-track {
    background: transparent !important;
}
div#menu::-webkit-scrollbar-thumb {
    background: var(--border-card) !important;
    border-radius: 4px !important;
}
div#menu::-webkit-scrollbar-thumb:hover {
    background: var(--accentColors) !important;
}
div#menu {
    scrollbar-width: thin !important;
    scrollbar-color: var(--border-card) transparent !important;
}

div#menu table,
div#menu table td,
div#menu tbody,
div#menu tr {
    background: transparent !important;
    border: none !important;
    padding: 0 !important;
    margin: 0 !important;
    width: 100% !important;
    display: block !important;
}

div#menu a,
div#menu table td a {
    display: flex !important;
    align-items: center !important;
    padding: 10px 14px !important;
    margin-top: 0 !important;
    margin-bottom: 6px !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
   
    background-color: var(--bg-card) !important;
    border: 1px solid var(--border-card) !important;
    border-radius: 12px !important;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1) !important;
   
    color: var(--myTitle) !important;
    font-size: 14px !important;
    font-weight: 500 !important;
    line-height: 1.2 !important;
    text-decoration: none !important;
   
    transition: all 0.2s ease !important;
    box-sizing: border-box !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
}

@media screen and (min-width: 601px) {
    div#menu a:hover,
    div#menu table td a:hover {
        border-color: var(--accentColors) !important;
        background-color: var(--bg-card-hover) !important;
        transform: translateY(-2px) !important;
        box-shadow: 0 6px 14px rgba(0, 0, 0, 0.15) !important;
    }
}

div#menu a.sel,
div#menu table td.sel a,
div#menu td.sel a {
    background-color: var(--bg-card-active) !important;
    border: 1px solid var(--accentColors) !important;
    color: var(--myTitle) !important;
    font-weight: 600 !important;
    box-shadow: 0 4px 15px rgba(255, 140, 0, 0.2) !important;
}

div#menu a.sel::before,
div#menu table td.sel a::before {
    content: "" !important;
    display: inline-block !important;
    width: 8px !important;
    height: 8px !important;
    background-color: var(--accentColors) !important;
    border-radius: 50% !important;
    margin-right: 10px !important;
    box-shadow: 0 0 8px var(--accentColors) !important;
    flex-shrink: 0 !important;
}

/* Kategorie-Überschriften */
div#menu .menuHeader,
div#menu td.header,
div#menu tr.header td {
    color: var(--text-muted) !important;
    font-size: 11px !important;
    font-weight: 700 !important;
    text-transform: uppercase !important;
    letter-spacing: 1px !important;
    padding: 14px 6px 4px 6px !important;
    background: transparent !important;
}

/* Suche / Commandline */
div#menu input[type="text"] {
    background-color: var(--bg-card) !important;
    border: 1px solid var(--border-card) !important;
    border-radius: 12px !important;
    color: var(--myTitle) !important;
    padding: 10px 14px !important;
    font-size: 13px !important;
    width: 100% !important;
    box-sizing: border-box !important;
    margin-bottom: 10px !important;
    outline: none !important;
    transition: all 0.2s ease !important;
}

div#menu input[type="text"]:focus {
    border-color: var(--accentColors) !important;
    box-shadow: 0 0 10px rgba(255, 140, 0, 0.2) !important;
}

/* Mobil-Abstände */
@media screen and (max-width: 600px) {
    div#menu {
        padding: 6px 4px !important;
    }

    div#menu table,
    div#menu tbody,
    div#menu tr,
    div#menu td,
    div#menu div {
        margin: 0 !important;
        padding: 0 !important;
        border: 0 !important;
        height: auto !important;
        min-height: 0 !important;
        line-height: 1 !important;
        display: block !important;
    }

    div#menu br,
    div#menu table tr:empty,
    div#menu table td:empty {
        display: none !important;
    }

    div#menu a,
    div#menu table td a {
        display: flex !important;
        align-items: center !important;
        padding: 8px 10px !important;
        margin-top: 0 !important;
        margin-bottom: 4px !important;
        margin-left: 0 !important;
        margin-right: 0 !important;
        height: auto !important;
        box-sizing: border-box !important;
    }

    div#menu .menuHeader,
    div#menu td.header,
    div#menu tr.header td {
        padding: 8px 4px 2px 4px !important;
        margin: 0 !important;
    }
}

Darauf aufbauend habe ich mein MiniChartWidget um den Modus "forcemobile" erweitert. Diese Änderung muss ich allerdings noch einchecken.

Gruß schwatter