* { box-sizing: border-box; } html { width: 100%; height: 100%; } body { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; color: var(--default-fg-color); background-color: var(--body-bg-color); font-family: var(--font-family); } hr { border: 0; border-top: 1px solid var(--hr-color); margin: 16px 0; } /* -- start common layout */ .section-title { color: var(--section-title-fg-color); font-size: var(--font-base-size); font-variant: small-caps; padding: 20px 0 10px 0; } hr + .section-title, .section-title:first-child { padding-top: 0px; } .section .t { color: var(--title-fg-color); font-size: var(--font-base-size); } .section .s { color: var(--subtitle-fg-color); font-size: calc(var(--font-base-size) - 4px); padding-bottom: 4px; } .section .ts { font-size: calc(var(--font-base-size) - 4px); } .section a { font: inherit; color: inherit; text-decoration: none; font-variant: proportional-nums; } .section a:hover { color: var(--section-link-fg-color); } .section-subtitle { color: var(--section-subtitle-fg-color); font-size: calc(var(--font-base-size) - 4px); } .heading { color: var(--section-title-fg-color); font-size: calc(var(--font-base-size) - 2px); padding-bottom: 6px; } .cols { display: flex; flex-wrap: wrap; } .cols > div { flex: 1 } .ctrl { padding: 5px; border-radius: 10px; border: 1px solid transparent; } .ctrl:last-child, .noctrl:last-child { flex: 1; } .noctrl { padding: 5px; border: 1px solid transparent; } body.authenticated .ctrl:hover { padding: 10px; margin: -5px; background-color: var(--ctrl-bg-color-hover); } /* -- end common layout */ /* -- start overall layout -- */ #all { display: flex; min-width: 100%; height: 100%; flex-direction: column; background-color: var(--body-bg-color); } #nav { position: absolute; display: flex; width: 100%; min-height: 64px; max-height: 64px; background-color: var(--nav-bg-color); } #panel { display: flex; flex: 1; height: 100%; padding-top: 64px; background-color: var(--nav-bg-color); } #select { display: flex; min-width: 64px; flex-direction: column; background-color: var(--nav-bg-color); } #main { flex: 1; height: 100%; padding: 10px; background-color: var(--body-bg-color); overflow-y: scroll; overscroll-behavior: contain; border-top-left-radius: 20px; } #main-container { display: flex; flex: 1; } #c1 { display: flex; flex-direction: column; min-width: 330px; width: 330px; } #general { display: flex; flex-direction: column; padding: 10px 5px; } #location { } #c2 { display: flex; flex-direction: column; flex: 5; padding: 20px 15px 0 15px; min-width: 420px; } #services { display: flex; flex-direction: column; } #local-and-neighbor-devices { container-type: inline-size; } #c3 { display: flex; flex-direction: column; flex: 4; padding: 20px 0 0 5px; container-type: inline-size; } #radio-and-antenna { display: flex; flex-direction: column; } #mesh-summary { } #tunnels { display: flex; flex-direction: column; } #dhcp { display: flex; flex-direction: column; } @container (width < 400px) { #dhcp .t { font-size: 12px; } #dhcp .ts { font-size: 10px; } } /* -- end overall layout -- */ /* -- start nav layout -- */ .nav-node-name { color: var(--title-fg-color); font-size: 24px; font-weight: bold; margin: auto 0 auto 20px; } #nav-status { color: var(--subtitle-fg-color); font-size: calc(var(--font-base-size) - 4px); padding: 8px 0 0 8px; margin: auto 0; } /* -- end nav layout -- */ /* -- start general layout -- */ #general .radio-image { display: flex; align-items: center; justify-content: center; height: 150px; margin-bottom: 20px; } #general .t { font-size: var(--font-base-size); color: var(--title-fg-color); } #general .s { color: var(--subtitle-fg-color); font-size: calc(var(--font-base-size) - 4px); padding-bottom: 6px; } #general .ts { font-size: calc(var(--font-base-size) - 4px); } .node-description { padding-bottom: 4px; } .node-description .t { font-size: var(--font-base-size); } #general .firmware { font-size: calc(var(--font-base-size) - 4px); } #general .firmware .s { padding-top: 2px; } #general .firmware .s a { color: inherit; text-decoration: none; } #general .firmware .s a:hover { text-decoration: underline; } #general .firmware-status { position: relative; top: -2px; display: inline-block; margin-left: 4px; font-size: calc(var(--font-base-size) - 6px); padding: 2px 5px; border-radius: 5px; color: var(--firmware-status-fg-color); } #general .firmware-status.uptodate { background-color: var(--firmware-status-bg-color-positive); } #general .firmware-status.uptodate::after { content: "Up to date"; } #general .firmware-status.needupdate { background-color: var(--firmware-status-bg-color-negative); } #general .firmware-status.needupdate::after { content: "Update available"; } #general .firmware-status.custom { background-color: var(--firmware-status-bg-color-other); } #general .firmware-status.custom::after { content: "Custom"; } #health { padding: 20px 0; font-size: calc(var(--font-base-size) - 2px); } /* -- end general layout -- */ /* -- start location layout -- */ #location .t { color: var(--title-fg-color); font-size: var(--font-base-size); } #location .s { color: var(--subtitle-fg-color); font-size: calc(var(--font-base-size) - 4px); } #location .location-image { pointer-events: none; width: 300px; height: 150px; margin: 0 0 15px 10px; } #location .location-image iframe { border: 1px solid var(--hr-color); filter: var(--map-filter); } /* -- end location layout -- */ /* -- start local and neighborhood devices layout -- */ @container (width < 450px) { #local-and-neighbor-devices .section { font-size: 12px; } #local-and-neighbor-devices .ts { font-size: 10px; } } #local-and-neighbor-devices .stats { text-align: right; min-width: 260px; } #local-and-neighbor-devices .status { padding: 2.5px 5px; margin: -5px -5px; } body.authenticated #local-and-neighbor-devices .status.ctrl:hover { padding: 7.5px 10px; margin: -10px -10px; } #local-and-neighbor-devices .excellent { color: var(--conn-fg-color-excellent); } #local-and-neighbor-devices .good { color: var(--conn-fg-color-good); } #local-and-neighbor-devices .okay { color: var(--conn-fg-color-okay); } #local-and-neighbor-devices .poor { color: var(--conn-fg-color-poor); } #local-and-neighbor-devices .bad { color: var(--conn-fg-color-bad); } #local-and-neighbor-devices .blocked { color: var(--conn-fg-color-idle); text-decoration: line-through; } #local-and-neighbor-devices .idle { color: var(--conn-fg-color-idle); } #local-and-neighbor-devices .icon { display: inline-block; width: 12px; height: 12px; margin-left: 4px; background-position: center center; background-repeat: no-repeat; filter: var(--icon-filter); } /* -- end local and neighborhood devices layout -- */ /* -- start services layout -- */ #services .service, #services .device { font-size: calc(var(--font-base-size) - 3px); padding: 2px 0; flex-basis: 50%; } #services .service .status { display: inline-block; width: calc(var(--font-base-size) * 3 + 4px); padding: 2px 0; border-radius: 5px; margin-right: 5px; text-align: center; font-size: calc(var(--font-base-size) - 6px); color: var(--service-fg-color-status); background-color: var(--service-bg-color-status-inactive); } #services .service .icon { position: relative; display: inline-block; top: 3px; width: 14px; height: 14px; filter: var(--icon-filter); } #services .service .status.inactive { background-color: var(--service-bg-color-status-inactive); } #services .service .status.active { background-color: var(--service-bg-color-status-active); } #services .service .status.disabled { background-color: var(--service-bg-color-status-disabled); } #services .service .status.inactive::after { content: "inactive"; } #services .service .status.active::after { content: "active"; } #services .service .status.disabled::after { content: "disabled"; } /* -- end services layout -- */ /* -- start icon layout -- */ #nav a { position: relative; text-decoration: none; } #icon-logo { display: table-cell; width: 64px; height: 64px; background: url("data:image/svg+xml,") center center no-repeat; text-align: center; vertical-align: bottom; } #icon-logo + div { position: absolute; display: inline-block; bottom: 0; left: 8px; font-family: inherit; font-size: 13px; font-weight: bold; color: var(--logo-fg-color); background-color: var(--nav-bg-color); } #icon-logo.animate { animation-name: logo-rotate; animation-duration: 1s; animation-iteration-count: infinite; animation-timing-function: linear; } @keyframes logo-rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } #select .icon, #select .icon:hover:active, #login-icon .icon, #logout-icon .icon { width: 32px; height: 32px; margin: 16px; filter: var(--nav-icon-filter); background-position: center center; background-repeat: no-repeat; } #select .icon:hover, #select .icon.true, #login-icon:hover .icon, #logout-icon:hover .icon { filter: var(--nav-icon-filter-select); } #nav:has(#changes:not(:empty)) #logout-icon .menu div:last-child { display: none; } /* -- end icon layout -- */ /* login start */ #login-icon, #logout-icon { position: relative; } #login-icon .icon, #logout-icon .icon { position: absolute; top: 0; pointer-events: none; } #login-icon label, #logout-icon label { position: absolute; top: 0; right: 0; } #login-icon input, #logout-icon input { width: 64px; height: 64px; opacity: 0; } #login-icon .menu, #logout-icon .menu { display: none; position: absolute; top: 64px; right: 0; padding: 0 0 5px 5px; text-align: right; font-size: calc(var(--font-base-size) - 2px); background-color: var(--nav-bg-color); border-bottom-left-radius: 10px; border-top: 1px solid var(--ctrl-modal-bg-tertiary-color); z-index: 1; } #login-icon .menu > div, #logout-icon .menu > div { padding: 12px 20px; color: var(--title-fg-color); cursor: pointer; } #login-icon:has(input:checked) .menu, #logout-icon:has(input:checked) .menu { display: block; } #login-icon .menu > div:hover, #logout-icon .menu > div:hover { color: var(--menu-fg-select-color); } #login-icon .menu a, #logout-icon .menu a { color: inherit; } #login { font: inherit; font-size: 16px; padding: 50px; color: var(--ctrl-modal-fg-color); border-radius: 20px; background-color: var(--ctrl-modal-bg-tertiary-color); } #login input { color: inherit; background-color: var(--ctrl-modal-textbox-bg-color); margin: 0 10px; outline: none; } #login button { font: inherit; font-size: 12px; color: inherit; background-color: var(--ctrl-modal-textbox-bg-color); } #login::backdrop { background-color: var(--ctrl-modal-backdrop-color); } /* login end */ /* messages start */ #messages { position: relative; background-color: var(--message-bg-color); padding: 10px; border-radius: 10px; z-index: 1; } #messages .section-title { color: var(--message-fg-color); } #messages .section > div { color: var(--message-fg-color); padding: 0 0 4px 2px; } /* messages end */ /* tools start */ #tools { display: none; } /* tools end */ /* meshpage start */ #meshfilter { padding-top: 30px; display: flex; } #meshfilter input { width: 300px; outline: none; font: inherit; padding: 5px; color: var(--ctrl-modal-fg-color); background-color: var(--ctrl-modal-textbox-bg-color); border: 1px solid var(--ctrl-modal-textbox-border-color); } #meshfilter button { padding: 5px 10px; border: 1px solid var(--ctrl-modal-textbox-border-color); background-color: transparent; font: inherit; color: var(--ctrl-modal-textbox-border-color); } #meshfilter button:hover { background-color: var(--meshpage-node-bg-color-hover); } #meshpage { padding: 40px 60px; font-size: calc(var(--font-base-size) - 2px); } #meshpage .block { position: relative; display: flex; flex-flow: wrap; padding: 40px 20px 30px 20px; border-radius: 10px; margin-bottom: 10px; border-width: 2px; border-style: solid; } #meshpage .block:empty { display: none; } #meshpage .block .label { position: absolute; top: -1px; left: -1px; padding: 4px 10px; font-size: calc(var(--font-base-size) - 2px); text-transform: uppercase; color: var(--body-bg-color); border-top-left-radius: 10px; border-bottom-right-radius: 10px; } #meshpage .node { width: 50%; padding: 2px 20px; border-radius: 10px; } #meshpage .node:hover { background-color: var(--meshpage-node-bg-color-hover); } #meshpage .node .etx { font-size: 10px; color: var(--meshpage-etx-fg-color); padding-left: 6px; } #meshpage .lanhosts { font-size: calc(var(--font-base-size) - 3px); padding: 4px 0 6px 0; } #meshpage .host, #meshpage .lanhost { display: flex; } #meshpage .host .name, #meshpage .lanhost .name { flex: 1; } #meshpage .host .name a { text-decoration: none; color: var(--meshpage-hostname-fg-color); } #meshpage .host .name a:hover { text-decoration: underline; } #meshpage .services { flex: 1; font-size: calc(var(--font-base-size) - 3px); } #meshpage .service { white-space: nowrap; } #meshpage .service a, #meshpage .service span { text-decoration: none; color: inherit; white-space: normal; } #meshpage .service a:hover { text-decoration: underline; color: var(--meshpage-service-hover-fg-color); } #meshpage .service div { position: relative; display: inline-block; top: 2.5px; width: 14px; height: 14px; margin: 0; background: url('data:image/svg+xml;utf8,') center center no-repeat; filter: var(--icon-filter); } .meshpage-help { display: none; padding: 40px 120px 0 120px; } .meshpage-help.visible { display: block; color: var(--ctrl-modal-fg-help-color); font-size: calc(var(--font-base-size) - 4px); } .block1 { border-color: var(--meshpage-block1-border-color); } .block2 { border-color: var(--meshpage-block2-border-color); } .block3 { border-color: var(--meshpage-block3-border-color); } .block5 { border-color: var(--meshpage-block5-border-color); } .block10 { border-color: var(--meshpage-block10-border-color); } .block1000 { border-color: var(--meshpage-block1000-border-color); } .block1 .label { background-color: var(--meshpage-block1-border-color); } .block2 .label { background-color: var(--meshpage-block2-border-color); } .block3 .label { background-color: var(--meshpage-block3-border-color); } .block5 .label { background-color: var(--meshpage-block5-border-color); } .block10 .label { background-color: var(--meshpage-block10-border-color); } .block1000 .label { background-color: var(--meshpage-block1000-border-color); } #meshpage.filtering .service, #meshpage.filtering .lanhost, #meshpage.filtering .node, #meshpage.filtering .block { display: none; } #meshpage.filtering .service.valid, #meshpage.filtering .node:has(.service.valid), #meshpage.filtering .node:has(.lanhost.valid), #meshpage.filtering .node:has(.host.valid) { display: block; } #meshpage.filtering .lanhost:has(.service.valid), #meshpage.filtering .lanhost.valid, #meshpage.filtering .block:has(.service.valid), #meshpage.filtering .block:has(.lanhost.valid), #meshpage.filtering .block:has(.host.valid) { display: flex; } /* meshpage end /* start icons */ .icon.status { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.mesh { background-image: url("data:image/svg+xml;utf8,") !important; } .icon.cloudmesh { background-image: url("data:image/svg+xml;utf8,") !important; } .icon.tools { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.login { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.login.authenticated { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.map { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.camera { background-image: url('data:image/svg+xml;utf8, ') !important; } .icon.phone { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.time { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.winlink, .icon.mail { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.local { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.server { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.router, .icon.switch { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.radio { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.video { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.chat { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.solar { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.battery { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.power { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.wiki { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.refresh { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.cloud { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.cloudup { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.clipboard { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.wifi { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.download { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.twoarrow { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.tool { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.signal { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.plane { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.bolt { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.updownarrow { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.globe { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.eye { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.warning { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.weather { background-image: url('data:image/svg+xml;utf8,') !important; } .icon.plus { background-image: url('data:image/svg+xml;utf8,') !important; } /* end icons */