@import "./breakpoints.css"; @font-face { font-family: "Montserrat"; src: url("../font/Montserrat-Medium.woff2") format("woff2"); font-weight: normal; font-style: normal; } @font-face { font-family: "Montserrat"; src: url("../font/Montserrat-Bold.woff2") format("woff2"); font-weight: bold; font-style: normal; } :root { --evcc-green: #baffcb; --evcc-dark-green: #0fde41ff; --evcc-darker-green: #0ba631ff; --evcc-darker-green-rgb: 11, 166, 49; --evcc-darkest-green: #076f20ff; --evcc-darkest-green-rgb: 7, 111, 32; --evcc-yellow: #faf000; --evcc-dark-yellow: #f6bb0f; --evcc-orange: #ff9000; --evcc-orange-rgb: 255, 144, 0; --evcc-red: #fc440f; --evcc-red-rgb: 252, 68, 15; --bs-gray-deep: #010322; --bs-gray-dark: #28293e; --bs-gray-darker: #151630; --bs-gray-medium: #93949e; --bs-gray-light: #b5b6c3; --bs-gray-bright: #f3f3f7; --bs-gray-brighter: #f9f9fb; --evcc-grid: var(--bs-gray-dark); --evcc-self: var(--evcc-dark-green); --evcc-pv: var(--evcc-dark-green); --evcc-battery: var(--evcc-darker-green); --evcc-export: var(--evcc-yellow); --evcc-export-contrast: var(--evcc-dark-yellow); --evcc-price: #ff912fff; --evcc-co2: #00916eff; --evcc-background: var(--bs-gray-bright); --evcc-box: var(--bs-white); --evcc-box-border: var(--bs-gray-brighter); --evcc-default-text: var(--bs-gray-dark); --evcc-gray: var(--bs-gray-medium); --evcc-gray-50: #93949e80; --evcc-gray-25: #93949e40; --evcc-gray-10: #93949e20; --evcc-accent1: var(--evcc-dark-yellow); --evcc-accent2: var(--evcc-darker-green); --evcc-accent3: var(--evcc-darkest-green); --evcc-transition-slow: 1000ms; --evcc-transition-medium: 500ms; --evcc-transition-fast: 250ms; --evcc-transition-very-fast: 100ms; --bs-primary: var(--evcc-darker-green); --bs-primary-rgb: var(--evcc-darker-green-rgb); --bs-primary-dim: color-mix(in srgb, var(--bs-primary) 50%, transparent); --bs-warning: var(--evcc-orange); --bs-warning-rgb: var(--evcc-orange-rgb); --bs-warning-bg-subtle: color-mix(in srgb, var(--evcc-orange) 10%, transparent); --bs-warning-border-subtle: color-mix(in srgb, var(--evcc-orange) 30%, transparent); --bs-warning-text-emphasis: var(--evcc-orange); --bs-danger-50: #dc354580; --bs-danger: var(--evcc-red); --bs-danger-rgb: var(--evcc-red-rgb); --bs-form-invalid-border-color: var(--bs-danger); --bs-body-font-size: 14px; --bs-font-sans-serif: Montserrat, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --bs-success: var(--evcc-primary); --bs-success-rgb: var(--bs-primary-rgb); --bs-code-color: var(--evcc-darkest-green); --evcc-backdrop: #93949eaa; /* --bs-gray-medium + transparent */ --safe-area-inset-top: env(safe-area-inset-top, 0px); --safe-area-inset-bottom: env(safe-area-inset-bottom, 0px); --safe-area-inset-left: env(safe-area-inset-left, 0px); --safe-area-inset-right: env(safe-area-inset-right, 0px); --tab-bar-height: 3rem; --bottom-space: calc(var(--tab-bar-height) + 1.5rem); --tab-bar-background: var(--evcc-background); --evcc-backdrop-blur: blur(20px); } :root.dark { --evcc-grid: var(--bs-gray-medium); --evcc-export: var(--evcc-yellow); --evcc-export-contrast: var(--evcc-yellow); --evcc-background: var(--bs-gray-deep); --evcc-box: var(--bs-gray-dark); --evcc-box-border: var(--bs-gray-darker); --evcc-default-text: var(--bs-white); --evcc-gray: var(--bs-gray-light); --evcc-accent1: var(--evcc-yellow); --evcc-accent2: var(--evcc-dark-green); --evcc-accent3: var(--evcc-darker-green); --bs-primary: var(--evcc-dark-green); --bs-primary-dim: color-mix(in srgb, var(--bs-primary) 70%, transparent); --bs-border-color-translucent: rgba(255, 255, 255, 0.175); --bs-code-color: var(--evcc-dark-green); --evcc-backdrop: #000000aa; /* black + transparent */ --tab-bar-background: var(--evcc-box); color-scheme: dark; } html.no-transitions * { transition: none !important; } body { background-color: var(--evcc-background); color: var(--evcc-default-text); } body:not(.modal-open) { overflow-y: scroll; } h1, h2, h3, h4 { font-weight: bold; } h1, h2 { font-size: 1.25rem; text-transform: uppercase; } h3, h4 { font-size: 1.25rem; } h5 { font-size: 1rem; font-weight: bold; } .large { font-size: 1.25rem; line-height: 1.2; } .bg-primary { background-color: var(--evcc-dark-green) !important; } .bg-dark-green { background-color: var(--evcc-dark-green) !important; } .bg-darker-green { background-color: var(--evcc-darker-green) !important; } .bg-darkest-green { background-color: var(--evcc-darkest-green) !important; } .text-primary { color: var(--bs-primary) !important; } .text-price { color: var(--evcc-price) !important; } .text-co2 { color: var(--evcc-co2) !important; } .text-export { color: var(--evcc-export-contrast) !important; } a { color: var(--bs-primary); } a:hover { color: var(--evcc-accent3); } /* reverse loading animation */ .progress-bar-animated { animation-direction: reverse; } .bg-muted { opacity: 0.25; } .rounded { border-radius: 10px !important; } .btn { --bs-btn-border-width: 1px; } .btn-reset { border: none; background: none; padding: 0; color: inherit; } .evcc-background { background-color: var(--evcc-background); } .btn-primary, .btn-primary:focus { background-color: var(--bs-primary); border-color: var(--bs-primary); color: var(--evcc-background); } .btn-primary:hover { background-color: var(--evcc-accent3); border-color: var(--evcc-accent3); } .btn-primary:active { color: var(--evcc-default-text) !important; background-color: var(--evcc-accent3) !important; border-color: var(--evcc-accent3) !important; } .btn:disabled { color: inherit !important; background-color: inherit !important; border-color: inherit !important; opacity: 0.3; } .btn-succeeded:disabled { color: var(--bs-primary) !important; background-color: transparent !important; border-color: var(--bs-primary) !important; opacity: 1 !important; } .dark .btn-disabled { opacity: 0.4; } .btn-outline-primary { --bs-btn-active-bg: var(--bs-primary); --bs-btn-active-border-color: var(--bs-primary); } .btn-outline-primary, .btn-outline-primary:focus { color: var(--bs-primary); background-color: transparent; border-color: var(--bs-primary); } .btn-outline-primary:hover { color: var(--evcc-accent3) !important; background-color: transparent !important; border-color: var(--evcc-accent3) !important; } .btn-group > .btn-check + .btn-outline-primary:hover, .btn-outline-primary:active { color: var(--bs-white) !important; background-color: var(--evcc-accent3) !important; border-color: var(--evcc-accent3) !important; } .btn-xs { --bs-btn-padding-y: 0; --bs-btn-padding-x: 0.5rem; --bs-btn-font-size: 0.7rem; --bs-btn-border-radius: 0.25rem; --bs-btn-line-height: 2; } .btn-outline-secondary { --bs-btn-color: var(--evcc-default-text); --bs-btn-border-color: var(--evcc-default-text); --bs-btn-hover-bg: transparent; --bs-btn-hover-color: var(--bs-gray-medium); --bs-btn-hover-border-color: var(--bs-gray-medium); } .btn-link:hover, .btn-link:focus { color: var(--bs-primary); } .btn-link:focus { outline: var(--bs-focus-ring-width) solid var(--bs-focus-ring-color); outline-width: var(--bs-focus-ring-width); } .btn-link:disabled { border-color: transparent !important; opacity: 0.2; } .dark .btn-outline-secondary { --bs-btn-color: var(--bs-gray-bright); --bs-btn-border-color: var(--bs-gray-bright); --bs-btn-hover-bg: transparent; --bs-btn-hover-color: var(--bs-gray-medium); --bs-btn-hover-border-color: var(--bs-gray-medium); } .accordion { --bs-accordion-active-color: var(--bs-text); --bs-accordion-active-bg: var(--evcc-background); --bs-accordion-btn-active-icon: var(--bs-accordion-btn-icon); } .text-evcc { color: var(--evcc-dark-green); } .text-accent1 { color: var(--evcc-accent1); } .text-accent2 { color: var(--evcc-accent2); } .text-accent3 { color: var(--evcc-accent3); } .evcc-default-text { color: var(--evcc-default-text) !important; } .evcc-gray { color: var(--evcc-gray); } .text-grid { color: var(--evcc-grid); } .text-dark { color: var(--bs-gray-dark); } .text-light { color: var(--bs-gray-bright); } .text-gray { color: var(--bs-gray-medium); } .text-gray-medium { color: var(--bs-gray-medium); } .text-gray-light { color: var(--bs-gray-light); } .bg-dark { background-color: var(--bs-gray-dark) !important; } @media screen and (--xs-to-sm) { .d-xs-none { display: none !important; } .d-xs-inline { display: inline !important; } } /* breakpoint lg */ @media (--lg-and-up) { .modal-lg, .modal-xl { --bs-modal-width: 850px; } .w-lg-auto { width: auto !important; } } .modal-backdrop.show { opacity: 1; } .modal-backdrop { --bs-backdrop-bg: var(--evcc-backdrop); backdrop-filter: var(--evcc-backdrop-blur); } .modal-backdrop.fade { transition-property: opacity, backdrop-filter, background-color; transition-duration: var(--evcc-transition-fast); transition-timing-function: linear; } .modal.fade-left .modal-dialog { transform: translate(-50px, 0); } .modal.fade-right .modal-dialog { transform: translate(50px, 0); } .modal.show .modal-dialog { transform: none; } .modal-header { padding: 0 0 1rem 0; border: none; } .modal-title { font-weight: bold; font-size: 1.25rem; } .modal-content { border-radius: 1rem; padding: 1.25rem; background-color: var(--evcc-box); color: var(--evcc-default-text); } .modal-content h6 { margin-top: 2rem; margin-bottom: 1.5rem; font-size: 1rem; font-weight: bold; } /* breakpoint sm */ @media (--sm-and-up) { .modal-content { padding: 2rem; } } .modal { /* prevent touch-scroll chaining from the modal to on iOS Safari */ overscroll-behavior: contain; } .modal-body { padding: 1rem 0 0; } .modal-footer { padding: 1rem 0 0; border: none; } .modal-footer > * { margin: 0; } html:has(.modal.show) { overflow-y: hidden; } /* Safari renders non-overlay scrollbars above modal backdrops at compositor level */ body.modal-open .scroll-overlay-fix { scrollbar-color: transparent transparent; } .cursor-pointer { cursor: pointer; } .v-popper__inner { margin: 0 12px !important; } .small, small { font-size: var(--bs-body-font-size); color: var(--bs-gray-medium) !important; } .btn-close { opacity: 1; } .dark .btn-close { filter: invert(1); } .circle-badge { display: inline-block; width: 12px; height: 12px; border-radius: 50%; } .dropdown-menu { border: none; border-radius: 10px; box-shadow: 0 0 8px var(--bs-gray-light); background-color: var(--evcc-box); } .dropdown-item { color: var(--evcc-default-text); } .dropdown-item:active, .dropdown-item.active { background-color: var(--evcc-gray-25); color: var(--evcc-default-text); } .form-select { overflow: hidden; text-overflow: ellipsis; } .form-select.disabled, .form-select:disabled { background-color: var(--bs-secondary-bg); } .dark .dropdown-menu { box-shadow: 0 0 8px var(--evcc-background); } .dark .form-select { background-color: var(--evcc-box); color: var(--evcc-default-text); background-image: url("data:image/svg+xml,"); } .dark .text-muted { color: var(--bs-gray-medium) !important; } .dark .form-select.disabled, .dark .form-select:disabled { opacity: 0.5; } .dark .table { --bs-table-color: var(--evcc-default-text); --bs-table-border-color: var(--evcc-gray); } .nav-tabs .nav-link { color: var(--evcc-gray) !important; } .nav-tabs .nav-link.active { color: var(--evcc-default-text) !important; background-color: var(--evcc-box) !important; border-bottom-color: var(--evcc-box); } .form-check-input:checked { border-color: var(--bs-primary); background-color: var(--bs-primary); } .dark .form-switch .form-check-input:checked { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2328293e'/%3e%3c/svg%3e"); } /* fix desktop safari formatting */ input::-webkit-datetime-edit { display: block; padding: 0; } .tooltip { --bs-tooltip-opacity: 1; --bs-tooltip-bg: var(--bs-gray-deep); --bs-tooltip-color: var(--bs-white); } .dark .tooltip { --bs-tooltip-bg: var(--bs-white); --bs-tooltip-color: var(--bs-gray-deep); } .card { --bs-card-bg: var(--evcc-background); } .form-control { color: var(--evcc-default-text); } input.form-control:disabled, input.form-control:read-only, textarea.form-control:disabled, textarea.form-control:read-only, .dark input.form-control:disabled, .dark input.form-control:read-only, .dark textarea.form-control:disabled, .dark textarea.form-control:read-only { background-color: var(--evcc-gray-10); color: var(--bs-default-text); opacity: 1; } .dark .form-control { background-color: var(--evcc-box); color: var(--evcc-default-text); } .form-control::placeholder { opacity: 0.5 !important; } input[type="time"]::-webkit-calendar-picker-indicator { display: none; } /* Safari: hide the datalist dropdown button */ input[list]::-webkit-list-button { display: none !important; appearance: none !important; opacity: 0 !important; width: 0 !important; pointer-events: none !important; } .form-control-clear { position: absolute; right: 0; top: 0; bottom: 0; justify-content: center; display: flex; align-items: center; justify-self: center; width: 36px; height: 100%; border: none; background-color: transparent; background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M 2,3 L 12,13 M 12,3 L 2,13'/%3e%3c/svg%3e"); background-repeat: no-repeat; background-position: calc(50% - 3px) center; background-size: 0.75rem; padding: 0; cursor: pointer; } .dark .form-control-clear { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1 0 16 16'%3e%3cpath fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M 2,3 L 12,13 M 12,3 L 2,13'/%3e%3c/svg%3e"); } /* hide dropdown arrow if clear is visible */ .form-select.has-clear-button { background-image: none; } .table { --bs-table-bg: transparent; } .badge { --bs-badge-font-size: 0.8rem; --bs-badge-padding-x: 0.75em; --bs-badge-padding-y: 0.75em; font-weight: normal; } /* larger check switch */ .form-switch .form-check-input { height: 1.1rem; width: calc(1.2rem + 0.75rem); border-radius: 3rem; } .form-switch .form-check-input + .form-check-label { margin-top: 0.1rem; padding-left: 0.5rem; } @media (--sm-and-up) { .w-sm-100 { width: 100% !important; } .w-sm-50 { width: 50% !important; } .w-sm-25 { width: 25% !important; } } html.app .hide-in-app { display: none !important; } .safe-area-inset { padding: max(1rem, var(--safe-area-inset-top)) var(--safe-area-inset-right) calc(var(--safe-area-inset-bottom) + var(--bottom-space)) var(--safe-area-inset-left); position: relative; } .safe-area-inset::before { content: ""; display: block; position: fixed; top: 0; left: 0; right: 0; height: var(--safe-area-inset-top); z-index: 1000; opacity: 0.9; background-color: var(--evcc-background); } html.app .modal-dialog { margin-top: var(--safe-area-inset-top); margin-bottom: var(--safe-area-inset-bottom); } .btn-neutral { all: unset; } .btn-neutral:hover { outline: revert; } .round-box { border-radius: 1rem; color: var(--evcc-default-text); background: var(--evcc-box); padding: 1rem; } .round-box--error { box-shadow: 0 0 0.5rem var(--bs-danger); border: 1px solid var(--bs-danger); } .round-box--error .tags * { color: var(--bs-danger-text-emphasis) !important; } .dark .round-box--error { box-shadow: 0 0 0.5rem var(--bs-danger); border: 1px solid var(--bs-danger); } .dark .round-box--error .tags * { color: var(--bs-danger) !important; } .round-box--warning { box-shadow: 0 0 0.5rem var(--bs-warning); border: 1px solid var(--bs-warning); } .round-box--warning .tags * { color: var(--bs-warning-text-emphasis) !important; } .dark .round-box--warning { box-shadow: 0 0 0.5rem var(--bs-warning); border: 1px solid var(--bs-warning); } .dark .round-box--warning .tags * { color: var(--bs-warning) !important; } .alert-danger code { color: var(--evcc-darkest-green); } .hyphenate { overflow-wrap: break-word; word-wrap: break-word; hyphens: auto; } input::-webkit-date-and-time-value { text-align: left; } @media (max-width: 576px) { .text-truncate-xs-only { overflow: hidden; text-overflow: ellipsis; } } .textarea--tiny { font-size: 8px; } @media (--sm-and-up) { .textarea--tiny { font-size: 0.875em; } } .tabular { font-variant-numeric: tabular-nums; } /* Collapsible wrapper pattern with choreographed animation */ .collapsible-wrapper { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--evcc-transition-fast) ease 0.2s; } .collapsible-wrapper.open { grid-template-rows: 1fr; transition: grid-template-rows var(--evcc-transition-fast) ease; } .collapsible-content { overflow: hidden; opacity: 0; transition: opacity 0.2s ease; } .collapsible-wrapper.open .collapsible-content { opacity: 1; transition: opacity var(--evcc-transition-fast) ease 0.2s; } .sticky-bottom { bottom: calc(var(--tab-bar-height) + 0.25rem); }