diff options
Diffstat (limited to 'public/css')
37 files changed, 7307 insertions, 0 deletions
diff --git a/public/css/icinga/about.less b/public/css/icinga/about.less new file mode 100644 index 0000000..fe3a71b --- /dev/null +++ b/public/css/icinga/about.less @@ -0,0 +1,113 @@ +/*! Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +#about { + &.content { + display: flex; + flex-direction: column; + align-items: center; + } + + section { + width: auto; + + > * { + margin-bottom: 2em; + } + + .pending-migrations { + .name-value-table.migrations { + tr:not(:first-child):not(:last-child) { + border-top: 1px solid @gray-lighter; + } + } + + a { + float: right; + margin-top: 1em; + color: @icinga-blue + } + } + } + + h2 { + margin: 0; + } + + .name-value-table { + th { + width: 100%; + } + + th, + td { + white-space: nowrap; + + a { + color: @icinga-blue + } + } + } + + section:not(:last-child), + .icinga-logo { + margin-bottom: 2em; + } + + .external-links { + .rounded-corners(); + border: 1px solid @gray-light; + display: flex; + padding: .5em 0; + overflow: hidden; + + .col { + flex: 1 1 auto; + text-align: center; + font-size: 12/14em; + } + + .col:not(:last-child) { + border-right: 1px solid @gray-light; + } + + a { + display: block; + padding: .75em 1em; + margin: -7/12em 0; + } + + a:hover { + text-decoration: none; + background: @gray-light; + } + + i { + font-size: 2*14/12em; + opacity: .8; + margin-bottom: .25em; + display: block; + + &:before { + margin-right: 0; + } + } + } + + footer { + margin-top: auto; + align-self: stretch; + display: flex; + justify-content: space-between; + align-items: baseline; + + a { + i { + font-size: 2em; + } + + &:hover { + opacity: .6; + } + } + } +} diff --git a/public/css/icinga/animation.less b/public/css/icinga/animation.less new file mode 100644 index 0000000..aad3ffb --- /dev/null +++ b/public/css/icinga/animation.less @@ -0,0 +1,366 @@ +/*! Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +.animate(@animate) { + -moz-animation: @animate; + -o-animation: @animate; + -webkit-animation: @animate; + animation: @animate; +} + +@-moz-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-webkit-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-o-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@-ms-keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -moz-transform: rotate(0deg); + -o-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(359deg); + -o-transform: rotate(359deg); + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} + +@-moz-keyframes move-vertical { + 0% { + -moz-transform: translate(0, 100%); + -o-transform: translate(0, 100%); + -webkit-transform: translate(0, 100%); + transform: translate(0, 100%); + } + + 17% { + -moz-transform: translate(0, 66%); + -o-transform: translate(0, 66%); + -webkit-transform: translate(0, 66%); + transform: translate(0, 66%); + } + + 33% { + -moz-transform: translate(0, 33%); + -o-transform: translate(0, 33%); + -webkit-transform: translate(0, 33%); + transform: translate(0, 33%); + } + + 50% { + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + } + + 67% { + -moz-transform: translate(0, -33%); + -o-transform: translate(0, -33%); + -webkit-transform: translate(0, -33%); + transform: translate(0, -33%); + } + + 83% { + -moz-transform: translate(0, -66%); + -o-transform: translate(0, -66%); + -webkit-transform: translate(0, -66%); + transform: translate(0, -66%); + } + + 100% { + -moz-transform: translate(0, -100%); + -o-transform: translate(0, -100%); + -webkit-transform: translate(0, -100%); + transform: translate(0, -100%); + } +} +@-webkit-keyframes move-vertical { + 0% { + -moz-transform: translate(0, 100%); + -o-transform: translate(0, 100%); + -webkit-transform: translate(0, 100%); + transform: translate(0, 100%); + } + + 17% { + -moz-transform: translate(0, 66%); + -o-transform: translate(0, 66%); + -webkit-transform: translate(0, 66%); + transform: translate(0, 66%); + } + + 33% { + -moz-transform: translate(0, 33%); + -o-transform: translate(0, 33%); + -webkit-transform: translate(0, 33%); + transform: translate(0, 33%); + } + + 50% { + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + } + + 67% { + -moz-transform: translate(0, -33%); + -o-transform: translate(0, -33%); + -webkit-transform: translate(0, -33%); + transform: translate(0, -33%); + } + + 83% { + -moz-transform: translate(0, -66%); + -o-transform: translate(0, -66%); + -webkit-transform: translate(0, -66%); + transform: translate(0, -66%); + } + + 100% { + -moz-transform: translate(0, -100%); + -o-transform: translate(0, -100%); + -webkit-transform: translate(0, -100%); + transform: translate(0, -100%); + } +} +@-o-keyframes move-vertical { + 0% { + -moz-transform: translate(0, 100%); + -o-transform: translate(0, 100%); + -webkit-transform: translate(0, 100%); + transform: translate(0, 100%); + } + + 17% { + -moz-transform: translate(0, 66%); + -o-transform: translate(0, 66%); + -webkit-transform: translate(0, 66%); + transform: translate(0, 66%); + } + + 33% { + -moz-transform: translate(0, 33%); + -o-transform: translate(0, 33%); + -webkit-transform: translate(0, 33%); + transform: translate(0, 33%); + } + + 50% { + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + } + + 67% { + -moz-transform: translate(0, -33%); + -o-transform: translate(0, -33%); + -webkit-transform: translate(0, -33%); + transform: translate(0, -33%); + } + + 83% { + -moz-transform: translate(0, -66%); + -o-transform: translate(0, -66%); + -webkit-transform: translate(0, -66%); + transform: translate(0, -66%); + } + + 100% { + -moz-transform: translate(0, -100%); + -o-transform: translate(0, -100%); + -webkit-transform: translate(0, -100%); + transform: translate(0, -100%); + } +} +@-ms-keyframes move-vertical { + 0% { + -moz-transform: translate(0, 100%); + -o-transform: translate(0, 100%); + -webkit-transform: translate(0, 100%); + transform: translate(0, 100%); + } + + 17% { + -moz-transform: translate(0, 66%); + -o-transform: translate(0, 66%); + -webkit-transform: translate(0, 66%); + transform: translate(0, 66%); + } + + 33% { + -moz-transform: translate(0, 33%); + -o-transform: translate(0, 33%); + -webkit-transform: translate(0, 33%); + transform: translate(0, 33%); + } + + 50% { + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + } + + 67% { + -moz-transform: translate(0, -33%); + -o-transform: translate(0, -33%); + -webkit-transform: translate(0, -33%); + transform: translate(0, -33%); + } + + 83% { + -moz-transform: translate(0, -66%); + -o-transform: translate(0, -66%); + -webkit-transform: translate(0, -66%); + transform: translate(0, -66%); + } + + 100% { + -moz-transform: translate(0, -100%); + -o-transform: translate(0, -100%); + -webkit-transform: translate(0, -100%); + transform: translate(0, -100%); + } +} +@keyframes move-vertical { + 0% { + -moz-transform: translate(0, 100%); + -o-transform: translate(0, 100%); + -webkit-transform: translate(0, 100%); + transform: translate(0, 100%); + } + + 17% { + -moz-transform: translate(0, 66%); + -o-transform: translate(0, 66%); + -webkit-transform: translate(0, 66%); + transform: translate(0, 66%); + } + + 33% { + -moz-transform: translate(0, 33%); + -o-transform: translate(0, 33%); + -webkit-transform: translate(0, 33%); + transform: translate(0, 33%); + } + + 50% { + -moz-transform: translate(0, 0); + -o-transform: translate(0, 0); + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + } + + 67% { + -moz-transform: translate(0, -33%); + -o-transform: translate(0, -33%); + -webkit-transform: translate(0, -33%); + transform: translate(0, -33%); + } + + 83% { + -moz-transform: translate(0, -66%); + -o-transform: translate(0, -66%); + -webkit-transform: translate(0, -66%); + transform: translate(0, -66%); + } + + 100% { + -moz-transform: translate(0, -100%); + -o-transform: translate(0, -100%); + -webkit-transform: translate(0, -100%); + transform: translate(0, -100%); + } +} + +@keyframes blink { + 0% { + opacity: 0.2; + } + + 20% { + opacity: 1; + } + + 100% { + opacity: 0.2; + } +} + +@keyframes pulse { + 0% { + opacity: .5; + transform: scale(1); + } + + 50% { + opacity: 1; + transform: scale(1.2); + } + + 100% { + opacity: .5; + transform: scale(1); + } +} diff --git a/public/css/icinga/audit.less b/public/css/icinga/audit.less new file mode 100644 index 0000000..23ab5b9 --- /dev/null +++ b/public/css/icinga/audit.less @@ -0,0 +1,363 @@ +// Style + +.privilege-audit-role-control { + list-style-type: none; + + li { + .rounded-corners(3px); + border: 1px solid; + border-color: @low-sat-blue; + + &.active { + border-color: @icinga-blue; + } + } +} + +.privilege-audit { + &, ul, ol { + list-style-type: none; + } + + .privilege-section > summary { + font-weight: @font-weight-bold; + border-bottom: 1px solid @gray-light; + } + + .privilege-section > summary em, + .previews em, + .privilege-label em { + color: @text-color-light; + } + .privilege-section > summary em { + font-weight: normal; + } + .privilege-label em { + font-style: normal; + } + + .icon { + color: @gray-light; + + &.granted { + color: @color-granted; + } + + &.refused { + color: @color-refused; + } + + &.restricted { + color: @color-restricted; + } + } + + .privilege-list > li { + .spacer { + opacity: 0; + .transition(opacity .5s ease-out); + } + + &:hover .spacer { + .transition(opacity .25s .25s ease-in); + border: 0 dashed; + border-color: @gray-light; + border-top-width: .2em; + opacity: 1; + } + } + + .vertical-line { + border: 0 solid; + border-left-width: 2px; + + &.granted { + border-color: @color-granted; + } + + &.refused { + border-color: @color-refused; + } + } + + .connector { + border: 0 solid; + border-color: @gray-lighter; + border-bottom-width: 2px; + + &.granted { + border-color: @color-granted; + } + + &.refused { + border-color: @color-refused; + } + + &:first-child { + border-width: 0 0 2px 2px; + border-bottom-left-radius: .5em; + } + } + + .role { + .rounded-corners(1em); + border: 2px solid; + border-color: @gray-lighter; + + &.granted { + border: 2px solid; + border-color: @color-granted; + } + + &.refused { + border: 2px solid; + border-color: @color-refused; + } + } + + .restriction { + font-family: @font-family-fixed; + background-color: @gray-lighter; + } +} + +// Layout + +.privilege-audit-role-control { + display: inline-flex; + flex-wrap: wrap; + + margin: 0 0 0 1em; + padding: 0; + + li { + margin-top: @vertical-padding; + + &:not(:first-child) { + margin-left: .5em; + } + } +} + +.privilege-audit { + &, ul, ol { + margin: 0; + padding: 0; + } + + .flex-overflow, + .privilege-list > li, + .inheritance-paths > ol { + display: flex; + } + + .privilege-list > li { + margin-top: 1em; + + > :last-child { + // This aids the usage of text-overflow:ellipsis in any of the children. + // It seems that to get this working while none of the children has a + // defined width, any flex item on the way up to the clipped container + // also must have a overflow value of "hidden". + // https://codepen.io/unthinkingly/pen/XMwJLG + overflow: hidden; + } + + > details:last-child { + // The overflow above cuts off the outline of the summary otherwise + margin: -4px; + padding: 4px; + } + } + + .privilege-section { + &:not(.collapsed) { + margin-bottom: 2em; + } + } + + .privilege-section > summary { + display: flex; + align-items: baseline; + font-size: 1.167em; + margin: 0.556em 0 0.333em; + + > :first-child { + flex: 3 1 auto; + min-width: 20em; + max-width: 40em / 1.167em; // privilege label width + spacer width / summary font-size + } + + .audit-preview { + flex: 1 1 auto; + + .icon:before { + width: 1.25em; + font-size: 1.25em / 1.167em; // privilege state icon font-size / summary font-size + } + } + + em { + font-size: .857em; + } + } + + h4, + .privilege-label { + flex-shrink: 0; + width: 20em; + margin: 0; + text-align: right; + } + + ol + h4 { + margin-top: 1em; + } + + .spacer { + flex: 20 1 auto; + min-width: 10em; // TODO: Mobile? + max-width: 18.8em; // 20em - (margin-left + margin-right) + margin: .6em; + } + + .inheritance-paths, + .restrictions { + flex: 1 1 auto; + + > summary { + line-height: 1; + + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + + > .icon:before { + width: 1.25em; + font-size: 1.25em; + } + } + } + + .vertical-line { + margin-left: ~"calc(.75em - 1px)"; + } + + .connector { + flex: 1 1 auto; + width: 2em; + max-width: 2em; + min-width: 1em; + margin-bottom: ~"calc(1em - 1px)"; + + &:first-child { + margin-left: ~"calc(.75em - 1px)"; + } + + &.initiator { + z-index: 1; + margin-right: ~"calc(-.25em - 2px)"; + } + } + + .vertical-line + .connector { + min-width: ~"calc(.75em - 2px)"; + width: ~"calc(.75em - 2px)"; + flex-grow: 0; + + &.initiator { + width: ~"calc(1em - 1px)"; + } + } + .connector:first-child { + min-width: .75em; + width: .75em; + flex-grow: 0; + + &.initiator { + width: 1em; + } + } + + .role { + padding: .25em .5em .25em .5em; + line-height: 1; + + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + + .icon:before { + font-size: 1.25em; + } + } + .inheritance-paths .role { + min-width: 4em; + margin-top: .5em; + padding-left: .25em; + } + .restrictions .role { + display: inline-block; + } + + .previews { + display: flex; + margin-top: .25em; + + em { + // explicit margin + ((header icon width + its margin right) * 125% font-size) + margin: 0 1em 0 1em + ((1.25em + .2em) * 1.25em); + } + } + + .links li:not(:last-child):after { + content: ","; + } + + .restrictions > ul > li { + margin-top: .5em; + + .role { + margin-left: 1.25em + .2em * 1.25em; // (header icon width + its margin right) * 125% font-size + margin-right: 1em; + } + } + + .restriction { + font-size: .8em; + padding: .335em / .8em; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + + .user-select(all); + } +} + +#layout.minimal-layout, +#layout.poor-layout { + .privilege-audit { + .privilege-section > summary > :first-child { + flex-grow: 99; + } + + h4, + .privilege-label { + width: 12em; + } + + .spacer { + flex: 0; + min-width: 0; + } + } +} + +// Integrations + +.privilege-audit .collapsible { + .collapsible-control { + cursor: pointer; + .user-select(none); + } +} diff --git a/public/css/icinga/badges.less b/public/css/icinga/badges.less new file mode 100644 index 0000000..eae95c2 --- /dev/null +++ b/public/css/icinga/badges.less @@ -0,0 +1,22 @@ +/*! Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +@badge-color: @body-bg-color; +@badge-line-height: 1.2; +@badge-padding: 0.25em; + +.badge { + .bg-stateful(); + .rounded-corners(); + + background-color: @gray; + color: @badge-color; + display: inline-block; + font-family: @font-family-wide; + font-size: @font-size-small; + line-height: @badge-line-height; + min-width: 2em; + padding: @badge-padding; + text-align: center; + vertical-align: middle; + white-space: nowrap; +} diff --git a/public/css/icinga/base.less b/public/css/icinga/base.less new file mode 100644 index 0000000..539a981 --- /dev/null +++ b/public/css/icinga/base.less @@ -0,0 +1,344 @@ +/*! Icinga Web 2 | (c) 2013 Icinga Development Team | GPLv2+ */ + +// Black colors +@black: #535353; +@white: #fff; + +// Gray colors +@gray: #c4c4c4; +@gray-semilight: #888; +@gray-light: #5c5c5c; +@gray-lighter: #4b4b4b; +@gray-lightest: #3a3a3a; + +@disabled-gray: #9a9a9a; + +// State colors +@color-ok: #44bb77; +@color-up: @color-ok; +@color-warning: #ffaa44; +@color-warning-handled: #ffcc66; +@color-critical: #ff5566; +@color-critical-handled: #ff99aa; +@color-critical-accentuated: darken(@color-critical, 10%); +@color-down: @color-critical; +@color-down-handled: @color-critical-handled; +@color-unknown: #aa44ff; +@color-unknown-handled: #cc77ff; +@color-unreachable: @color-unknown; +@color-unreachable-handled: @color-unknown-handled; +@color-pending: #77aaff; + +// Icinga colors +@icinga-blue: #00C3ED; +@icinga-secondary: #EF4F98; +@icinga-secondary-dark: darken(@icinga-secondary, 10%); +@low-sat-blue: #404d72; +@low-sat-blue-dark: #434374; +@icinga-blue-light: fade(@icinga-blue, 50%); +@icinga-blue-dark: #0081a6; + +// Notification colors +@color-notification-error: @color-critical; +@color-notification-info: @color-pending; +@color-notification-success: @color-ok; +@color-notification-warning: @color-warning; + +// Background color for <body> +@body-bg-color: #282E39; +@body-bg-color-transparent: fade(@body-bg-color, 0); + +// Text colors +@text-color: @white; +@text-color-inverted: @body-bg-color; +@text-color-light: fade(@text-color, 75%); +@text-color-on-icinga-blue: @body-bg-color; +@light-text-bg-color: fade(@gray, 5%); + +// Text color on <a> +@link-color: @text-color; + +@tr-active-color: fade(@icinga-blue, 25); +@tr-hover-color: fade(@icinga-blue, 5); + +// Menu colors +@menu-bg-color: #06062B; +@menu-hover-bg-color: lighten(@menu-bg-color, 5%); +@menu-search-hover-bg-color: @menu-hover-bg-color; +@menu-active-bg-color: #181742; +@menu-active-hover-bg-color: lighten(@menu-active-bg-color, 5%); +@menu-color: #DBDBDB; +@menu-active-color: @text-color; +@menu-highlight-color: @icinga-blue; +@menu-highlight-hover-bg-color: @icinga-blue-dark; +@menu-2ndlvl-color: #c4c4c4; +@menu-2ndlvl-highlight-bg-color: fade(@icinga-blue, 10); +@menu-2ndlvl-active-bg-color: @menu-highlight-color; +@menu-2ndlvl-active-color: @text-color-inverted; +@menu-2ndlvl-active-hover-bg-color: darken(@menu-2ndlvl-active-bg-color, 5%); +@menu-2ndlvl-active-hover-color: @menu-2ndlvl-active-color; +@menu-flyout-bg-color: @body-bg-color; +@menu-flyout-color: @text-color; +@tab-hover-bg-color: fade(@body-bg-color, 50%); + +// Form colors +@form-info-bg-color: fade(@color-ok, 20%); +@form-error-bg-color: fade(@color-critical, 30%); +@form-warning-bg-color: fade(@color-warning, 40%); +@login-box-background: fade(#0B0B2F, 30%); + +// Other colors +@color-granted: #59cd59; +@color-refused: #ee7373; +@color-restricted: #dede7d; + +// Font families +@font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; +@font-family-fixed: "Liberation Mono", "Lucida Console", Courier, monospace; +@font-family-wide: Tahoma, Verdana, sans-serif; + +// Font sizes +@font-size: 0.750em; // 12px +@font-size-small: 11/12em; // 11px +@font-size-dashboard: 3.5em; // 56px +@font-size-dashboard-small: 1.1em; // 17px +@font-weight-bold: 600; + +// Set line-height w/o unit so that the line-height is dynamically calculated as font-size * line-height +@line-height: 1.5; + +@table-column-padding: 0.333em; // 4px + +@vertical-padding: 0.5em; // 6px +@horizontal-padding: 1em; // 12px + +@light-mode: { + @light-body-bg-color: #F5F9FA; + + @iplWebLightRules(); + + :root { + --body-bg-color: @light-body-bg-color; + --body-bg-color-transparent: fade(@light-body-bg-color, 0); + --badge-color: #F5F9FA; + --text-color-inverted: #F5F9FA; + --text-color-on-icinga-blue: #F5F9FA; + --menu-flyout-bg-color: #F5F9FA; + --tab-hover-bg-color: fade(#F5F9FA, 50%); + + --menu-color: #535353; + --menu-bg-color: #DEECF1; + --menu-hover-bg-color: darken(#DEECF1, 10%); + --menu-search-hover-bg-color: darken(#DEECF1, 10%); + --menu-active-bg-color: #EDF7FC; + --menu-active-hover-bg-color: darken(#EDF7FC, 20%); + --menu-highlight-hover-bg-color: darken(#EDF7FC, 20%); + --menu-2ndlvl-color: #676767; + + --text-color: #535353; + --text-color-light: fade(#535353, 75%); + --light-text-bg-color: fade(#7F7F7F, 5%); + --link-color: #535353; + --menu-active-color: #535353; + --menu-flyout-color: #535353; + + --low-sat-blue: #DEECF1; + --low-sat-blue-dark: #c0cccd; + + --gray: #819398; + --gray-semilight: #94a5a6; + --gray-light: #d0d3da; + --gray-lighter: #e8ecef; + --gray-lightest: #F7F7F7; + + // ipl-web overrides + --base-gray: var(--gray); + --base-gray-light: var(--gray-light); + --base-gray-lighter: var(--gray-lighter); + --base-gray-semilight: var(--gray-semilight); + + --default-text-color: var(--text-color); + --default-text-color-light: var(--text-color-light); + --default-text-color-inverted: var(--text-color-inverted); + --default-input-bg: var(--low-sat-blue); + + --search-logical-operator-bg: fade(#819398, 50%); // --gray + } +}; + +// ipl-web overrides +@default-bg: @body-bg-color; + +@base-gray: @gray; +@base-gray-light: @gray-light; +@base-gray-lighter: @gray-lighter; +@base-gray-semilight: @gray-semilight; +@base-disabled: @disabled-gray; + +@base-primary-color: @icinga-blue; +@base-primary-bg: @icinga-blue; +@base-primary-dark: @icinga-blue-dark; +@base-primary-light: @icinga-blue-light; + +@default-text-color: @text-color; +@default-text-color-light: @text-color-light; +@default-input-bg: @low-sat-blue; + +@state-ok: @color-ok; +@state-warning: @color-warning; +@state-critical: @color-critical; +@state-pending: @color-pending; +@state-unknown: @color-unknown; + +// Make padding not affect the final computed width of an element +html { + box-sizing: border-box; +} +details > * { + // children somehow default to content-box no matter the inheritance + box-sizing: border-box; +} +*, +*:before, +*:after { + -webkit-box-sizing: inherit; + -moz-box-sizing: inherit; + box-sizing: inherit; +} + +a { + // Reset defaults + color: inherit; + text-decoration: none; + + &:hover { + text-decoration: underline; + } +} + +:focus { + outline: 3px solid fade(@icinga-blue, 50%); + outline-offset: 1px; +} + +// Default margin for block text +blockquote, p, pre { + margin: 0 0 1em 0; +} + +blockquote { + border-left: 5px solid @gray-lighter; + padding: 0.667em 0.333em; +} + +h1, h2, h3, h4, h5, h6 { + font-weight: @font-weight-bold; + margin: 0.556em 0 0.333em; +} + +h1 { + border-bottom: 1px solid @gray-lighter; + font-size: 1.333em; +} + +h2 { + font-size: 1.333em; +} + +h3 { + font-size: 1.167em; +} + +h4 { + font-size: 1em; +} + +h5 { + font-size: @font-size-small; +} + +h6 { + font-size: @font-size-small; + font-weight: normal; +} + +pre { + .rounded-corners(.25em); + background-color: @gray-lighter; + font-family: @font-family-fixed; + font-size: @font-size-small; + padding: @vertical-padding @horizontal-padding; + white-space: pre-wrap; +} + +td, th { + padding: @table-column-padding; +} + +[class^="icon-"], [class*=" icon-"] { + // Smooth icons; ifont claims to have it, but it does not work in :before + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + &:before { + margin-left: 0; + } +} + +// Styles for when the page is loading. JS will remove this class once the document is ready +.loading * { + // Disable all transition on page load + -webkit-transition: none !important; + -moz-transition: none !important; + -o-transition: none !important; + transition: none !important; +} + +.container { + &:before, + > .content:before { + content: ""; + display: block; + + background: url(../img/icinga-loader.gif) no-repeat center center; + background-color: @body-bg-color; + background-size: 4em 4em; + + opacity: 0; + z-index: -1; + pointer-events: none; + .transition(none); + } + + &.impact, + > .content.impact { + overflow: hidden; + position: relative; + + &:before { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + + opacity: .7; + z-index: 1000; + pointer-events: all; + .transition(opacity 1s 2s linear); + } + } + + &.impact:before { + top: 2.5em; + } +} + +@light-mode: { + .container { + &:before, + > .content:before { + background-image: url(../img/icinga-loader-light.gif) + } + } +}; diff --git a/public/css/icinga/compat.less b/public/css/icinga/compat.less new file mode 100644 index 0000000..d57a189 --- /dev/null +++ b/public/css/icinga/compat.less @@ -0,0 +1,35 @@ +/*! Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +@colorMainLayout: @icinga-blue; +@colorMainBackground: @body-bg-color; +@colorMainForeground: @text-color; +@colorMainLink: @text-color; +@colorSecondary: @gray-lightest; +@colorGray: @gray-lightest; +@colorLinkDefault: @text-color; +@colorTextDefault: @text-color; +@colorTextDarkDefault: @text-color; +@colorOk: @color-ok; +@colorWarning: #ffaa44; +@colorWarningHandled: #ffcc66; +@colorCritical: #ff5566; +@colorCriticalHandled: #ff99aa; +@colorUnknown: #aa44ff; +@colorUnknownHandled: #cc77ff; +@colorUnreachable: #aa44ff; +@colorUnreachableHandled: #cc77ff; +@colorPending: #77aaff; +@colorInvalid: #999; +@colorFormNotificationInfo: #77aaff; +@colorFormNotificationWarning: #ffaa44; +@colorFormNotificationError: #ff5566; +@colorPetrol: @icinga-blue; +@menu-2ndlvl-highlight-color: @menu-2ndlvl-active-color; + +table.action { + .common-table(); +} + +table.avp { + .name-value-table(); +} diff --git a/public/css/icinga/configmenu.less b/public/css/icinga/configmenu.less new file mode 100644 index 0000000..05e50e8 --- /dev/null +++ b/public/css/icinga/configmenu.less @@ -0,0 +1,303 @@ +#menu { + margin-bottom: 3em; +} + +.sidebar-collapsed #menu { + margin-bottom: 8em; +} + +#menu .config-menu { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background-color: @menu-bg-color; + margin-top: auto; + + > ul { + display: flex; + flex-wrap: nowrap; + padding: 0; + + > li { + > a { + padding: 0.5em 0.5em 0.5em 0.75em; + line-height: 2.167em; + white-space: nowrap; + text-decoration: none; + + } + + &:hover .nav-level-1 { + display: block; + } + } + + li.active a:after { + display: none; + } + + .user-nav-item { + width: 100%; + overflow: hidden; // necessary for .text-ellipsis of <a> + + > a { + overflow: hidden; + text-overflow: ellipsis; + } + + &:not(.active):hover a, + &:not(.active) a:focus { + background: @menu-hover-bg-color; + } + } + + .config-nav-item { + line-height: 2; + display: flex; + align-items: center; + position: relative; + + > button { + background: none; + border: none; + display: block; + .rounded-corners(); + + > .state-badge { + position: absolute; + pointer-events: none; + } + + .icon { + opacity: .8; + font-size: 1.25em; + + &:before { + margin-right: 0; + } + } + } + + &:hover > button { + background: fade(@menu-hover-bg-color, 25); + + > .state-badge { + display: none; + } + } + + button:focus { + background: fade(@menu-hover-bg-color, 25); + } + + &.active > button { + color: @text-color-inverted; + background: @icinga-blue; + } + } + + .state-badge { + line-height: 1.2; + padding: .25em; + font-family: @font-family-wide; + } + } + + .nav-level-1 li { + &.badge-nav-item > a { + display: flex; + align-items: baseline; + width: 100%; + + .state-badge { + margin-left: auto; + } + } + } + + .nav-item-logout { + color: @color-critical; + border-top: 1px solid @gray-lighter; + } + + .user-ball { + .ball(); + .ball-size-l(); + .ball-solid(@icinga-blue); + + // icingadb-web/public/css/common.less: .user-ball + font-weight: bold; + text-transform: uppercase; + + // compensate border vertically and add space to the right; + margin: -1px .2em -2px 0; + border: 1px solid @text-color-inverted; + font-style: normal; + line-height: 1.2; + } +} + +#layout:not(.sidebar-collapsed) #menu .config-menu { + .user-nav-item { + > a { + padding-right: 4.75em; + } + + &.active.selected + .config-nav-item { + > button { + color: @text-color-inverted; + } + } + } + + .config-nav-item { + position: absolute; + right: 2.5em; + bottom: 0; + top: 0; + + .state-badge { + left: -1em; + top: 0; + } + } + + .flyout { + bottom: 100%; + right: -2em; + width: 15em; + } +} + +.sidebar-collapsed #menu .config-menu { + ul { + flex-direction: column; + + .user-ball { + margin-left: .25em * 1.5/2; + margin-right: .5em + .25em * 1.5/2; + width: 2em * 1.5/2 ; + height: 2em * 1.5/2; + font-size: 2/1.5em; + line-height: 1; + } + + .config-nav-item { + padding-right: 0; + margin-bottom: 3em; + + .icon { + font-size: 1.5em; + } + + button { + position: relative; + width: 3em; + margin: .125em .5em; + padding: .5em .75em; + + .state-badge { + right: -.25em; + bottom: -.25em; + font-size: .75em; + + overflow: hidden; + text-overflow: ellipsis; + max-width: 4em; + } + } + } + } + + .flyout { + bottom: 0; + left: 100%; + width: 14em; + + &:before { + left: -.6em; + bottom: 1em; + transform: rotate(135deg); + } + } +} + +.flyout { + display: none; + position: absolute; + border: 1px solid @gray-lighter; + background: @body-bg-color; + box-shadow: 0 0 1em 0 rgba(0,0,0,.25); + z-index: 1; + .rounded-corners(); + + a { + font-size: 11/12em; + padding: 0.364em 0.545em 0.364em 2em; + line-height: 2; + + &:hover { + text-decoration: none; + background: @menu-2ndlvl-highlight-bg-color; + } + } + + h3 { + font-size: 10/12em; + color: @text-color-light; + letter-spacing: .1px; + padding: 0.364em 0.545em 0.364em 0.545em; + margin: 0; + } + + .flyout-content { + overflow: auto; + // Partially escape to have ems calculated + max-height: calc(~"100vh - " 50/12em); + padding: .5em 0; + position: relative; + } + + // Caret + &:before { + content: ""; + display: block; + position: absolute; + transform: rotate(45deg); + background: @body-bg-color; + border-bottom: 1px solid @gray-lighter; + border-right: 1px solid @gray-lighter; + height: 1.1em; + width: 1.1em; + bottom: -.6em; + right: 2.5em; + } +} + +// Prevent flyout to vanish on autorefresh +#layout.config-flyout-open .config-nav-item { + .flyout { + display: block; + } + + > button > .state-badge { + display: none; + } +} + +#layout.minimal-layout .config-menu { + display: none; +} + +#layout.minimal-layout #menu { + margin-bottom: 0; +} + +#layout:not(.minimal-layout) #menu .primary-nav { + .user-nav-item, + .configuration-nav-item, + .system-nav-item { + display: none; + } +} diff --git a/public/css/icinga/controls.less b/public/css/icinga/controls.less new file mode 100644 index 0000000..01cf152 --- /dev/null +++ b/public/css/icinga/controls.less @@ -0,0 +1,281 @@ +/*! Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +// TODO(el): Rename .filter to .filter-control + +// Hide auto sumbit info in controls +.controls .autosubmit-info { + display: none; +} + + +// Backend selection control in user and group list views +.backend-selection { + float: left; + + .control-label-group, select { + display: inline-block; + } + + select { + margin-left: .5em; + } +} + +.controls input.search, +input.search { + .transition(border 0.3s ease); + .transition(background-image 0.2s ease); + + background-image: url(../img/icons/search_white.png); + background-repeat: no-repeat; + background-size: 1em 1em; + background-position: .25em center; + outline: none; + padding-left: 1.5em; + width: 20em; + + &:focus { + background-image: url(../img/icons/search_icinga_blue.png); + } + + &:focus:not([readonly]) { + border-color: @icinga-blue; + } +} + +@light-mode: { + #menu input.search, + .controls input.search, + input.search { + background-image: url(../img/icons/search.png); + } +}; + +.backend-selection, +.pagination-control, +.selection-info, +.sort-controls-container { + margin-bottom: 0.5em; +} + +.filter { + // Display filter control on a new line + clear: both; + margin: .5em 0; + + > a { + color: @icinga-blue; + padding: .5em; + line-height: 1; + } + + > a > i { + text-align: center; + &:before { + margin-right: 0; + } + } + + .form input { + padding: @vertical-padding @vertical-padding; + } +} + +.controls .filter { + form .search { + height: 2em; + } +} + +.controls .button-link { + height: 2em; +} + +.limiter-control > select { + margin-left: .5em; +} + +.pagination-control { + // Display the pagination-control on a new line + clear: both; + float: left; + + li { + line-height: 1; + + &.active { + border-bottom: 2px solid @icinga-blue; + + > a, + > a:hover { + color: @icinga-blue; + /* Compensate border-bottom: 2px */ + margin-bottom: -2px; + } + + > a:hover { + background: none; + cursor: default; + text-decoration: none; + } + } + + &.disabled { + color: @disabled-gray; + cursor: no-drop; + } + + > a, + > span { + padding: 0.5em; + } + > a:hover { + background-color: @gray-lighter; + text-decoration: none; + } + } + + .previous-page { + padding-left: 0; + } + + .next-page { + padding-right: 0; + } +} + +// Multi-selection info +.selection-info { + float: right; + font-size: @font-size-small; + + &:hover { + cursor: help; + } +} + +.sort-control { + label { + width: auto; + margin-right: 0.5em; + } + + select[name=sort] { + width: 12em; + margin-left: 0; + } + + select[name=dir] { + width: 8em; + margin-left: 0; + } +} + +.sort-controls-container { + clear: right; + float: right; + display: flex; + + > *:not(:last-child) { + margin-right: .5em; + } +} + +.sort-direction-control { + margin-left: 0.25em; + width: 1em; + + .spinner { + line-height: 1; + } +} + +.controls .icinga-controls { + .control-label-group { + margin-top: 0; + margin-bottom: 0; + line-height: 1.5em; + padding-top: 0.25em; + padding-bottom: 0.25em; + } + + input, + select { + max-width: 16em; + } + + select { + padding-right: 1.526em; + margin-top: 0; + margin-bottom: 0; + /* compensate inconsistent select height calculations */ + line-height: 1; + max-height: 2em; + } +} + +// Datetime picker colors + +// The less variables are essentially the official dark theme for the flatpickr +@fp-calendarBackground: #3f4458; +@fp-calendarBorderColor: darken(#3f4458, 50%); + +@fp-monthForeground: #fff; +@fp-monthBackground: #3f4458; + +@fp-weekdaysBackground: transparent; +@fp-weekdaysForeground: #fff; + +@fp-dayForeground: fadeout(white, 5%); +@fp-dayHoverBackground: lighten(@fp-calendarBackground, 25%); + +@fp-todayColor: #eee; +@fp-today_fg_color: #3f4458; + +@fp-selectedDayBackground: #80CBC4; + +.icinga-datetime-picker .flatpickr-day.today { + &:hover, + &:focus { + color: @fp-today_fg_color; + } +} + +@light-mode: { + :root { + // These are actually the default colors for the flatpickr + + @fp-dayForeground: #393939; + @fp-dayHoverBackground: #e6e6e6; + + --fp-calendarBackground: #ffffff; + --fp-calendarBorderColor: @fp-dayHoverBackground; + + --fp-arrowColor: fadeout(@fp-dayForeground, 40%); + --fp-arrow_hover_color: #f64747; + + --fp-monthForeground: fadeout(black, 10%); + --fp-monthBackground: transparent; + + --fp-weekdaysBackground: transparent; + --fp-weekdaysForeground: fadeout(black, 46%); + --fp-weekNumberForeground: fadeout(@fp-dayForeground, 70%); + + --fp-dayForeground: @fp-dayForeground; + --fp-dayHoverBackground: @fp-dayHoverBackground; + --fp-disabledDayForeground: fadeout(@fp-dayForeground, 90%); + --fp-outsideRangeDayForeground: fadeout(@fp-dayForeground, 70%); + --fp-selectedDayBackground: #569FF7; + --fp-todayColor: #959ea9; + + --fp-timeHoverBg: lighten(@fp-dayHoverBackground, 3); + + --fp-hoverInvertedBg: fadeout(black, 95%); + + --fp-numChooserSvgFillColor: fadeout(fadeout(black, 10%), 50%); + --fp-hoverNumChooserBg: fadeout(black, 90%); + --fp-numChooserBorderColor: fadeout(@fp-dayForeground, 85%); + } +}; + +// Datetime picker colors (end) diff --git a/public/css/icinga/dev.less b/public/css/icinga/dev.less new file mode 100644 index 0000000..a1e34be --- /dev/null +++ b/public/css/icinga/dev.less @@ -0,0 +1,10 @@ +/*! Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +#fontsize-calc { + display: none; + width: 1000em; + height: 1em; + font-size: 1em; + position: absolute; + top: -2em; +} diff --git a/public/css/icinga/forms.less b/public/css/icinga/forms.less new file mode 100644 index 0000000..00389ea --- /dev/null +++ b/public/css/icinga/forms.less @@ -0,0 +1,596 @@ +/*! Icinga Web 2 | (c) 2019 Icinga Development Team | GPLv2+ */ + +/** + Rules found in here are structured with two layers: + + 1) form.icinga-form, that's what defines the general structure of our single/individual forms. It's not + supposed to be used for any other forms that are not the only content on the page (e.g. inline-forms) + 2) .icinga-controls, this defines the design of our controls. Any input that's part of a container with + this class gets our design applied + */ + +// General form layout + +form.icinga-form { + max-width: 70em; + width: 80%; + + .control-group { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + + // Negative margin-right because every child gets 1em right but we can't exclude + // the last element as it's impossible to identify the last *visible* element + margin: 1em -1em 1em 0; + + > fieldset { + > .control-group:first-of-type { + margin-top: 0; + } + + > .control-group:last-of-type { + margin-bottom: 0; + } + } + } + + .control-group > :not(.control-label-group) { + margin-right: 1em; + } + + .form-controls { + display: flex; + justify-content: flex-end; + } + + &.inline { + width: auto; + + .control-group { + margin: 0; + align-items: center; + + > :not(.control-label-group) { + margin-right: .5em; + } + + &:last-child { + margin-right: -.5em; + } + } + } +} + +form.inline { + display: inline-block; + + fieldset { + display: inline-block; + vertical-align: top; + border: none; + } +} + +// Minimal form layout + +#layout.minimal-layout, +#layout.twocols:not(.wide-layout) { + form.icinga-form { + &:not(.inline) { + width: 100%; + } + + .control-label-group { + text-align: left; + padding-bottom: 0; + padding-left: 0; + margin-bottom: 0; + } + + .toggle-switch ~ .control-info:before { + margin-left: 0; + } + + .errors { + margin: 0; + } + } +} + +#layout.minimal-layout .icinga-form { + .form-controls { + input[type="submit"] { + width: 100%; + + &:not(:last-child) { + margin-bottom: 1em; + } + } + } +} + +// Label styles + +form.icinga-form .control-label-group { + display: flex; + flex-direction: column; + justify-content: center; + line-height: 1.1em; + padding: .5625em .5625em .5625em 0; + max-height: 2.5em; + text-align: right; + width: 14em; +} + +form.icinga-form.inline .control-label-group { + width: auto; + line-height: 0.857em; +} + +.icinga-controls fieldset { + margin: 0; + padding: 0; + border: none; + + legend { + font-weight: bold; + font-size: 4/3em; + margin: 0.556em 0 0.333em; + } +} + +.icinga-controls .control-info { + line-height: 2.25em; + opacity: .6; + + &:before { + margin-right: 0; + } + + &:hover { + opacity: 1; + } +} + +form.icinga-form .control-group .control-info { + margin-left: -.5em; +} +form.icinga-form .control-group .toggle-switch ~ .control-info { + margin-left: 0; +} + +// General input styles + +.icinga-controls { + input[type="text"], + input[type="password"], + input[type="number"], + input[type="datetime-local"], + input[type="date"], + input[type="time"], + input[type="file"], + textarea, + select { + background-color: @low-sat-blue; + } +} + +form.icinga-form { + input[type="text"], + input[type="password"], + input[type="number"], + input[type="datetime-local"], + input[type="date"], + input[type="time"], + input[type="file"], + .control-group > fieldset, + textarea, + select { + flex: 1 1 auto; + width: 0; + } +} + +.icinga-controls { + input:not([type="radio"]), + .toggle-switch, + button, + select, + textarea { + border: none; + .rounded-corners(.25em); + .appearance(none); + } +} + +.icinga-controls { + input:not([type="checkbox"]), + .toggle-switch, + select, + textarea, + button, + .toggle-switch { + font-size: inherit; + padding: @vertical-padding; + } + + input[type="radio"] { + margin-right: .25em; + } +} + +form.icinga-form { + .control-group .toggle-switch, + .form-controls .toggle-switch { + margin-top: 0.5em*0.666666667; + margin-bottom: 0.5em*0.666666667; + } +} + +form.icinga-form select:not([multiple]) { + // Compensate inconsistent select height calculations + line-height: 1em; + height: 2.25em; +} + +// Remove native dropdown arrow in IE10+ +.icinga-controls select::-ms-expand { + display: none; + opacity: 0; +} + +.icinga-controls select:not([multiple]) { + padding-right: 1.5625em; + background-image: url(../img/select-icon.svg); + background-repeat: no-repeat; + background-position: right center; + background-size: contain; +} + +form.icinga-form select { + width: 0; // Prevent selects with long option values from exceeding the container +} + +form.inline select { + width: auto; +} + + +// Specific input styles + +.link-button { + .action-link(); + // Reset defaults + background: none; + border: none; + display: inline-block; + padding: 0; + + text-align: left; +} + +.icinga-controls { + input ~ .spinner, + button ~ .spinner, + select ~ .spinner, + textarea ~ .spinner { + line-height: normal; + padding: .5em 0; + + &:before { + vertical-align: middle; + margin-left: .5em; + opacity: 0.4; + } + } +} + +/* selects get their spinner specifically placed */ +.icinga-controls select:not([multiple]) + .spinner { + height: 2.25em; + margin: 0; + + &:before { + margin-left: -3.75em; + } +} + +form.icinga-form .form-controls { + .spinner { + order: -1; + } + + .btn-primary { + order: 99; + } +} + +// Button styles + +.icinga-controls { + button:not([type]), + button[type="submit"], + input[type="submit"], + input[type="submit"].btn-confirm { + .button(); + } + + input[type="submit"].btn-remove { + .button(@body-bg-color, @color-critical, @color-critical-accentuated); + } + + input[type="submit"].btn-cancel { + .button(@body-bg-color, @gray, @black); + } + + button.noscript-apply { + color: @gray; + background-color: @gray-lightest; + border-color: @gray; + border-width: 1px; + } + + button[type="button"] { + background-color: @low-sat-blue; + } +} + +form.icinga-form { + button[type="button"] { + line-height: normal; + } +} + +form.inline { + :not([type="hidden"]) { + & ~ button:not([type]), + & ~ button[type="submit"], + & ~ input[type="submit"], + & ~ input[type="submit"].btn-confirm { + margin-left: @horizontal-padding; + } + } + + button.noscript-apply { + margin-left: .5em; + padding: .1em; + } +} + +// Toggle styles + +.icinga-controls .toggle-switch { + cursor: pointer; + position: relative; + display: inline-block; + height: 1.5em; + width: 2.625em; +} + +.icinga-controls .toggle-switch .toggle-slider { + position: absolute; + left: 0; + top: 0; + + display: inline-block; + background: @low-sat-blue; + border: 1px solid; + border-color: @low-sat-blue; + box-sizing: content-box; + border-radius: 1em; + height: 4/3em; + width: 8/3em; + vertical-align: middle; +} + +.icinga-controls .toggle-switch .toggle-slider:before { + position: absolute; + top: 0; + left: 0; + + background: @text-color-inverted; + border-radius: 1em; + border: 1px solid; + border-color: @low-sat-blue; + box-sizing: border-box; + content: ""; + display: block; + height: 4/3em; + margin-left: 0; + width: 4/3em; + + @transition: left .2s ease, margin .2s ease; + -webkit-transition: @transition; + -moz-transition: @transition; + -o-transition: @transition; + transition: @transition; +} + +.icinga-controls input[type="checkbox"]:checked + .toggle-switch .toggle-slider { + background-color: @icinga-blue; + border: 1px solid; + border-color: @icinga-blue; +} + +.icinga-controls input[type="checkbox"]:focus + .toggle-switch .toggle-slider { + box-shadow: 0 0 0 2px @body-bg-color, 0 0 0 4px @icinga-blue-light; +} + +.icinga-controls input[type="checkbox"]:checked + .toggle-switch .toggle-slider:before { + border: 1px solid; + border-color: @icinga-blue; + left: 100%; + margin-left: -4/3em; +} + +// Disabled inputs + +.icinga-controls .toggle-switch.disabled { + cursor: default; + + & > .toggle-slider { + background-color: @gray-light; + border-color: @gray-light; + + &:before { + background-color: @gray-lighter; + border-color: @gray-light; + } + } +} + +form.icinga-form .control-group.disabled .control-label-group { + color: @disabled-gray; +} + +.icinga-controls { + input[disabled], + select[disabled] { + background-color: @gray-lighter; + border-color: transparent; + } +} + +// Errors and additional information + +form.icinga-form { + .form-notifications, + .form-description { + border-radius: .25em; + display: flex; + list-style: none; + align-items: center; + margin: 0 0 1em 0; + padding: .25em .5em; + + ul { + list-style: none; + margin: 0; + padding: 0 .5em; + } + + li { + list-style: none; + } + + & .form-notification-icon, + & .form-description-icon { + font-size: 2em; + margin-left: .25em; + opacity: .4; + align-self: flex-start; + } + } + + .form-notifications { + &.info { + background-color: @form-info-bg-color; + } + + &.error { + background-color: @form-error-bg-color; + } + + &.warning { + background-color: @form-warning-bg-color; + } + } + + .form-description { + background-color: @light-text-bg-color; + } + + .errors { + list-style: none; + display: block; + width: 100%; + margin: 0 0 0 15em; + padding: 0; + + & > li { + margin: 0.5em; + color: #f56; + } + } +} + +form.icinga-form .form-info { + color: @text-color-light; + font-size: @font-size-small; + list-style: none; + padding-left: 0; +} + +// Placeholder styles + +.icinga-controls { + input::placeholder { + color: @disabled-gray; + font-style: italic; + opacity: 1; + } + + input:-ms-input-placeholder { + color: @disabled-gray; + font-style: italic; + opacity: 1; + } +} + +// Specific form styles + +.search.inline { + display: inline-block; +} + +/* Flyover form styles */ + +.flyover-content form:not(.inline):not([role="search"]) { + width: auto; +} + +.flyover-content .control-label-group { + text-align: left; +} + +.theme-mode-input { + display: none; + + &:checked + img { + border-color: @icinga-blue; + border-radius: .25em; + } + + & + img { + margin: 0 auto; + border: .25em solid transparent; + display: block; + width: 6em; + overflow: hidden; + box-shadow: 0 0 .25em 0 rgba(0,0,0,.4); + } + + &[disabled] ~ img, + &[disabled] ~ span { + opacity: .25; + } + + & ~ span { + display: block; + text-align: center; + } +} + +#layout.minimal-layout .icinga-form { + .theme-mode { + .control-label-group { + width: 100%; + margin-bottom: .5em; + } + + label:first-of-type { + margin-left: auto; + } + } +} diff --git a/public/css/icinga/grid.less b/public/css/icinga/grid.less new file mode 100644 index 0000000..e061bc8 --- /dev/null +++ b/public/css/icinga/grid.less @@ -0,0 +1,47 @@ +/*! Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +.grid { + .clearfix(); +} + +[class^="col-"], +[class*=" col-"] { + float: left; + // Fix that empty columns don't consume their width + min-height: 1px; +} + +.controls { + [class^="col-"], + [class*=" col-"] { + padding: @vertical-padding / 2 0; + } +} + +.col-1-2 { + width: 50%; +} + +.col-1-3 { + width: 33.33%; +} + +.col-2-3 { + width: 66.66%; +} + +.col-3-3 { + width: 100%; +} + +// TODO(el): Set proper breakpoints +#layout.twocols, +#layout.compact-layout, +#layout.minimal-layout, +#layout.poor-layout { + [class^="col-"], + [class*=" col-"] { + float: none; + width: 100%; + } +} diff --git a/public/css/icinga/health.less b/public/css/icinga/health.less new file mode 100644 index 0000000..50cc11a --- /dev/null +++ b/public/css/icinga/health.less @@ -0,0 +1,69 @@ +// Style + +.app-health { + header { + color: @text-color-light; + + span { + color: @text-color; + } + } + + span { + &.state-ok { + background-color: @color-ok; + } + + &.state-warning { + background-color: @color-warning; + } + + &.state-critical { + background-color: @color-critical; + } + + &.state-unknown { + background-color: @color-unknown; + } + } + + a { + font-weight: bold; + } + + tbody tr, tr.active { + border: none; + } + + tr:not(:last-child) td { + border: 0 solid; + border-color: @gray-light; + border-bottom-width: 1px; + } + + section { + color: @text-color-light; + font-family: @font-family-fixed; + } +} + +// Layout + +.app-health { + th { + width: 2.5em; + padding: .5em 1em 0 .5em; + vertical-align: top; + } + + td { + padding: .5em 0; + } + + section { + margin-top: .25em; + height: 3em; + overflow: hidden; + word-break: break-word; + } +} diff --git a/public/css/icinga/layout-structure.less b/public/css/icinga/layout-structure.less new file mode 100644 index 0000000..b1ca8e6 --- /dev/null +++ b/public/css/icinga/layout-structure.less @@ -0,0 +1,167 @@ +/*! Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +html { + height: 100%; + font-family: 'default-layout'; +} + +body { + height: 100%; + overflow: hidden; +} + +#layout { + height: 100%; + display: flex; + flex-direction: column; +} + +#content-wrapper { + flex: 1 1 auto; + display: flex; + height: 0; + +} + +#sidebar { + width: 16em; + display: flex; + flex-direction: column; + position: relative; + z-index: 2; +} + +#layout:not(.minimal-layout) #sidebar:after { + content: ""; + display: block; + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 1em; + background: linear-gradient(to left, rgba(0,0,0,.1), rgba(0,0,0,0)); + z-index: 0; + pointer-events: none; +} + +#main { + flex: 1; + display: flex; + z-index: 1; +} + +.iframe { + #header, #sidebar { + display: none; + } +} + +#responsive-debug { + font-size: 0.9em; + font-family: Courier new, monospace; + padding: 0.5em; + width: 25em; + color: white; + height: 10em; + display: none; + position: fixed; + bottom: 0.5em; + right: 2em; + overflow: hidden; + z-index: 1000; + background: #333; + border-radius: 0.5em; + opacity: 0.9; +} + +#layout.minimal-layout #responsive-debug { + font-size: 0.6em; +} + +#layout.poor-layout #responsive-debug { + font-size: 0.7em; +} + +#layout.compact-layout #responsive-debug { + font-size: 0.8em; +} + +#layout.wide-layout #responsive-debug { + font-size: 1em; +} + +/** Fullscreen layout **/ +#layout.fullscreen-layout { + #sidebar { + display: none; + } + + .container .controls { + padding: 0; + } + + .controls > ul.tabs { + margin-top: 0; + height: 1.5em; + font-size: 0.75em; + padding: 0.2em 0 0; + } + + .controls > ul.tabs > li > a { + line-height: 1.5em; + } +} + +.controls-separated, +.container .controls.separated { + box-shadow: 0 3px 4px -4px rgba(0, 0, 0, 0.2); +// border-bottom: 1px solid @gray-lightest; + padding-bottom: @horizontal-padding / 2 +} + +.hbox { + display: inline-block; +} + +.hbox-item { + display: inline-block; + vertical-align: top; + margin-top: 0.5em; + margin-bottom: 0.25em; + margin-left: 1em; + margin-right: 1em; +} + +.hbox-spacer { + display: inline-block; + vertical-align: top; + width: 2em; +} + +/* + * Class to hide content from users but available for screen reader + * Based on: https://cloudfour.com/thinks/see-no-evil-hidden-content-and-accessibility/ + */ +.sr-only { + border: 0; + clip: rect(0 0 0 0); + clip-path: polygon(0px 0px, 0px 0px, 0px 0px); + -webkit-clip-path: polygon(0px 0px, 0px 0px, 0px 0px); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: fixed; // absolute causes view port glitches in chrome (#4310) + width: 1px; + white-space: nowrap; +} + +// Hide non-javascript elements if javascript is enabled +html.js *.no-js { + .sr-only; +} + +// Hide javascript elements if javascript is disabled +html.no-js *.js { + .sr-only; +} diff --git a/public/css/icinga/layout.less b/public/css/icinga/layout.less new file mode 100644 index 0000000..c37da79 --- /dev/null +++ b/public/css/icinga/layout.less @@ -0,0 +1,379 @@ +/*! Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +#footer { + bottom: 0; + right: 0; + left: 12em; + position: fixed; + z-index: 999; +} + +#layout.minimal-layout #footer { + left: 0; +} + +.sidebar-collapsed #footer { + left: 3em; +} + +#guest-error { + background-color: @icinga-blue; + height: 100%; + overflow: auto; +} + +#guest-error #icinga-logo { + .fadein(); +} + +#guest-error-message { + .fadein(); + color: @body-bg-color; + font-size: 2em; +} + +#header, +#login, +#content-wrapper { + font-size: @font-size; + line-height: @line-height; +} + +#header-logo-container { + background: @menu-bg-color; + height: 6em; + padding: 1.25em; + width: 16em; +} + +#header-logo, +#mobile-menu-logo { + background-image: url('../img/icinga-logo.svg'); + background-position: center center; + background-repeat: no-repeat; + background-size: contain; + display: block; + height: 100%; + width: 100%; + + &:focus { + opacity: .6; + outline: none; + } +} + +#mobile-menu-logo { + width: 50%; + float: left; + height: 2em; + margin-top: .25em; + background-position: .75em center; +} + +#mobile-menu-toggle .icon-cancel { + display: none; +} + +#icinga-logo { + background-image: url('../img/icinga-logo-big.svg'); + background-position: center bottom; + background-repeat: no-repeat; + background-size: contain; // Does not work in IE < 10 + height: 177px; + margin-bottom: 2em; + width: 100%; + + &.invert { + background-image: url('../img/icinga-logo-big-dark.svg'); + } +} + +#layout { + background-color: @body-bg-color; + color: @text-color; + font-family: @font-family; +} + +#login { + overflow: auto; +} + +@gutter: 1em; + +// x-column-layout +#main { + .clearfix(); + + & > .container { + width: 0; + overflow: auto; + flex: 1 1 auto; + display: flex; + flex-direction: column; + + &:empty { + display: none; + } + + & > .content { + flex: 1 1 auto; + overflow: auto; + } + + & > .controls { + > .tabs { + // Remove gutter for tabs + margin-left: -1 * @gutter; + margin-right: -1 * @gutter; + height: 2.5em; + } + + .tabs:first-child:not(:last-child) { + margin-bottom: .5em; + } + } + } +} + +// Not part of the above to relax specificity and to allow modules adjust this +:not(.dashboard) > .container { + & > .controls { + padding-left: @gutter; + padding-right: @gutter; + } + + & > .content { + padding: @gutter; + } +} + +// Mobile menu +#layout.minimal-layout #sidebar { + background-color: @menu-bg-color; +} + +#mobile-menu-toggle { + color: @menu-color; + text-align: right; + + > button { + background: none; + border: none; + font-size: 2em; + padding: 0 .5em; + line-height: 2; + + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + appearance: none; + } + + i:before { + margin-right: 0; + } +} + +.container, +.error-message, +.modal-window { + // Don't outline containers and error messages when focused because they receive focus for accessibility only + // programmatically + outline: none; +} + +.controls { + > .tabs { + overflow: hidden; + } +} + +// Dashboard grid + +.dashboard { + letter-spacing: -0.417em; + + > .container { + display: inline-block; + letter-spacing: normal; + vertical-align: top; + // Column width controlled by #layout + width: 100%; + + &:last-of-type { + // See reponsive.less for gutters + padding-right: 0; + } + } +} + +// Notification styles + +#notifications { + // Reset defaults + list-style-type: none; + margin: 0; + padding: 0; +} + +#notifications > li { + color: @text-color; + display: block; + line-height: 2.5em; + border-left: .5em solid @gray-light; + background: @body-bg-color; + margin-bottom: 1px; + box-shadow: 0 0 1em 0 rgba(0,0,0,0.25); + + .icon { + padding: .5em; + width: 3em; + text-align: center; + } + + &:hover { + cursor: pointer; + } + + &.error { + border-color: @color-notification-error; + background: @color-notification-error; + color: @text-color-on-icinga-blue; + + .icon { + color: @text-color-on-icinga-blue; + } + } + + &.info { + border-color: @color-notification-info; + + .icon { + color: @color-notification-info; + } + } + + &.success { + border-color: @color-notification-success; + + .icon { + color: @color-notification-success; + } + } + + &.warning { + border-color: @color-notification-warning; + background: @color-notification-warning; + color: @text-color-inverted; + + .icon { + color: @text-color-inverted; + } + } +} + +// Collapsed sidebar +#layout:not(.minimal-layout).sidebar-collapsed { + #header-logo-container { + height: 3em; + padding: 0.25em 0.125em; + width: 4em; + } + + #header-logo { + background-image: url('../img/icinga-logo-compact.svg'); + } + + #sidebar { + width: 4em; + } + + #open-sidebar { + display: inline; + } + + #close-sidebar { + display: none; + } + + #menu { + .nav-level-1 { + > .badge-nav-item > a { + position: relative; + + > .badge { + position: absolute; + right: .5em; + bottom: .25em; + font-size: 75%; + overflow: hidden; + text-overflow: ellipsis; + max-width: 4em; + } + } + + > .nav-item.active > a > .badge { + display: unset; + } + } + + img.icon { + margin: 0 1.25em -.25em 0.25em; + font-size: 1.5em; + } + + .nav-item { + white-space: nowrap; + } + + .nav-item.no-icon > a { + padding-left: .75em; + } + + .nav-level-1 > .nav-item i { + font-size: 1.5em; + margin-right: .5em; + } + + > .search-control { + height: 3.333em; + } + } + + #search { + padding-left: 3.75em; + } + + #search:focus { + background-color: @menu-bg-color; + border-radius: 0 .25em .25em 0; + box-shadow: 0 0 .25em 0 rgba(0, 0, 0, .2); + color: @menu-color; + width: 20em; + position: fixed; + z-index: 1; + } + + .search-input { + font-size: 1.25em; + padding-right: .625em; + } + + .search-reset { + display: none; + } + + .skip-links { + a, button { + width: 20em; + } + } +} + +@light-mode: { + #header-logo, + #mobile-menu-logo, + #about .icinga-logo { + filter: brightness(0.415) sepia(1) ~"saturate(0.1)" hue-rotate(144deg); + } +}; diff --git a/public/css/icinga/login-orbs.less b/public/css/icinga/login-orbs.less new file mode 100644 index 0000000..b0426dd --- /dev/null +++ b/public/css/icinga/login-orbs.less @@ -0,0 +1,104 @@ +/*! Icinga Web 2 | (c) 2021 Icinga GmbH | GPLv2+ */ + +#login { + background-image: none; + + .login-form { + background: none; + box-shadow: none; + } +} + +.orb { + display: block; + position: absolute; + pointer-events: none; + transform-origin: center center; +} + +.orb img { + height: auto; + width: 100%; +} + +#orb-analytics { + top: -19%; + width: 25%; + left: 22.5%; + z-index: 0; +} + +#orb-analytics img { + opacity: .2; +} + +#orb-automation { + bottom: -6%; + width: 60%; + left: 7%; + z-index: 0; + margin-left: -30%; + margin-bottom: -30%; +} + +#orb-automation img { + opacity: .75; +} + +#orb-cloud { + top: -6%; + width: 25%; + right: 4%; + z-index: 0; + margin-right: -12.5%; + margin-top: -12.5%; +} + +#orb-cloud img { + opacity: .4; +} + +#orb-notifactions { + top: 7%; + right: 46%; + width: 10%; + margin: -5%; +} + +#orb-notifactions img { + opacity: .5; +} + +#orb-metrics { + left: 5%; + top: 20%; + width: 35%; + margin: -17.5%; +} + +#orb-metrics img { + opacity: .5; +} + +#orb-icinga { + left: 50%; + top: 50%; + margin-top: -38.5em; + margin-left: -38em; + width: 75em; + z-index: 0; +} + +#orb-icinga img { + opacity: .8; +} + +#orb-infrastructure { + top: -36%; + left: -15%; + width: 30%; +} + +#orb-infrastructure img { + opacity: .6; +} diff --git a/public/css/icinga/login.less b/public/css/icinga/login.less new file mode 100644 index 0000000..b37dbd8 --- /dev/null +++ b/public/css/icinga/login.less @@ -0,0 +1,183 @@ +/*! Icinga Web 2 | (c) 2013 Icinga Development Team | GPLv2+ */ + +// Login page styles + +#login { + height: 100%; + background-color: @menu-bg-color; + background-image: url(../img/icingaweb2-background-orbs.jpg); + background-repeat: no-repeat; + background-size: cover; + text-align: center; + display: flex; + justify-content: center; + align-items: center; + + .login-form { + width: 36em; + position: relative; + z-index: 10; + padding: 2em 6em; + background-color: @login-box-background; + .box-shadow(0, 0, 1em, 1em, @login-box-background); + } + + #icinga-logo { + width: 100%; + max-width: 18em; + height: auto; + margin: 0 auto 2em auto; + + &:after { + content: ""; + display: block; + width: 100%; + padding-bottom: 35%; + } + } + + .errors, + .form-errors { + list-style-type: none; + padding: 0.5em; + } + + .errors { + background-color: @color-critical; + color: white; + } + + .form-errors { + margin-top: 0; + padding: 0; + } + + .form-errors, + .control-group { + &:not(:last-child) { + margin-bottom: 1em; + } + } + + input[type=password], + input[type=text] { + display: block; + height: 2.5em; + margin: 0; + transition: none; + width: 100%; + + &:focus { + .rounded-corners(3px); + border-radius: 0; + padding-bottom: 3px; + } + } + + input[type="submit"]:focus { + outline: 3px solid; + outline-color: @icinga-blue-light; + } + + input[type=submit] { + border-radius: .25em; + background: @icinga-secondary; + color: white; + border: none; + height: 2.5em; + margin: 0; + width: 100%; + + &:hover { + background-color: @icinga-secondary-dark; + } + } + + .config-note { + background-color: @color-critical; + margin: 0 auto 2em auto; // Center horizontally w/ bottom margin + max-width: 50%; + min-width: 24em; + padding: 1em; + + a { + color: @text-color-inverted; + font-weight: bold; + } + } + + .remember-me-box { + display: flex; + align-items: flex-start; + + .toggle-switch { + margin-right: 1em; + } + + .control-info { + line-height: 1.5; + margin-left: .5em; + } + } +} + +#social { + position: fixed; + right: 1em; bottom: 1em; + letter-spacing: -.417em; + margin: 0; + + > * { + letter-spacing: normal; + } + + > li { + display: inline-block; + + a { + display: block; + text-decoration: none; + -webkit-transform: scale(1, 1); + -moz-transform: scale(1, 1); + -ms-transform: scale(1, 1); + transform: scale(1, 1); + } + + i { + font-size: 3em; + color: white; + text-shadow: 0 0 .5em #01507B; + } + } + + > li a:hover { + -webkit-transform: scale(1.2, 1.2); + -moz-transform: scale(1.2, 1.2); + -ms-transform: scale(1.2, 1.2); + transform: scale(1.2, 1.2); + } + + li:not(:last-child) { + margin-right: 2em; + } +} + +#login-footer { + padding: .5em 0; + + p { + margin-bottom: 0; + } + + a { + text-decoration: underline; + + &:hover { + opacity: .8; + } + } +} + +.orb { + display: none; +} diff --git a/public/css/icinga/main.less b/public/css/icinga/main.less new file mode 100644 index 0000000..11dfa30 --- /dev/null +++ b/public/css/icinga/main.less @@ -0,0 +1,459 @@ +/*! Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +// Url for static ipl assets +@iplWebAssets: "../lib/icinga/icinga-php-library"; + +// Width for the name column--th--of name-value-table +@name-value-table-name-width: 38/3em; + +.action-link { + color: @icinga-blue; +} + +.error-message { + font-weight: @font-weight-bold; +} + +.error-reason { + margin-top: 4em; +} + +.large-icon { + font-size: 200%; +} + +.content-centered { + margin: 0 auto; + text-align: center; +} + +.icon-col { + text-align: center; + width: 1em; +} + +.preformatted { + font-family: @font-family-fixed; + white-space: pre-wrap; +} + +.markdown { + > * { + margin-left: 0; + margin-right: 0; + } + + > *:last-child { + margin-bottom: 0; + } + + img { + max-width: 100%; + height: auto; + } + + a { + border-bottom: 1px @text-color-light dotted; + + &:hover, &:focus { + border-bottom: 1px @text-color solid; + text-decoration: none; + } + + img { + max-width: 32em; + } + + &.with-thumbnail { + img { + padding: 1px; + } + + &:hover, &:focus { + img { + padding: 0; + } + } + } + } + + table { + border-collapse: collapse; + + th { + text-align: left; + background-color: @gray-lighter; + } + + &, th, td { + border: 1px solid @gray-light; + } + } +} + +.no-wrap { + white-space: nowrap; +} + +.pull-right { + float: right; +} + +.text-right { + text-align: right; +} + +.user-avatar { + height: 16px; + width: 16px; +} + +.v-center { + > * { + vertical-align: middle; + } +} + +.section { + margin-bottom: 2em; +} + +a:hover > .icon-cancel { + color: @color-critical; +} + +.icon-stateful { + .fg-stateful(); +} + +// Link styles + +.button-link { + .action-link(); + .rounded-corners(3px); + + background: @low-sat-blue; + display: inline-block; + padding: 0.25em 0.5em; + + &:hover { + background: @low-sat-blue-dark; + text-decoration: none; + } +} + +// List styles + +.comment-list { + margin: 0; + + > dt { + border-bottom: 1px solid @gray-lighter; + margin-bottom: 0.25em; + + &:hover { + background-color: @gray-lightest; + + > .remove-action button:not(.spinner.active) { + visibility: visible; + } + } + + > .remove-action button:not(.spinner.active) { + visibility: hidden; + } + } + + > dd { + margin: 0 0 1em 0; + } +} + +.comment-time { + color: @text-color-light; + font-size: @font-size-small; +} + +.name-value-list { + > dd { + // Reset default margin + margin: 0; + } + + > dt { + color: @text-color-light; + font-size: @font-size-small; + } +} + +// Table styles + +.common-table { + width: 100%; + + td, th { + padding-top: 1em; + } + + td { + padding-bottom: 1em; + } + + th { + text-align: left; + padding-bottom: 0.5em; + } + + thead { + border-bottom: 1px solid @gray-light; + } + + tbody tr { + border-bottom: 1px solid @gray-lightest; + border-left: 5px solid transparent; + + &:last-child { + border-bottom: none; + } + } + + tr[href].active { + background-color: @tr-active-color; + border-left-color: @icinga-blue; + } + + tr[href]:hover { + background-color: @tr-hover-color; + cursor: pointer; + } +} + +.name-value-table { + width: 100%; +} + +.name-value-table > caption { + margin-top: .5em; + text-align: left; + font-weight: bold; +} + +.name-value-table > tbody > tr > th { + color: @text-color-light; + // Reset default font-weight + font-weight: normal; + padding-left: 0; + text-align: left; + vertical-align: top; + width: @name-value-table-name-width; +} + +/* Styles for centering content of unknown width and height both horizontally and vertically + * + * Example markup: + * <div class="centered-ghost"> + * <div class="centered-content"> + * <p>I'm centered.</p> + * </div> + * </div> + */ + +.centered-content { + display: inline-block; + vertical-align: middle; +} + +.centered-ghost { + height: 100%; + text-align: center; + letter-spacing: -0.417em; // Remove gap between content and ghost +} + +.centered-ghost > * { + letter-spacing: normal; +} + +.centered-ghost:after { + content: ''; + display: inline-block; + height: 100%; + vertical-align: middle; +} + +// Responsive iFrames + +.iframe-container { + position: relative; + height: 0; + overflow: hidden; + padding-bottom: 75%; + width: 100%; + + & > iframe { + position: absolute; + left: 0; + top: 0; + height: 100%; + width: 100%; + } +} + +// Collapsible Control +#collapsible-control-ghost { + display: none; +} + +.collapsible + .collapsible-control { + position: relative; + z-index: 1; + + button { + .rounded-corners(50%); + + float: right; + width: 2em; + height: 2em; + padding: 0; + margin-top: -1em; + margin-right: .25em; + + background: @gray-lighter; + color: @gray; + border: none; + -webkit-box-shadow: 0 0 1/3em rgba(0,0,0,.3); + -moz-box-shadow: 0 0 1/3em rgba(0,0,0,.3); + box-shadow: 0 0 1/3em rgba(0,0,0,.3); + + &:hover { + background: @gray-light; + } + } + + button i:before { + margin-right: 0; + } +} + +details.collapsible > summary { + &::marker, + &::-webkit-details-marker { + display: none; + } +} + +.collapsible[data-can-collapse]:not(.collapsed) + .collapsible-control button, +.collapsible[data-can-collapse]:not(.collapsed) > .collapsible-control, +details.collapsible[open] + .collapsible-control button, +details.collapsible[open] > .collapsible-control { + i.expand-icon { + display: none; + } + + i.collapse-icon { + display: inline; + } +} + +.collapsible.collapsed + .collapsible-control button, +.collapsible.collapsed > .collapsible-control, +details.collapsible:not([open]) + .collapsible-control button, +details.collapsible:not([open]) > .collapsible-control { + i.expand-icon { + display: inline; + } + + i.collapse-icon { + display: none; + } +} + +// Collapsibles + +.collapsible.collapsed:not(details) { + overflow: hidden; +} + +.collapsible.collapsed:not([data-toggle-element], details) { + position: relative; + + &:after { + content: ""; + display: block; + height: 2em; + background: linear-gradient(@body-bg-color-transparent, @body-bg-color); + position: absolute; + bottom: 0; + left: 0; + right: 0; + z-index: 1; + + opacity: 1; + transition: opacity 2s 1s linear; + } +} + +.role-memberships { + letter-spacing: -0.417em; + list-style-type: none; + margin: 0; + padding: 0; + + > li { + display: inline-block; + letter-spacing: normal; + margin: 0; + padding: 0 0.25em 0 0; + + &:last-child { + padding-right: 0; + } + } +} + +.module-dependencies { + .unmet-dependencies { + background-color: @color-warning; + color: @text-color-on-icinga-blue; + padding: .25em .5em; + margin-left: -.5em; + } + + .name-value-table { + > caption { + font-weight: normal; + color: @text-color-light; + } + + > tbody > tr > th { + font-weight: bold; + color: @text-color; + } + + .missing { + color: @color-critical; + font-weight: bold; + } + + td { + white-space: nowrap; + + &.or-separator { + width: 100%; + transform: translate(0, 50%); + padding-left: 3em; + + &::before { + content: ""; + position: absolute; + height: 1.5em; + width: 1.5em; + left: 0.5em; + border-top: 3px solid @gray; + border-right: 3px solid @gray; + border-top-right-radius: .50em; + transform: rotate(45deg); + } + } + } + } +} diff --git a/public/css/icinga/menu.less b/public/css/icinga/menu.less new file mode 100644 index 0000000..98650a2 --- /dev/null +++ b/public/css/icinga/menu.less @@ -0,0 +1,554 @@ +/*! Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +#menu [class^="icon-"], +#menu [class*=" icon-"] { + &:before { + width: 1.5em; + } +} + +@icon-width: 1.7em; // 1.5em width + 0.2em right margin + +#menu { + background-color: @menu-bg-color; + width: 100%; + flex: 1; + overflow: auto; + overflow-x: hidden; +} + +#menu .nav-item { + vertical-align: middle; + + > a { + position: relative; + + &:focus { + outline: none; + } + + &:hover { + text-decoration: none; + } + } +} + +#layout:not(.sidebar-collapsed) #menu .nav-item > a:first-of-type { + // Respect overflowing content + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +#layout:not(.minimal-layout).sidebar-collapsed #menu .nav-level-1 > .nav-item { + overflow: hidden; +} + +#layout:not(.minimal-layout).sidebar-collapsed #menu .nav-level-1 > .nav-item > a { + // Clip overflowing content + overflow: hidden; + width: 4em; +} + +#menu .nav-level-1 > .nav-item { + line-height: 2.167em; // 26 px + color: @menu-color; + + &.active { + color: @menu-active-color; + + > a > .badge { + display: none; + } + + background-color: @menu-active-bg-color; + } + + &.no-icon > a { + padding-left: @icon-width + .75em; + } + + > a { + padding: 0.5em 0.5em 0.5em .75em; + } + + &.active:not(.selected) > a:focus, + &.active:not(.selected) > a:hover { + background-color: @menu-active-hover-bg-color; + } + + &:not(.selected) > a:hover, + &:not(.selected) > a:focus { + background-color: @menu-hover-bg-color; + } + + // Balance icon weight for non active menu items + &:not(.active) > a > i { + opacity: .8; + } + + & > a > .icon-letter:before { + content: attr(data-letter); + font-family: @font-family; + font-weight: 800; + text-transform: uppercase; + } +} + +#menu ul:not(.nav-level-2) > .selected > a { + background-color: @menu-highlight-color; + color: @text-color-inverted; + + &:focus { + background-color: @menu-highlight-hover-bg-color; + } + + &:after { + .transform(rotate(45deg)); + + position: absolute; + right: -.75em; + + background-color: @body-bg-color; + box-shadow: 0 0 1em 0 rgba(0,0,0,0.6); + content: ""; + display: block; + height: 1.25em; + margin-top: -1.75em; + width: 1.25em; + } +} + +#menu .nav-level-2 > .nav-item { + // Collapse menu by default + display: none; + line-height: 1.833em; // 22px + + > a { + color: @menu-2ndlvl-color; + font-size: @font-size-small; + padding: 0.364em 0.545em 0.364em 0.545em; + + &:first-of-type { + padding-left: (@icon-width + .75em)/@font-size-small; + } + } + + &.active { + overflow: hidden; + position: relative; + } + + // Little caret on active level-2 item + &.active:after { + .transform(rotate(45deg)); + + background-color: @body-bg-color; + box-shadow: 0 0 1em 0 rgba(0,0,0,.6); + content: ""; + display: block; + height: 1.25em; + width: 1.25em; + position: absolute; + top: .5em; + right: -.75em; + z-index: 3; + } + + &.active > a { + color: @menu-2ndlvl-active-color; + background-color: @menu-2ndlvl-active-bg-color; + + &:focus { + &:first-of-type, + &:first-of-type ~ a { + color: @menu-2ndlvl-active-hover-color; + background-color: @menu-2ndlvl-active-hover-bg-color; + } + } + } +} + +.no-js #menu .nav-level-2 > .nav-item { + // Expand menu if JavaScript is disabled + display: block; +} + +#layout:not(.sidebar-collapsed) { + #menu .nav-level-1 > .nav-item { + &.active { + .nav-level-2 > li { + // Expand menu if active + display: block; + } + } + } +} + +#menu img.icon { + line-height: 1; + margin: 0 0.5em -.05em 0.25em; + width: 1em; +} + +#menu img[src*="/img/icons/"] { + &:not([src$="tux.png"]):not([src$="win.png"]):not([src$="_white.png"]) { + -webkit-filter: invert(100%); + -moz-filter: invert(100%); + -ms-filter: invert(100%); + filter: invert(100%); + } +} + +.nav-item:hover img.icon { + opacity: .6; +} + +#menu input.search { + background: transparent url('../img/icons/search_white.png') no-repeat 1em center; + background-size: 1em auto; + border: none; + color: @menu-color; + line-height: 2.167em; + padding: .25em; + padding-left: @icon-width + .75em; + width: 100%; + + &:focus::placeholder { + color: @menu-color; + } + &:focus::-ms-input-placeholder { + color: @menu-color; + } + + &.active { + background-color: @menu-active-bg-color; + } + + &:hover, + &:focus { + background-color: @menu-search-hover-bg-color; + } +} + +// Badge offset correction +#menu > nav > .nav-level-1 > .badge-nav-item > a > .badge { + margin-top: 0.2em; +} + +#menu .nav-level-2 > .badge-nav-item > a > .badge { + margin-top: 0.2em; + margin-right: .5em +} + +// Hovered menu +#layout:not(.minimal-layout).sidebar-collapsed #menu .nav-level-1 > .nav-item.hover, +#layout:not(.minimal-layout) #menu .nav-level-1 > .nav-item:not(.active).hover { + > .nav-level-2 { + background-color: @menu-flyout-bg-color; + border: 1px solid; + border-color: @gray-light; + border-radius: .25em; + box-shadow: 0 0 1em 0 rgba(0,0,0,.3); + padding: @vertical-padding 0; + width: 14em; + position: fixed; + z-index: 1; + + &:after { + .transform(rotate(45deg)); + + background-color: @body-bg-color; + border-bottom: 1px solid @gray-light; + border-left: 1px solid @gray-light; + content: ""; + display: block; + height: 1.1em; + width: 1.1em; + position: absolute; + top: 1em; + left: -.6em; + z-index: -1; + } + > .nav-item { + display: block; + padding-left: 0; + position: relative; + + > a { + color: @menu-flyout-color; + + &:first-of-type { + padding-left: 1.5em; + } + } + + &:not(.active) { + a:hover, a:focus { + &:first-of-type, + &:first-of-type ~ a { + background-color: @menu-2ndlvl-highlight-bg-color; + } + } + } + + &.active > a { + color: @menu-color; + } + + // Hide activity caret when displayed as flyout + &:after { + display: none; + } + } + } + + > a > .badge { + display: none; + } + + img.icon { + opacity: .6; + } +} + +#layout:not(.minimal-layout) #menu .nav-level-1 > .nav-item:not(.active).hover { + > .nav-level-2 { + // Position relative to parent + margin-left: 16em; + margin-top: -3.167em; + } +} + +#layout:not(.minimal-layout).sidebar-collapsed #menu .nav-level-1 > .nav-item.hover { + > .nav-level-2 { + // Position relative to parent + margin-left: 4em; + margin-top: -3.333em; + + > .badge-nav-item { + display: flex; + + a:first-of-type { + flex: 1 1 auto; + width: 0; + } + + a:first-of-type ~ a { + flex: 0; + width: auto; + + &:hover, + &:focus { + .badge { + opacity: .6; + } + } + } + } + } +} + +// Accessibility skip links +.skip-links { + position: relative; + font-size: 1/.75em; + + ul { + list-style-type: none; + margin: 0; + padding: 0; + li { + display: block; + a, button[type="submit"] { + background-color: @body-bg-color; + border: none; + left: -999px; + padding: @vertical-padding @horizontal-padding; + position: absolute; + width: 100%; + z-index: 1; + &:focus { + left: 0; + outline-offset: -3px; + } + } + button[type="submit"] { + text-align: left; + } + } + } +} + +#sidebar.expanded { + #mobile-menu-toggle .icon-menu { + display: none; + } + + #mobile-menu-toggle .icon-cancel { + display: inline-block; + } +} + +.search-control { + position: relative; +} + +.search-input:focus ~ .search-reset:hover { + background-color: @menu-active-hover-bg-color; +} + +.search-reset { + background: none; + border: 0; + color: @menu-color; + cursor: pointer; + display: none; + height: 100%; + padding: 0; + user-select: none; + position: absolute; + right: 0; + top: 0; + + &:focus, + &:hover { + background-color: @menu-search-hover-bg-color; + outline: none; + } +} + +// Override forms.less +input[type=text].search-input { + padding-right: 1.4em; + text-overflow: ellipsis; + transition: none; +} + +.search-input:focus:-moz-placeholder { // FF 18- + color: @gray-light; +} + +.search-input:focus::-moz-placeholder { // FF 19+ + color: @gray-light; +} + +.search-input:focus:-ms-input-placeholder { + color: @gray-light; +} + +.search-input:focus::-webkit-input-placeholder { + color: @gray-light; +} + +.search-input ~ .search-reset { + opacity: 0; +} + +.search-input:valid ~ .search-reset { + display: block; + opacity: 1; +} + +.search-input:invalid, +.search-input:-moz-submit-invalid, +.search-input:-moz-ui-invalid { + // Disable glow + box-shadow: none; +} + +// Toggle sidebar button +#toggle-sidebar { + font-size: 1/.75em; + + // Reset button styles + background: none; + border: none; + padding: 0; + color: @text-color-light; + position: absolute; + bottom: 0; + right: 0; + z-index: 3; + line-height: 2; + + i { + background-color: @body-bg-color; + border-radius: .25em 0 0 .25em; + font-size: 1.125em; + width: 2em; + } + + &:focus { + outline: none; + } + + &:hover, &:focus { + i { + color: @menu-highlight-color; + } + } +} + +html.no-js #toggle-sidebar { + display: none; +} + +#layout.minimal-layout #toggle-sidebar { + display: none; +} + +#open-sidebar { + display: none; +} + +#open-sidebar:before, +#close-sidebar:before { + width: 1.4em; + margin-right: 0; +} + +#layout:not(.sidebar-collapsed) #menu .nav-level-1 > .nav-item.active .nav-level-2 > li { + &.nav-item:not(.badge-nav-item) { + &:not(.selected):not(.active) a:hover, + &:not(.selected):not(.active) a:focus { + background-color: @menu-2ndlvl-highlight-bg-color; + } + } +} + +#layout:not(.sidebar-collapsed) #menu .nav-level-1 > .nav-item.active .nav-level-2 > li, +#layout:not(.sidebar-collapsed) #menu .nav-level-1 > .nav-item:not(.active).hover .nav-level-2 > li { + &.badge-nav-item { + display: flex; + } + + &.badge-nav-item a:first-of-type { + flex: 1 1 auto; + width: 0; + } + + &.badge-nav-item a:first-of-type ~ a { + flex: 0; + width: auto; + + &:hover, + &:focus { + .badge { + opacity: .6; + } + } + } +} + +#layout:not(.sidebar-collapsed) #menu .nav-level-1 > .nav-item.active .nav-level-2 > li { + &.badge-nav-item:not(.selected) { + a:hover, + a:focus { + &:first-of-type, + &:first-of-type ~ a { + background-color: @menu-2ndlvl-highlight-bg-color; + } + } + } +} diff --git a/public/css/icinga/mixins.less b/public/css/icinga/mixins.less new file mode 100644 index 0000000..6c55512 --- /dev/null +++ b/public/css/icinga/mixins.less @@ -0,0 +1,201 @@ +/*! Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +.button( + @background-color: @body-bg-color, + @border-font-color: @icinga-blue, + @color-dark: @icinga-blue-dark +) { + .rounded-corners(3px); + + display: inline-flex; + align-items: baseline; + background-color: @background-color; + border: 2px solid @border-font-color; + color: @border-font-color; + cursor: pointer; + line-height: normal; + outline: none; + padding: ~"calc(@{vertical-padding} - 2px)" @horizontal-padding; + + @duration: 0.2s; + // The trailing semicolon is needed to be able to pass this as a css list + .transition(background @duration, border @duration ease, color @duration ease;); + + &:focus, + &:hover, + &.btn-primary { + background-color: @border-font-color; + color: @background-color; + } + + &.btn-primary:focus, + &.btn-primary:hover { + background-color: @color-dark; + border-color: @color-dark; + color: @background-color; + } + + &:hover { + text-decoration: none; + } +} + +.clearfix { + &:after { + content: ""; + clear: both; + display: table; + } +} + +.opacity(@opacity: 0.6) { + opacity: @opacity; +} + +.transform(@transform) { + -webkit-transform: @transform; + -moz-transform: @transform; + -ms-transform: @transform; + -o-transform: @transform; + transform: @transform; +} + +.user-select(@user-select) { + -webkit-user-select: @user-select; + -moz-user-select: @user-select; + -ms-user-select: @user-select; + user-select: @user-select; +} + +.transition (@transition) { + -webkit-transition: @transition; + -moz-transition: @transition; + -o-transition: @transition; + transition: @transition; +} + +// Fadein animation + +/* Chrome, WebKit */ +@-webkit-keyframes fadein { + from { opacity: 0; } + to { opacity: 1; } +} + +/* FF < 16 */ +@-moz-keyframes fadein { + from { opacity: 0; } + to { opacity: 1; } +} + +/* Opera < 12.1 */ +@-o-keyframes fadein { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes fadein { + from { opacity: 0; } + to { opacity: 1; } +} + +.fadein() { + opacity: 0; + + -webkit-animation: fadein 2s ease-in; /* Chrome, WebKit */ + -moz-animation: fadein 2s ease-in; /* FF < 16 */ + -o-animation: fadein 2s ease-in; /* Opera < 12.1 */ + animation: fadein 2s ease-in; + + // Make sure that after animation is done we remain at the last keyframe value (opacity: 1) + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + -o-animation-fill-mode: forwards; + animation-fill-mode: forwards; +} + +// Mixin for stateful foreground colors, e.g. text or icons +.fg-stateful { + &.state-ok { + color: @color-ok; + } + &.state-up { + color: @color-up; + } + &.state-warning { + color: @color-warning; + &.handled { + color: @color-warning-handled; + } + } + &.state-critical { + color: @color-critical; + &.handled { + color: @color-critical-handled; + } + } + &.state-down { + color: @color-down; + &.handled { + color: @color-down-handled; + } + } + &.state-unreachable { + color: @color-unreachable; + &.handled { + color: @color-unreachable-handled; + } + } + &.state-unknown { + color: @color-unknown; + &.handled { + color: @color-unknown-handled; + } + } + &.state-pending { + color: @color-pending; + } +} + +// Mixin for stateful background colors +.bg-stateful { + &.state-ok { + background-color: @color-ok; + } + &.state-up { + background-color: @color-up; + } + &.state-warning { + background-color: @color-warning; + &.handled { + background-color: @color-warning-handled; + } + } + &.state-critical { + background-color: @color-critical; + &.handled { + background-color: @color-critical-handled; + } + } + &.state-down { + background-color: @color-down; + &.handled { + background-color: @color-down-handled; + } + } + &.state-unreachable { + background-color: @color-unreachable; + &.handled { + background-color: @color-unreachable-handled; + } + } + &.state-unknown { + background-color: @color-unknown; + &.handled { + background-color: @color-unknown-handled; + } + } + &.state-pending { + background-color: @color-pending; + } +} diff --git a/public/css/icinga/modal.less b/public/css/icinga/modal.less new file mode 100644 index 0000000..3d497d6 --- /dev/null +++ b/public/css/icinga/modal.less @@ -0,0 +1,113 @@ +#layout > #modal { + position: fixed; + bottom: 0; + left: 0; + right: 0; + top: 0; + + background-color: rgba(0, 0, 0, .6); + opacity: 0; + font-size: @font-size; + line-height: @line-height; + pointer-events: none; + transition: opacity .2s ease-in; // This is coupled with a `setTimout` in modal.js + z-index: 1000; + + &.active { + opacity: 1; + pointer-events: auto; + } + + > div { + height: 100%; + pointer-events: none; + + display: flex; + align-items: center; + justify-content: center; + } +} + +#modal-content { + display: flex; + flex: 10; + flex-direction: column; + justify-content: stretch; + + > .content { + padding: 1em; + + > .icinga-form { + width: 100%; + } + } +} + +#modal-ghost { + display: none; +} + +.modal-area { + display: flex; + flex-direction: row; + flex-grow: 1; + justify-content: stretch; +} + +.modal-header { + padding: .25em 0; + position: relative; + text-align: center; + + > button { + position: absolute; + top: .75em; + right: 1em; + + background-color: @gray; + border: none; + border-radius: 50%; + color: @text-color-inverted; + height: 1.5em; + line-height: 1em; + padding: 0; + text-align: center; + width: 1.5em; + + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + appearance: none; + } + + > button:hover { + opacity: .8; + } + + > button > .icon-cancel:before { + margin-right: 0; + } +} + +.modal-header h1 { + padding: .25em; + margin: 0; +} + +.modal-window { + overflow: auto; + pointer-events: auto; + + display: flex; + align-items: stretch; + flex-direction: column; + + background-color: @body-bg-color; + border-radius: .5em; + box-shadow: 0 0 2em 0 rgba(0, 0, 0, .6); + flex: 1; + margin: 0 auto; + max-height: 80%; + min-height: 40vh; + max-width: 60em; +} diff --git a/public/css/icinga/nav.less b/public/css/icinga/nav.less new file mode 100644 index 0000000..cd8f9d0 --- /dev/null +++ b/public/css/icinga/nav.less @@ -0,0 +1,54 @@ +/*! Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +.badge-nav-item { + > a { + .clearfix(); + + > .badge { + float: right; + } + } +} + +.dropdown-nav-item > ul { + display: none; + position: absolute; +} + +.dropdown-nav-item.active > ul, +.dropdown-nav-item:hover > ul { + display: block; +} + +.nav { + // Reset defaults + list-style-type: none; + margin: 0; + padding: 0; + + li > a, + li > span { + // Rollover + display: block; + } +} + +.nav .nav-item .icon:before { + width: 1.5em; +} + +.tab-nav { + .clearfix(); + + > li { + float: left; + } +} + +.primary-nav a { + font-weight: 500; +} + +.remove-nav-item { + padding-left: 2em; +} diff --git a/public/css/icinga/pending-migration.less b/public/css/icinga/pending-migration.less new file mode 100644 index 0000000..bc70caa --- /dev/null +++ b/public/css/icinga/pending-migration.less @@ -0,0 +1,173 @@ +// Style + +@visual-width: 1.5em; +@max-view-width: 50em; + +.migration-state-banner, .change-database-user-description { + .rounded-corners(); + + border: 1px solid @gray-light; + color: @text-color; +} + +.migrations { + a { + color: @icinga-blue; + } + + .empty-state { + margin: 0 auto; + } + + .list-item { + .visual.upgrade-failed, span.upgrade-failed, .errors-section > header > i { + color: @state-critical; + } + + span.version { + color: @text-color; + } + } + +.migration-form { + input[type="submit"] { + line-height: 1.5; + + &:disabled { + color: @disabled-gray; + cursor: not-allowed; + background: none; + border-color: fade(@disabled-gray, 75) + } + } + } +} + +// Layout + +#layout.twocols:not(.wide-layout) .migration-form fieldset .control-label-group { + text-align: right; +} + +.migration-state-banner, .change-database-user-description { + padding: 1em; + text-align: center; + + &.change-database-user-description { + max-width: 50em; + padding: .5em; + } +} + +.pending-migrations-hint { + text-align: center; + + > h2 { + font-size: 2em; + } +} + +.migration-controls { + display: flex; + align-items: center; + justify-content: space-between; +} + +.migrations { + .migration-form fieldset { + max-width: @max-view-width; + } + + .migration-list-control { + padding-bottom: 1em; + + > .item-list { + max-width: @max-view-width; + } + } + + .item-list:not(.file-list) > .list-item { + > .main { + border-top: none; + } + + footer { + display: block; + } + } + + .list-item { + align-items: baseline; + + .main { + margin-left: 0; + } + + header { + align-items: baseline; + justify-content: flex-start; + + input { + margin-left: auto; + } + + .title span.upgrade-failed { + margin: .5em; + } + } + + .caption, .errors-section pre { + margin-top: .25em; + height: auto; + -webkit-line-clamp: 3; + } + + .errors-section { + margin: 1em -.25em; + border: 1px solid @state-critical; + padding: .25em; + .rounded-corners(.5em); + + .status-icon { + margin-top: .3em; + margin-left: -1.5em; + margin-right: .25em; + } + + .caption, header { + margin-left: 1.8em; + } + } + + footer { + width: 100%; + padding-top: 0; + + > * { + font-size: 1em; + } + + .list-item:first-child .main { + padding-top: 0; + } + + a { + margin-left: @visual-width; + } + } + } +} + +.item-list.file-list { + .visual { + width: @visual-width; + } + + .main { + margin-left: @visual-width; + } + + .visual + .main { + margin-left: 0; + } +} diff --git a/public/css/icinga/php-diff.less b/public/css/icinga/php-diff.less new file mode 100644 index 0000000..d8f6a80 --- /dev/null +++ b/public/css/icinga/php-diff.less @@ -0,0 +1,17 @@ +@diff-bg-color: transparent; +@diff-text-color: @text-color; + +@diff-bg-color-ins-base: @color-up; +@diff-bg-color-del-base: @color-down; +@diff-bg-color-rep-base: @color-warning; + +@diff-border-color: @gray-light; + +@light-mode: { + :root { + --diff-bg-color: var(--body-bg-color); + --diff-text-color: var(--text-color); + + --diff-border-color: var(--gray-light); + } +}; diff --git a/public/css/icinga/print.less b/public/css/icinga/print.less new file mode 100644 index 0000000..75d4728 --- /dev/null +++ b/public/css/icinga/print.less @@ -0,0 +1,39 @@ +/*! Icinga Web 2 | (c) 2015 Icinga GmbH | GPLv2+ */ + +@media print { + #sidebar, + #migrate-popup, // Icinga DB Web + .controls, + .footer, // ipl + .dontprint, // Compat only, use dont-print instead + .dont-print { + display: none !important; + } + + #main > .container { + overflow: visible !important; + + > .content { + overflow: visible !important; + } + } + + :root { + --body-bg-color: #fff !important; + --text-color: #535353 !important; + --text-color-light: #7F7F7F !important; + --tr-active-color: #fff !important; + --tr-hover-color: #fff !important; + + // ipl-web overrides + --default-bg: #fff !important; + --default-text-color: #535353 !important; + --default-text-color-inverted: #fff !important; + } +} + +@media not print { + .print-only { + display: none !important; + } +} diff --git a/public/css/icinga/responsive.less b/public/css/icinga/responsive.less new file mode 100644 index 0000000..6d1cae8 --- /dev/null +++ b/public/css/icinga/responsive.less @@ -0,0 +1,167 @@ +/*! Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */ + +// Not growing larger than 3840px at 1em=16px right now +@media screen and (min-width: 240em) { + #header { + min-width: 240em; + } + + #main { + width: 227em; + } +} + +// More than 100em, usually 1600px at 1em=16px +@media screen and (min-width: 100em) { + html { + font-family: 'wide-layout'; + } +} + +// Up to 1152px at 1em=16px +@media screen and (max-width:72em) { + html { + font-family: 'compact-layout'; + } +} + +// Up to 752px at 1em=16px +@media screen and (max-width: 47em) { + html { + font-family: 'poor-layout'; + } +} + +// Up to 576px at 1em=16px, should fit 320px devices +@media screen and (max-width: 36em) { + html { + font-family: 'minimal-layout'; + } +} + +#layout.compact-layout { + font-size: 0.875em; +} + +#layout.poor-layout { + font-size: 0.875em; + + #layout.twocols { + #col1 { + display: none; + } + + #main > .container { + width: 100%; + } + } + + .dashboard > div.container { + width: 100%; + } +} + +#layout:not(.minimal-layout) { + #mobile-menu-toggle { + display: none; + } +} + +#layout.minimal-layout { + #sidebar { + width: 100%; + overflow: auto; + } + + #header-logo-container { + width: auto; + height: 4em; + padding: 0; + background: inherit; + } + + #header-logo { + float: left; + width: 9em; + height: 3em; + margin: .5em 1em; + background-position: left center; + } + + #mobile-menu-toggle { + float: right; + } + + #sidebar:not(.expanded) #menu { + display: none; + } + + #menu { + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + } + + #content-wrapper { + flex-direction: column; + } + + #main { + flex: 1 1 auto; + height: 0; + } + + ul > .selected > a:after, + ul > .nav-item.active:after { + display: none; + } + + .dashboard > div.container { + width: 100%; + } +} + +// Dashboard + +.dashboard > .container { + padding-right: 0; + width: 100%; +} + +#layout:not(.twocols).default-layout .dashboard > .container:not(:only-child) { + padding-right: @gutter; + width: 50%; +} + +#layout:not(.twocols).wide-layout .dashboard > .container:not(:only-child) { + padding-right: @gutter; + width: 33.33%; +} + +// Columns + +#layout.twocols #col2 { + border-left: 1px solid @gray-lighter; +} + +#layout.twocols.wide-layout #col2 { + flex-grow: 2; +} + +// Safe areas for iPhone X + +#header, #sidebar, #footer { + padding-left: constant(safe-area-inset-left); +} + +#main, #footer { + padding-right: constant(safe-area-inset-right); +} + +#layout.twocols #col2 { + border-left: 1px solid @gray-lighter; + + &:empty { + display: flex; + } +} diff --git a/public/css/icinga/setup.less b/public/css/icinga/setup.less new file mode 100644 index 0000000..5748c8e --- /dev/null +++ b/public/css/icinga/setup.less @@ -0,0 +1,480 @@ +/*! Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +#setup-content-wrapper { + height: 0; + display: flex; + flex: 1 1 auto; + flex-direction: column; + + > .setup-content { + height: 0; + overflow: auto; + flex: 1 1 auto; + } +} + +.setup-header { + width: 100%; + height: 5.5em; + background-color: @icinga-blue; + text-align: center; + + img { + width: 7.5em; + margin: 1.5em; + float: left; + } + + form[name='setup_restart_form'] button { + background: none; + border: none; + color: #ffffff; + cursor: pointer; + outline: none; + font-size: 1.4em; + margin-right: 0.6em; + -moz-transform: scale(1, -1); + -webkit-transform: scale(1, -1); + -o-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); + } + + .progress-bar { + overflow: hidden; + padding-top: 1em; + + .step { + float: left; + + h1 { + margin: 0; + color: white; + font-size: 0.9em; + text-align: center; + border-bottom: none; + } + + table { + margin-top: 0.3em; + + td { + padding: 0; + + &.left, &.right { + width: 50%; + } + } + } + + div { + background-color: lightgrey; + + &.line { + height: 0.4em; + + &.left { + margin-left: 0.1em; + margin-right: -0.1em; + border-top-left-radius: 0.5em; + border-bottom-left-radius: 0.5em; + } + + &.right { + margin-left: -0.1em; + margin-right: 0.1em; + border-top-right-radius: 0.5em; + border-bottom-right-radius: 0.5em; + } + } + + &.bubble { + width: 1.2em; + height: 1.2em; + border-radius: 1.2em; + + // Make sure that such a bubble overlays lines + position: relative; + z-index: 1337; + } + + &.active { + background-color: white; + } + + &.complete { + background-color: @color-ok; + } + + &.visited { + background-color: #eee; + } + } + } + } +} + +.setup-content { + padding: 1.5em 10em 0 10em; + + h1 { + font-weight: bold; + } + + form { + h2 { + font-size: 2.0em; + } + } +} + +.setup-content .control-group > :not([hidden]) { + display: inline-block; + margin-right: 1em; +} + +.setup-content div.buttons { + margin-top: 1.5em; // Yes, -top and -bottom, keep it like that... + margin-bottom: 1.5em; + + .double { + position: absolute; + left: -1337px; + } + + .control-button, + input[type="submit"] { + .button(); + justify-content: center; + } + + .control-button[disabled] { + background: none; + cursor: default; + color: @control-disabled-color; + border: 1px solid @control-disabled-color; + + &:hover { + color: @control-disabled-color; + background: none; + border: 1px solid @control-disabled-color; + } + } + + button.finish, a.button-link.login { + min-width: 25em; + } + + .spinner { + margin-left: 1em; + } +} + +.setup-content div.buttons + ul.hints { + margin-top: -1.5em; + margin-bottom: 1.5em; +} + +form#setup_requirements { + margin-top: 2em; + padding-top: 0.5em; + border-top: 1px solid #888; + + div.buttons div.requirements-refresh { + width: 25%; + float: right; + text-align: center; + + a.button-like { + padding: 0.1em 0.4em; + } + } +} + +.setup-content ul.requirements { + margin: 0; + padding: 0; + list-style-type: none; + + li { + margin-bottom: 1em; + + & > ul { + margin: 0; + padding: 0; + list-style-type: none; + } + + div { + float: left; + padding-top: 0.4em; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + } + + div.title { + width: 25%; + + h2 { + padding: 0; + margin: 0 1em 0 0; + border-bottom: 0; + } + } + + div.description { + width: 50%; + border-left: 0.4em solid transparent; + border-right: 0.4em solid transparent; + + ul { + margin: 0; + padding-left: 1em; + list-style-type: square; + } + } + + div.state { + width: 25%; + color: white; + padding: 0.4em; + + &.fulfilled { + background-color: @color-ok; + } + + &.not-available { + color: black; + background-color: #e8ec70; + } + + &.missing { + background-color: @color-critical; + } + } + } +} + +#setup_ldap_discovery_confirm table { + margin: 1em 0; + border-collapse: separate; + border-spacing: 1em 0.2em; +} + +#setup_admin_account { + div.instructions { + width: 30.2em; + display: inline-block; + } + + div.radiobox { + vertical-align: top; + display: inline-block; + padding: 0.9em 0.2em 0; + } +} + +.setup-content { + div.summary { + font-size: 90%; + + div.page { + float: left; + width: 25em; + min-height: 25em; + padding: 0 1em 1em; + margin: 1em 1.5em 1.5em; + border: 1px dashed lightgrey; + + h2 { + font-size: 1.2em; + font-weight: bold; + } + + div.topic { + margin-left: 2em; + + h3 { + font-size: 1em; + } + + ul { + list-style-type: circle; + } + + table { + border-spacing: 0.5em; + border-collapse: separate; + font-size: 0.9em; + margin-left: 2em; + } + } + } + } + + form.summary { + clear: left; + } +} + +#setup-finish { + h2 { + padding: 0.5em; + border-bottom: 0; + font-variant: normal; + font-weight: bold; + color: white; + + &.success { + background-color: @color-ok; + } + + &.failure { + background-color: @color-critical; + } + } + + pre.log-output { + width: 66%; + height: 25em; + max-height: none; + } + + div.buttons { + margin-top: 0; + text-align: center; + + a { + padding: 0.5em; + } + } +} + +.welcome-page { + margin-top: 3em; + text-align: center; + + h2 { + font-size: 2.0em; + margin-bottom: 2em; + } + + div.info { + padding: 0 1em; + background-color: #eee; + border: 1px solid lightgrey; + } + + p.restart-warning { + color: coral; + font-weight: bold; + } + + form ul.errors { + display: block; + + list-style-type: none; + color: red; + } + + div.note { + padding: 1em 1em 0; + margin: 3em auto 0; + text-align: left; + font-size: 0.9em; + border: 1px solid; + border-color: @gray-light; + + h3 { + padding: 0.2em; + margin: -1em -1em 1em; + text-align: center; + color: @text-color; + background-color: @gray-lightest; + border: 1px solid; + border-color: @gray-light; + } + + img { + float: right; + } + + p { + margin: 2em 0 1em 0; + + &:first-child { + margin-top: 1em; + } + } + + div.code { + margin: 0 2em; + + span { + display: block; + font-family: monospace; + } + } + } +} + +#setup_monitoring_welcome { + .welcome-page; + margin-top: 0; + padding: 1em; + + h2 { + margin-top: 0; + } +} + +#setup_modules { + div.module { + float: left; + width: 15em; + height: 15em; + margin: 1em; + padding: 0.3em; + border: 1px solid; + border-color: @gray-semilight; + background-color: @gray-lightest; + + .header { + height: 2.5em; + display: flex; + justify-content: space-between; + } + + h3 { + margin: 0; + border: none; + overflow: hidden; + text-overflow: ellipsis; + + label { + cursor: pointer; + } + } + + label.description { + display: inline-block; + width: 14.4em; + height: 12em; + overflow: auto; + cursor: pointer; + font-weight: normal; + } + + input[type=checkbox] { + height: 10em; + float: right; + margin: 0; + } + } + + div.buttons { + padding-top: 1em; + clear: both; + } +} diff --git a/public/css/icinga/spinner.less b/public/css/icinga/spinner.less new file mode 100644 index 0000000..c1cf93e --- /dev/null +++ b/public/css/icinga/spinner.less @@ -0,0 +1,42 @@ +/*! Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +.refresh-container-control > i:before { + margin: 0; +} + +a.spinner.active > i, +button.spinner.active > i, +i.spinner.active { + &:before { + .animate(spin 2s infinite linear); + + // icon-spin6 + content: '\e874'; + } + + &.fa:before { + // fa spinner + content: '\f110'; + } +} + +div.spinner { + display: inline-block; + vertical-align: middle; + + i { + visibility: hidden; + + &.active { + visibility: visible; + + &:before { + .animate(spin 2s infinite linear); + } + } + + &:before { + margin: 0; // Disables wobbling + } + } +} diff --git a/public/css/icinga/tabs.less b/public/css/icinga/tabs.less new file mode 100644 index 0000000..7185d61 --- /dev/null +++ b/public/css/icinga/tabs.less @@ -0,0 +1,109 @@ +/*! Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +// Styles for tab navigation of containers + +.tabs { + background-color: @menu-bg-color; + letter-spacing: -0.417em; +} + +.tabs > li { + display: inline-block; + letter-spacing: normal; +} + +.tabs a { + padding: 0 1em; + line-height: 2.5em; + + &:focus { + outline-offset: -0.5em; + } +} + +.tabs > li { + &:not(:last-child) { + margin-right: 0.5em; + } + + > a { + color: @menu-color; + + &:hover { + text-decoration: none; + background: @tab-hover-bg-color; + } + } + + &.active > a, + > a:focus { + background-color: @body-bg-color; + color: @text-color; + } +} + +.tabs > .dropdown-nav-item > a, +.tabs > li > .close-container-control, +.tabs > li > .refresh-container-control { + text-align: center; + width: 3em; +} + +.tabs > .dropdown-nav-item:hover > a, +.tabs > .dropdown-nav-item > a:focus, +.tabs > li > .close-container-control:focus, +.tabs > li > .close-container-control:hover, +.tabs > li > .refresh-container-control:focus, +.tabs > li > .refresh-container-control:hover { + background-color: @body-bg-color; + color: @text-color; + text-decoration: none; +} + +.tabs > .dropdown-nav-item > ul { + .box-shadow(); + .rounded-corners(0 0 0.3em 0.3em); + + background-color: @body-bg-color; + border: 1px solid; + border-color: @gray-light; + border-top: none; + margin-left: -1px; + min-width: 14em; + z-index: 10; +} + +.tabs > .dropdown-nav-item > ul > li:hover > a { + background-color: @gray-lighter; + text-decoration: none; +} + +// Dropdown tabs after the fourth title should be right-aligned +.tabs > li:nth-child(n+5).dropdown-nav-item > ul { + transform: translate(~"calc(-100% + 3em)"); // -full width + tab width + margin-left: 1px; +} + +// TODO(el): Rename display-on-hover and move it to main.less +.display-on-hover { + font-size: @font-size-small; + left: -999em; + position: relative; +} + +.dropdown-nav-item > ul > li > a:focus > .display-on-hover, +.dropdown-nav-item > ul > li:hover > a > .display-on-hover { + position: static; +} + +.tabs > li > .close-container-control { + display: none; +} + +#layout.twocols .tabs > li > .close-container-control { + display: block; +} + +.close-container-btn { + float: right; +} diff --git a/public/css/icinga/widgets.less b/public/css/icinga/widgets.less new file mode 100644 index 0000000..3518cbe --- /dev/null +++ b/public/css/icinga/widgets.less @@ -0,0 +1,666 @@ +/*! Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +#announcements > ul { + background-color: @body-bg-color; + list-style: none; + margin: 0; + padding: 0; + + > li { + border-bottom: 1px solid @gray-lighter; + line-height: 1.5em; + padding: 0.5em 1em 0.5em 3em; + + position: relative; + + &:before { + color: @icinga-blue; + content: "\e811"; + font-family: 'ifont'; + + position: absolute; + left: 1.25em; + } + + &:last-child { + border-bottom: none; + } + + a { + color: @icinga-blue; + } + + .message { + display: inline-block; + vertical-align: middle; + padding-right: 1.5em; + font-size: 7/6em; + } + + p { + margin-bottom: 0; + } + } +} + +.acknowledge-announcement-control, +.application-state-acknowledge-message-control { + background: none; + border: none; + display: block; + margin-top: -0.75em; + + position: absolute; + right: .75em; + top: 50%; +} + +.application-state-acknowledge-message-control .link-button { + color: #fff; + + &:hover .icon-cancel { + color: @icinga-blue; + } +} + +#application-state-summary > div { + background-color: @color-critical; + color: @text-color-on-icinga-blue; + line-height: 1.5em; + padding: 0.5em 1em 0.5em 3em; + + position: relative; + + &:before { + content: "\e84d"; + font-family: 'ifont'; + + position: absolute; + text-align: center; + left: .4em; + padding: .5em; + width: 3em; + top: 0; + } + + > section { + margin-left: .5em; + } + + > form .icon-cancel:before { + color: @text-color-on-icinga-blue; + } +} + +.dashboard-link { + .clearfix(); + display: block; + max-width: 100%; + vertical-align: middle; + padding: 1em; + width: 36em; + + &:hover { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + + -webkit-box-shadow: 0 0 0.5em 0 rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 0 0.5em 0 rgba(0, 0, 0, 0.2); + box-shadow: 0 0 0.5em 0 rgba(0, 0, 0, 0.2); + + background-color: @tr-hover-color; + text-decoration: none; + } +} + +.dashboard.content > .container { + overflow-x: auto; +} + +.link-meta { + display: table-cell; + vertical-align: middle; +} + +.link-label { + font-weight: @font-weight-bold; +} + +.link-description { + color: @text-color-light; +} + +.link-icon { + display: table-cell; + padding-right: .5em; + vertical-align: middle; + text-align: center; + + > i { + font-size: 3em; + opacity: 0.7; + line-height: 1.5; + + &:before { + min-width: 1.25em; + } + } + + > img { + width: 3em; + height: 3em; + margin-right: .6em; + } +} + +table.historycolorgrid { + font-size: 1.5em; +} + +table.historycolorgrid th { + width: 1em; + height: 1em; + margin: 0.5em; + font-size: 0.55em; + font-weight: bold; +} + +table.historycolorgrid td { + width: 1em; + height: 1em; + margin: 1em; +} + +table.historycolorgrid td:hover { + opacity: 0.5; +} + +table.historycolorgrid td.weekday { + font-size: 0.55em; + font-weight: bold; + width: 2.5em; + opacity: 1.0; +} + +table.historycolorgrid a, table.historycolorgrid span { + .rounded-corners(0.2em); + margin: 0; + text-decoration: none; + display: block; + width: 1.1em; + height: 1.1em; +} + +table.historycolorgrid a:hover { + text-decoration: none; +} + +table.multiselect tr[href] td { + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; +} + +#main div.filter { + .search.search-input { + width: 8em; + } + + form.editor { + input[type=text], select { + width: 12em; + height: 2em; + line-height: 1; + } + + ul.tree li.active { + background-color: @gray-lightest; + } + + button { + padding: .5em; + border: none; + background: none; + color: @text-color; + + &:hover, &:focus { + color: @icinga-blue; + } + } + + .buttons { + margin-left: 25em; + padding: .25em 0; + } + + .buttons input:not(:last-child) { + margin-right:.5em; + } + + ul.tree { + .filter-operator { + width: 5em; + } + + .new-filter { + background: #ffb; + } + + .filter-rule { + width: 4em; + } + } + } +} + +form.role-form { + &.icinga-form .control-label-group { + width: 20em; + } + + .control-label-group em { + color: @text-color-light; + font-style: normal; + } + + .unrestricted-role { + text-decoration: line-through; + } + + .control-label > * { + display: inline-block; + } + + summary { + border-bottom: 1px solid @gray-light; + .user-select(none); + cursor: pointer; + + font-weight: @font-weight-bold; + margin: 0.556em 0 0.333em; + font-size: 1.167em; + + display: flex; + align-items: baseline; + .privilege-preview { + flex: 1 1 auto; + } + + > :first-child { + display: inline-block; + width: 20em / 1.167em; // element label width / summary font-size + } + + > :nth-last-child(1), + > :nth-last-child(2) { + font-size: .75em; + opacity: .6; + } + + .privilege-preview .icon { + &.granted { + color: @color-granted; + } + + &.refused { + color: @color-refused; + } + + &.restricted { + color: @color-restricted; + } + } + } + + .collapsible { + summary em { + font-size: .857em; + font-weight: normal; + color: @text-color-light; + } + + h4 { + display: inline-block; + width: 20em; + margin-top: 1.5em; + padding-right: .5625em; + text-align: right; + + & ~ i { + display: inline-block; + width: 2.625em; + margin-right: 1em; + text-align: center; + + &.icon-ok { + color: @color-granted; + } + + &.icon-cancel { + color: @color-refused; + } + } + } + } +} + +ul.tree select:first-of-type { /* ?? */ + margin-bottom: 0.3em; + margin-left: 2em; +} + +ul.tree { + padding: 0; + margin: 0; + padding-top: .5em; +} + +ul.tree ul { + padding-left: 1em; +} + +ul.tree li { + margin: 0; + list-style-type: none; + position: relative; + padding: 0; +} + +ul.tree li .handle { + background-image: url('../img/tree/tree-minus.gif'); + background-repeat: no-repeat; + display: inline-block; + position: absolute; + width: 1.5em; + height: 2em; + left: 0em; + background-position: center center; + z-index: 1; + cursor: pointer; +} + +ul.tree li.collapsed > .handle { + background-image: url('../img/tree/tree-plus.gif'); +} + +ul.tree li.collapsed > ul { + display: none; +} + +ul.tree li::before, ul.tree li::after { + content: ''; + position: absolute; + right: auto; + left: -0.2em; + border-color: @gray-light; + border-style: dotted; + border-width: 0; +} + +/* This is the left vertical line */ +ul.tree li::before { + border-left-width: 1px; + top: -.5em; + width: 1em; + height: 2.5em; + bottom: 1em; +} + +/* This is the horizontal dash in front of each item */ +ul.tree li::after { + border-top-width: 1px; + top: 1em; + width: 2em; + height: 1em; +} + +/* Stop left vertical line at "mid-height" after last nodes (at each level) */ +ul.tree li:last-child::before { + height: 1.5em; +} + +/* No border for the root element - there must be only ONE root */ +ul.tree > li::before, ul.tree > li::after { + display: none; +} + +/* No connector before (each) root element */ +ul.tree > ul > li::before, ul.tree > ul > li::after { + border: 0; +} + +ul.tree li a { + display: inline-block; + line-height: 2em; + padding: 0 .5em; + text-decoration: none; + color: @gray; + background-repeat: no-repeat; + background-position: 0.8em 0.4em; +} + +ul.tree li a.error { + color: @color-critical-handled; +} + +ul.tree li a:hover { + color: @text-color; + text-decoration: underline; +} + +ul.tree li a.error:hover { + color: @color-critical; +} + +/* charts should grow as much as possible but never beyond the current viewport's size */ +.svg-container-responsive { + padding: 1.5em; + height: 80vh; +} + +.tipsy .tipsy-inner { + // overwrite tooltip max width, we need them to grow bigger + font-family: @font-family; + font-size: @font-size-small; + max-width: 300px; + text-align: left; + background-color: rgba(0,0,0,0.8); +} + +.progress-label span { + font-size: 1.5em; + .animate(blink 1.4s infinite both); + + &:nth-child(2) { + animation-delay: .2s; + } + + &:nth-child(3) { + animation-delay: .4s; + } +} + +.flyover:not(.flyover-expanded) .flyover-content { + display: none; +} + +.flyover { + position: relative; + + .flyover-content { + background-color: @body-bg-color; + border: 1px solid; + border-color: @gray-lighter; + box-shadow: 0 0 .5em 0 rgba(0, 0, 0, 0.2); + position: absolute; + padding: @vertical-padding @horizontal-padding; + .rounded-corners(); + } + + &.flyover-arrow-top .flyover-content:before { + background: @body-bg-color; + border-left: 1px solid @gray-lighter; + border-top: 1px solid @gray-lighter; + content: ""; + height: 1em; + -ms-transform: rotate(45deg); + transform: rotate(45deg); + width: 1em; + + position: absolute; + left: 6px; + top: -7px; + } + + &.flyover-right .flyover-content { + left: auto; + right: 0; + } + + &.flyover-arrow-top.flyover-right .flyover-content:before { + left: auto; + right: 6px; + } +} + +.slice-state-ok { + stroke: @color-ok; + background: @color-ok; +} + +.slice-state-warning-handled { + stroke: @color-warning-handled; + background: @color-warning-handled; +} + +.slice-state-warning { + stroke: @color-warning; + background: @color-unreachable-handled; +} + +.slice-state-critical-handled { + stroke: @color-critical-handled; + background: @color-critical-handled; +} + +.slice-state-critical { + stroke: @color-critical; + background: @color-critical; +} + +.slice-state-unknown-handled { + stroke: @color-unknown-handled; + background: @color-unknown-handled; +} + +.slice-state-unknown { + stroke: @color-unknown; + background: @color-unknown; +} + +.slice-state-unreachable-handled { + stroke: @color-unreachable-handled; + background: @color-unreachable-handled; +} + +.slice-state-unreachable { + stroke: @color-unreachable; + background: @color-unreachable; +} + +.slice-state-pending { + stroke: @color-pending; + background: @color-pending; +} + +.slice-state-not-checked { + stroke: @gray-light; + background: @gray-light; +} + +.donut { + width: 22em; + height: 22em; + min-width: 11.5em; + display: table; +} + +.donut-graph { + width: 22em; + height: 22em; +} + +.donut-label { + font-weight: bold; + fill: @text-color; +} + +.donut-label { + margin-top: -12.5em; + text-align: center; +} + +.donut-label-big { + color: @gray-light; + .fg-stateful(); + font-size: 6em; + line-height: 0; + text-anchor: middle; + &:hover { + text-decoration: none; + } +} + +.donut-label-small { + fill: @text-color; + font-size: 1.2em; + text-anchor: middle; + -moz-transform: translateY(0.35em); + -ms-transform: translateY(0.35em); + -webkit-transform: translateY(0.35em); + transform: translateY(0.35em); +} + +.donut-container { + float: left; + + &:not(:last-of-type) { + margin-right: 10em; + } +} + +.dashboard .donut-container .donut-legend { + margin-left: auto; +} + +.donut-legend { + width: 50%; + padding: 0; + margin-left: 18em; + list-style-type: none; + + li { + vertical-align: middle; + + &:not(:last-child) { + margin-bottom: .5em; + } + + .badge { + font-weight: bold; + margin-right: .5em; + vertical-align: initial; + } + } +} + +html.no-js .progress-label { + display: none; +} + diff --git a/public/css/modes/light.less b/public/css/modes/light.less new file mode 100644 index 0000000..7044007 --- /dev/null +++ b/public/css/modes/light.less @@ -0,0 +1,4 @@ +/* Icinga Web 2 | (c) 2021 Icinga GmbH | GPLv2+ */ + +@enable-color-preference: 999999px; +@prefer-light-color-scheme: 0px; diff --git a/public/css/modes/none.less b/public/css/modes/none.less new file mode 100644 index 0000000..05c618c --- /dev/null +++ b/public/css/modes/none.less @@ -0,0 +1,4 @@ +/* Icinga Web 2 | (c) 2021 Icinga GmbH | GPLv2+ */ + +@enable-color-preference: 999999px; +@prefer-light-color-scheme: 999999px; diff --git a/public/css/modes/system.less b/public/css/modes/system.less new file mode 100644 index 0000000..07bd06a --- /dev/null +++ b/public/css/modes/system.less @@ -0,0 +1,4 @@ +/* Icinga Web 2 | (c) 2021 Icinga GmbH | GPLv2+ */ + +@enable-color-preference: 0px; +@prefer-light-color-scheme: 999999px; diff --git a/public/css/pdf/pdfprint.less b/public/css/pdf/pdfprint.less new file mode 100644 index 0000000..2c68d37 --- /dev/null +++ b/public/css/pdf/pdfprint.less @@ -0,0 +1,103 @@ +/*! Icinga Web 2 | (c) 2014 Icinga GmbH | GPLv2+ */ + +// Ensure styling is light, exports use a white background + +@gray: #7F7F7F; +@gray-semilight: #A9A9A9; +@gray-light: #C9C9C9; +@gray-lighter: #EEEEEE; +@gray-lightest: #F7F7F7; +@icinga-blue: #0095BF; +@low-sat-blue: #dae3e6; +@low-sat-blue-dark: #becbcf; +@body-bg-color: #fff; +@text-color: @black; +@text-color-light: @gray; +@tr-active-color: @body-bg-color; +@tr-hover-color: @body-bg-color; + +// Page layout + +@page { + margin: 1cm; +} + +body { + font-family: sans-serif; + margin: 0; + padding-top: 37px; // ~ logo height in the header +} + +.content { + font-size: 9pt; +} + +#header, +#footer { + position: fixed; + left: 0; + right: 0; + color: #aaa; + font-size: 0.9em; +} + +#header { + top: 0; + border-bottom: 0.1pt solid #aaa; + + .title { + text-align: left; + } + + img { + margin-bottom: 3px; + } +} + +#footer { + bottom: 0; + padding-top: 2em; +} + +.content table { + margin-bottom: 3em; +} + +#header table, +#footer table { + width: 100%; + border-collapse: collapse; + border: none; +} + +#header td, +#header th, +#footer td, +#footer th { + padding: 0; + width: 50%; +} + +.page-number { + padding-top: 0.5em; + border-top: 0.1pt solid #aaa; + text-align: center; +} + +.page-number:before { + content: "Page " counter(page); +} + +hr { + page-break-after: always; + border: 0; +} + +// General style +.state-icons, +.overview-performance-data, +.controls, +.dontprint, // Compat only, use dont-print instead +.dont-print { + display: none !important; +} diff --git a/public/css/themes/Winter.less b/public/css/themes/Winter.less new file mode 100644 index 0000000..2edf4f8 --- /dev/null +++ b/public/css/themes/Winter.less @@ -0,0 +1,30 @@ +/*! Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +@icinga-blue: #2b95ff; +@control-color: @icinga-blue; + +.letitsnow { + background-image: url('../img/winter/snow1.png'), url('../img/winter/snow2.png'), url('../img/winter/snow3.png'); + animation: ~"snow" 10s linear infinite; +} + +#header-logo { + background-image: url('../img/winter/logo_icinga_big_winter.png'); +} + +/* Snow, from http://codepen.io/NickyCDK/pen/AIonk */ +#login, #header-logo-container, #main > .container > .controls > .tabs { + .letitsnow() +} + +@keyframes ~"snow" { + 0% {background-position: 0px 0px, 0px 0px, 0px 0px;} + 50% {background-position: 500px 500px, 100px 200px, -100px 150px;} + 100% {background-position: 500px 1000px, 200px 400px, -100px 300px;} +} + +#menu ul.nav-level-1 > .nav-item { + &:focus, &:hover { + .letitsnow() + } +} diff --git a/public/css/themes/colorblind.less b/public/css/themes/colorblind.less new file mode 100644 index 0000000..c6df585 --- /dev/null +++ b/public/css/themes/colorblind.less @@ -0,0 +1,29 @@ +/*! Icinga Web 2 | (c) 2019 Icinga Development Team | GPLv2+ */ + +@color-ok: fade(#77E08E, 25%); +@color-critical: #FE5566; +@color-critical-handled: fade(@color-critical, 33%); +@color-warning: #B0A029; +@color-warning-handled: fade(@color-warning, 33%); +@color-unknown: #7791E0; +@color-unknown-handled: fade(@color-unknown, 50%); +@color-unreachable: @color-unknown; +@color-unreachable-handled: @color-unknown-handled; +@color-pending: fade(#FFFFFF, 75%); + +/* Adapt font color to match handled / unhandled states */ +.badge, +.state-badge { + font-weight: bold; + color: @text-color !important; + + &.handled, + &.state-up, + &.state-ok { + color: fade(@text-color, 75%) !important; + } +} + +.processinfo .process > div.backend-running { + color: @text-color; +} diff --git a/public/css/themes/high-contrast.less b/public/css/themes/high-contrast.less new file mode 100644 index 0000000..b22ffd5 --- /dev/null +++ b/public/css/themes/high-contrast.less @@ -0,0 +1,250 @@ +/*! Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */ + +@icinga-blue: #006D8C; + +// Gray colors +@gray: #7F7F7F; +@gray-semilight: #A9A9A9; +@gray-light: #C9C9C9; +@gray-lighter: #EEEEEE; +@gray-lightest: #F7F7F7; +@disabled-gray: #9a9a9a; + +// State colors +@color-ok: #006400; +@color-critical: #EE0000; +@color-critical-handled: #EE0000; +@color-warning: #8B5A00; +@color-warning-handled: #8B5A00; +@color-unknown: #800080; +@color-unknown-handled: #800080; +@color-unreachable: #800080; +@color-unreachable-handled: #800080; +@color-pending: #0000EE; + +// Icinga colors +@low-sat-blue: #dae3e6; +@low-sat-blue-dark: #c0cccd; + +// Background color for <body> +@body-bg-color: @white; + +@text-color: #191919; +@text-color-light: #555555; + +@menu-highlight-color: white; +@menu-2ndlvl-color: white; +@menu-2ndlvl-highlight-color: white; +@menu-2ndlvl-active-hover-color: @text-color; + +#menu ul.nav-level-1 > .nav-item > a { + &:focus, &:hover { + text-decoration: underline; + } +} + +#menu ul.nav-level-1 > .nav-item.active > a, +#menu .nav-level-1 > .nav-item.active:not(.selected) > a:hover { + color: @text-color; + background-color: @white; +} + +#menu .nav-level-2 > .nav-item.active { + background-color: @white; + + a { + color: @text-color; + } + + > a:focus, > a:hover { + opacity: 1; + } +} + +#menu .nav-level-2 > .nav-item > a { + &:hover, &:focus { + text-decoration: underline; + } +} + +#menu ul:not(.nav-level-2) > .selected > a { + color: @text-color; +} + +#menu .active > a { + text-decoration: underline; +} + +.badge:not(.handled), +.state-badge:not(.handled) { + &.state-warning { + border: 1px solid @color-warning; + } + + &.state-critical, + &.state-down { + border: 1px solid @color-critical; + } + + &.state-unreachable { + border: 1px solid @color-unreachable; + } + + &.state-unknown { + border: 1px solid @color-unknown; + } + + &.state-ok, + &.state-up { + border: 1px solid @color-ok; + } +} + +.badge.handled, +.badge.state-ok, +.state-badge.handled, +.state-badge.state-ok { + background-color: @body-bg-color !important; + color: @text-color !important; + + &.state-warning { + border: 1px solid @color-warning-handled; + } + + &.state-critical, + &.state-down { + border: 1px solid @color-critical-handled; + } + + &.state-unreachable { + border: 1px solid @color-unreachable-handled; + } + + &.state-unknown { + border: 1px solid @color-unknown-handled; + } +} + +.boxview a:focus { + color: @text-color; + text-decoration: underline; +} + +.icinga-module.module-monitoring { + @timeline-notification-color: #1650CF; + @timeline-hard-state-color: #A24600; + @timeline-comment-color: #346964; + @timeline-ack-color: #855D18; + @timeline-downtime-start-color: #515151; + @timeline-downtime-end-color: #5e5e2f; + + // Unfortunately it does not suffice to only override the timeline colors here, because our less compiler seems to + // have the related style block in module.less already evaluated + + .timeline-notification { + background-color: @timeline-notification-color; + + &.extrapolated { + background-color: lighten(@timeline-notification-color, 20%); + } + } + + .timeline-hard-state { + background-color: @timeline-hard-state-color; + + &.extrapolated { + background-color: lighten(@timeline-hard-state-color, 20%); + } + } + + .timeline-comment { + background-color: @timeline-comment-color; + + &.extrapolated { + background-color: lighten(@timeline-comment-color, 20%); + } + } + + .timeline-ack { + background-color: @timeline-ack-color; + + &.extrapolated { + background-color: lighten(@timeline-ack-color, 20%); + } + } + + .timeline-downtime-start { + background-color: @timeline-downtime-start-color; + + &.extrapolated { + background-color: lighten(@timeline-downtime-start-color, 20%); + } + } + + .timeline-downtime-end { + background-color: @timeline-downtime-end-color; + + &.extrapolated { + background-color: lighten(@timeline-downtime-end-color, 20%); + } + } +} + +.icinga-controls { + input:not([type="checkbox"]):not([type="radio"]), + .toggle-switch .toggle-slider:before, + .toggle-switch > .toggle-slider, + select, + textarea { + border: 1px solid @icinga-blue; + } + + input[type="checkbox"]:not(:checked) + .toggle-switch .toggle-slider:before { + height: 1.166666667em; + width: 1.166666667em; + margin: 1px; + } +} + +.search-suggestions { + input:not([type="checkbox"]):not([type="radio"]), + .toggle-switch .toggle-slider:before, + .toggle-switch > .toggle-slider, + select, + textarea { + border: none; + } +} + +.icinga-module.module-icingadb .list-item.overdue { + background: none; + + header > *:not(time), + .caption { + opacity: 1; + } +} + +.controls input.search, +input.search { + background-image: url(../img/icons/search.png); +} + +.search-bar, +.button-link, +.view-mode-switcher > label { + border: 1px solid @icinga-blue; +} + +// compensate for 1px border +.filter-input-area { + padding: 1/12em !important; +} + +.view-mode-switcher > label { + padding: (10/16)*.25em (10/16)*.5em !important; + + &:not(:first-of-type) { + border-left: none; + } +} diff --git a/public/css/vendor/normalize.css b/public/css/vendor/normalize.css new file mode 100644 index 0000000..458eea1 --- /dev/null +++ b/public/css/vendor/normalize.css @@ -0,0 +1,427 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} |