diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..917a558 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +styles/styles.css +styles/print.css +styles/embed.css +deps/* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e9c2176 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +# No default target to avoid this being mistaken as sufficient preparation for +# running the code (these styles depend on bootstrap, which needs to be +# downloaded, too; see bin/install-jsdeps.sh in the repo's root). + +css: + npx lessc --clean-css="--s1 --advanced" styles/styles.less > styles/styles.min.css + npx lessc --clean-css="--s1 --advanced" styles/print.less > styles/print.min.css + npx lessc --clean-css="--s1 --advanced" styles/embed.less > styles/embed.min.css diff --git a/fonts/fa-regular-400.woff b/fonts/fa-regular-400.woff new file mode 100644 index 0000000..43b1a9a Binary files /dev/null and b/fonts/fa-regular-400.woff differ diff --git a/fonts/fa-regular-400.woff2 b/fonts/fa-regular-400.woff2 new file mode 100644 index 0000000..b9344a7 Binary files /dev/null and b/fonts/fa-regular-400.woff2 differ diff --git a/fonts/fa-solid-900.woff b/fonts/fa-solid-900.woff new file mode 100644 index 0000000..77c1786 Binary files /dev/null and b/fonts/fa-solid-900.woff differ diff --git a/fonts/fa-solid-900.woff2 b/fonts/fa-solid-900.woff2 new file mode 100644 index 0000000..e30fb67 Binary files /dev/null and b/fonts/fa-solid-900.woff2 differ diff --git a/fonts/roboto-v29-italic-700.woff b/fonts/roboto-v29-italic-700.woff new file mode 100644 index 0000000..afecf26 Binary files /dev/null and b/fonts/roboto-v29-italic-700.woff differ diff --git a/fonts/roboto-v29-italic-700.woff2 b/fonts/roboto-v29-italic-700.woff2 new file mode 100644 index 0000000..385aa01 Binary files /dev/null and b/fonts/roboto-v29-italic-700.woff2 differ diff --git a/fonts/roboto-v29-italic.woff b/fonts/roboto-v29-italic.woff new file mode 100644 index 0000000..fd90554 Binary files /dev/null and b/fonts/roboto-v29-italic.woff differ diff --git a/fonts/roboto-v29-italic.woff2 b/fonts/roboto-v29-italic.woff2 new file mode 100644 index 0000000..d49ce7b Binary files /dev/null and b/fonts/roboto-v29-italic.woff2 differ diff --git a/fonts/roboto-v29-regular-700.woff b/fonts/roboto-v29-regular-700.woff new file mode 100644 index 0000000..60b7400 Binary files /dev/null and b/fonts/roboto-v29-regular-700.woff differ diff --git a/fonts/roboto-v29-regular-700.woff2 b/fonts/roboto-v29-regular-700.woff2 new file mode 100644 index 0000000..31abf9f Binary files /dev/null and b/fonts/roboto-v29-regular-700.woff2 differ diff --git a/fonts/roboto-v29-regular.woff b/fonts/roboto-v29-regular.woff new file mode 100644 index 0000000..d491906 Binary files /dev/null and b/fonts/roboto-v29-regular.woff differ diff --git a/fonts/roboto-v29-regular.woff2 b/fonts/roboto-v29-regular.woff2 new file mode 100644 index 0000000..55affe5 Binary files /dev/null and b/fonts/roboto-v29-regular.woff2 differ diff --git a/images/contactgroup.svg b/images/contactgroup.svg new file mode 100644 index 0000000..f8f9c21 --- /dev/null +++ b/images/contactgroup.svg @@ -0,0 +1,3 @@ + + + diff --git a/images/contactpic.svg b/images/contactpic.svg new file mode 100644 index 0000000..ea0dfe9 --- /dev/null +++ b/images/contactpic.svg @@ -0,0 +1,3 @@ + + + diff --git a/images/corner-handle.svg b/images/corner-handle.svg new file mode 100644 index 0000000..ecf8d06 --- /dev/null +++ b/images/corner-handle.svg @@ -0,0 +1,3 @@ + + + diff --git a/images/download.svg b/images/download.svg new file mode 100644 index 0000000..10fbd48 --- /dev/null +++ b/images/download.svg @@ -0,0 +1,3 @@ + + + diff --git a/images/favicon.ico b/images/favicon.ico new file mode 100644 index 0000000..9f8c783 Binary files /dev/null and b/images/favicon.ico differ diff --git a/images/google-icon.svg b/images/google-icon.svg new file mode 100644 index 0000000..e2c39ed --- /dev/null +++ b/images/google-icon.svg @@ -0,0 +1 @@ + diff --git a/images/logo.svg b/images/logo.svg new file mode 100644 index 0000000..e3ee3fe --- /dev/null +++ b/images/logo.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/images/microsoft-icon.svg b/images/microsoft-icon.svg new file mode 100644 index 0000000..25bec39 --- /dev/null +++ b/images/microsoft-icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/meta.json b/meta.json new file mode 100644 index 0000000..4b3f003 --- /dev/null +++ b/meta.json @@ -0,0 +1,20 @@ +{ + "name": "Elastic", + "author": "Aleksander Machniak", + "license": "Creative Commons Attribution-ShareAlike", + "license-url": "http://creativecommons.org/licenses/by-sa/3.0/", + "config": { + "supported_layouts": ["widescreen"], + "jquery_ui_colors_theme": "bootstrap", + "embed_css_location": "/styles/embed.css", + "editor_css_location": "/styles/embed.css", + "dark_mode_support": true, + "media_browser_css_location": "none", + "additional_logo_types": ["dark", "small", "small-dark"] + }, + "meta": { + "viewport": "width=device-width, initial-scale=1.0, shrink-to-fit=no, maximum-scale=1.0", + "theme-color": "#f4f4f4", + "msapplication-navbutton-color": "#f4f4f4" + } +} diff --git a/styles/colors.less b/styles/colors.less new file mode 100644 index 0000000..9e80c16 --- /dev/null +++ b/styles/colors.less @@ -0,0 +1,278 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +@color-main: #37beff; +@color-main-dark: darken(@color-main, 35%); +@color-black: #161b1d; +@color-font: lighten(@color-black, 10%); +@color-link: #00acff; +@color-link-hover: darken(@color-link, 10%); +@color-border: #ddd; +@color-error: #ff5552; +@color-success: #41b849; +@color-warning: #ffd452; + +@color-black-shade-text: tint(@color-black, 40%); +@color-black-shade-border: lighten(@color-black, 75%); +@color-black-shade-bg: lighten(@color-black, 85%); + + +// Layout elements +@color-layout-border: @color-black-shade-border; +@color-layout-header: @color-font; +@color-layout-sidebar-background: #fff; +@color-layout-list-background: #fff; +@color-layout-content-background: #fff; +@color-layout-header-background: #f4f4f4; +@color-layout-footer-background: #fff; + +@color-layout-mobile-header-background: @color-layout-header-background; +@color-layout-mobile-footer-background: @color-layout-header-background; + +// Task menu +@color-taskmenu-background: #2f3a3f; +@color-taskmenu-button: #fff; +@color-taskmenu-button-selected: @color-taskmenu-button; +@color-taskmenu-button-action: @color-main; + +@color-taskmenu-button-selected-background: lighten(@color-taskmenu-background, 10%); +@color-taskmenu-button-action-background: transparent; + +@color-taskmenu-button-hover: #fff; +@color-taskmenu-button-selected-hover: #fff; +@color-taskmenu-button-action-hover: @color-main; + +@color-taskmenu-button-background-hover: lighten(@color-taskmenu-background, 10%); +@color-taskmenu-button-action-background-hover: @color-taskmenu-button-background-hover; +@color-taskmenu-button-logout: @color-error; +@color-taskmenu-button-logout-hover: @color-error; + + +// Toolbar +@color-toolbar-button: @color-font; +@color-toolbar-button-background-hover: darken(@color-layout-header-background, 3%); + +@color-searchbar-background: #fbfbfb; + +// Toolbar menu +@color-menu-hover: #fff; +@color-menu-hover-background: @color-main; + + +// Listings +@color-list: @color-font; +@color-list-selected: @color-font; +@color-list-selected-background: tint(@color-main, 90%); +@color-list-flagged: @color-error; +@color-list-deleted: fadeout(@color-font, 50%); +@color-list-secondary: @color-black-shade-text; +@color-list-droptarget-background: #ffffcc; +@color-list-focus-indicator: lighten(@color-main, 20%); + +@color-list-border: @color-black-shade-bg; +@color-list-badge: #fff; +@color-list-badge-background: @color-main; +@color-list-recent: darken(@color-main, 20%); +@color-list-recent-badge: #fff; +@color-list-recent-badge-background: @color-main; + +@color-list-pagenav: @color-black-shade-text; +@color-list-icon: fadeout(@color-list-secondary, 25%); +@color-list-unread-status: @color-warning; + +@color-attachmentlist-border: #f4f4f4; +@color-attachmentlist-background: #fcfcfc; + +// Drag-n-drop layer +@color-drag-layer: #fff; +@color-drag-layer-background: @color-taskmenu-background; +@color-drag-layer-shadow: @color-black-shade-bg; + + +// Messages +@color-message: @color-font; +@color-message-border: transparent; +@color-message-background: fadeout(@color-main, 95%); +@color-message-text: #fff; +@color-message-link: @color-main; +@color-message-link-font-weight: normal; +@color-message-information: @color-main; +@color-message-success: @color-success; +@color-message-warning: @color-warning; +@color-message-error: @color-error; +@color-message-loading: tint(@color-font, 30%); +@color-message-information-text: @color-message-text; +@color-message-success-text: @color-message-text; +@color-message-warning-text: @color-message; +@color-message-error-text: @color-message-text; +@color-message-loading-text: @color-message-text; +@color-message-error-box: @color-message; +@color-message-information-box: @color-message; +@color-message-success-box: @color-message; +@color-message-warning-box: @color-message; +@color-message-error-box-background: fadeout(@color-message-error, 80%); +@color-message-information-box-background: fadeout(@color-message-information, 80%); +@color-message-success-box-background: fadeout(@color-message-success, 80%); +@color-message-warning-box-background: fadeout(@color-message-warning, 80%); + + +// Popovers (menus) +@color-popover-shadow: @color-black-shade-bg; +@color-popover-separator: @color-black-shade-text; +@color-popover-separator-background: @color-black-shade-bg; +@color-popover-mobile-header: #fff; +@color-popover-mobile-header-background: @color-main-dark; +@color-popover-mobile-dropbutton-background: #f6f6f6; + +// Dialogs +@color-dialog-overlay-background: fade(@color-font, 50%); +@color-dialog-header: @color-layout-header; +@color-dialog-header-border: @color-border; + + +@color-spinner-circle: @color-black-shade-bg; +@color-spinner-item: @color-black-shade-text; + + +// Forms +@color-input: @color-font; +@color-input-border: #ced4da; // from Bootstrap's .form-control +@color-input-border-focus: @color-main; +@color-input-border-focus-shadow: fadeout(@color-main, 75); +@color-input-border-invalid: @color-error; +@color-input-border-invalid-shadow: fadeout(@color-error, 75); +@color-input-addon-background: @color-black-shade-bg; +@color-recipient-input-border: @color-input-border; +@color-recipient-input-background: @color-black-shade-bg; +@color-input-placeholder: #bbb; + +@color-checkbox: @color-main; +@color-checkbox-checked: @color-main; +@color-checkbox-checked-disabled: lighten(@color-main, 15%); +@color-checkbox-focus: @color-input-border-focus; +@color-checkbox-focus-shadow: @color-input-border-focus-shadow; + +@color-form-hint: @color-black-shade-text; + +@color-image-upload-background: #f4f4f4; + +@color-btn-secondary: #fff; +@color-btn-secondary-background: lighten(@color-black, 50%); +@color-btn-primary: #fff; +@color-btn-primary-background: @color-main; +@color-btn-danger: #fff; +@color-btn-danger-background: @color-error; + +@color-quota-background: #fff; +@color-quota-text: @color-black-shade-text; +@color-quota-value: @color-main; +@color-quota-value-warning: @color-error; + +@color-blockquote-background: fadeout(@color-black-shade-bg, 50%); +@color-blockquote-0: darken(@color-main, 30%); +@color-blockquote-1: darken(@color-success, 25%); +@color-blockquote-2: darken(@color-error, 20%); +@color-blockquote-0-border: @color-blockquote-0; +@color-blockquote-1-border: @color-blockquote-1; +@color-blockquote-2-border: @color-blockquote-2; + +@color-mail-signature: @color-black-shade-text; +@color-mail-headers: @color-black-shade-text; + +@color-messagepart-border: #f4f4f4; +@color-messagepart-background: #fcfcfc; + +@color-spellcheck-link: @color-error; + +@color-table-border: @color-layout-border; +@color-table-selected: @color-list-selected; +@color-table-selected-background: @color-list-selected-background; + + +// Datepicker +@color-datepicker-border: @color-layout-border; +@color-datepicker-font: @color-font; +@color-datepicker-highlight: @color-main; +@color-datepicker-highlight-background: lighten(@color-main, 30%); +@color-datepicker-active: #fff; +@color-datepicker-active-background: @color-main; + + +// HTML editor +@color-editor-disabled-mask: fadeout(lighten(@color-black, 85), 10); + + +// Image tools +@color-image-tools: #fff; +@color-image-tools-background: fadeout(@color-main, 60%); +@color-image-tools-hover: fadeout(@color-main, 50%); + + +// Scrollbars +@color-scrollbar-thumb: #c1c1c1; +@color-scrollbar-track: #f1f1f1; + + +// Dark mode colors +@color-dark-main: darken(@color-main, 30%); +@color-dark-background: #21292c; +@color-dark-font: #c5d1d3; +@color-dark-border: #4d6066; +@color-dark-hint: darken(@color-dark-font, 20%); +@color-dark-information: shade(@color-main, 40%); +@color-dark-success: shade(@color-success, 40%); +@color-dark-warning: shade(@color-warning, 40%); +@color-dark-error: shade(@color-error, 40%); + +@color-dark-list-selected: @color-main; +@color-dark-list-selected-background: #374549; +@color-dark-list-badge: lighten(@color-dark-font, 10%); +@color-dark-list-badge-background: @color-dark-border; +@color-dark-list-deleted: darken(@color-dark-hint, 15%); +@color-dark-list-droptarget-background: #4d4d00; +@color-dark-list-border: #2c373a; + +@color-dark-input: @color-dark-font; +@color-dark-input-border: #7c949c; +@color-dark-input-background: @color-dark-background; +@color-dark-input-focus: #e2e7e9; +@color-dark-input-border-focus: @color-main; +@color-dark-input-background-focus: lighten(@color-dark-background, 5%); +@color-dark-input-addon-background: #374549; +@color-dark-input-addon-background-focus: lighten(@color-dark-list-selected-background, 15%); +@color-dark-checkbox: @color-dark-border; +@color-dark-checkbox-checked: @color-dark-main; + +@color-dark-btn: lighten(@color-dark-font, 10%); +@color-dark-btn-primary-background: @color-dark-main; +@color-dark-btn-secondary-background: @color-dark-border; +@color-dark-btn-danger-background: @color-dark-error; + +@color-dark-dialog-overlay-background: fade(black, 70%); + +@color-dark-popover-background: #161b1d; +@color-dark-popover-border: lighten(#161b1d, 50%); + +@color-dark-message-information: @color-dark-information; +@color-dark-message-success: @color-dark-success; +@color-dark-message-warning: @color-dark-warning; +@color-dark-message-error: @color-dark-error; +@color-dark-message-loading: lighten(@color-dark-background, 10%); + +@color-dark-scrollbar-thumb: darken(@color-main, 25%); +@color-dark-scrollbar-track: @color-dark-border; + +@color-dark-blockquote-0: lighten(@color-main, 10%); +@color-dark-blockquote-1: lighten(@color-success, 10%); +@color-dark-blockquote-2: lighten(@color-error, 10%); +@color-dark-blockquote-0-border: @color-dark-blockquote-0; +@color-dark-blockquote-1-border: @color-dark-blockquote-1; +@color-dark-blockquote-2-border: @color-dark-blockquote-2; diff --git a/styles/dark.less b/styles/dark.less new file mode 100644 index 0000000..6c78e96 --- /dev/null +++ b/styles/dark.less @@ -0,0 +1,1137 @@ +/** + * Roundcube webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +@import (reference) "variables"; + +html.dark-mode { + scrollbar-color: @color-dark-scrollbar-thumb @color-dark-scrollbar-track; + + &:not(.touch) { + ::-webkit-scrollbar-track { + background-color: @color-dark-scrollbar-track; + } + + ::-webkit-scrollbar-thumb { + background-color: @color-dark-scrollbar-thumb; + } + } + + body { + color: @color-dark-font; + background-color: @color-dark-background; + } + + #logo { + // FIXME: is there a better way to make the logo darker? + // `mix-blend-mode: soft-light` makes it slightly too dark + opacity: .8; + } + + #layout-list, + #layout-content, + #layout-sidebar, + #layout > div > .header, + #layout > div > .footer, + .popup .listbox .footer, + .menu.pagenav.pagenav-list, + .menu.pagenav.pagenav-list + .navlist, + .menu.pagenav.pagenav-list.expanded + .navlist { + background-color: transparent; + border-color: @color-dark-border; + } + + #layout > div > .footer { + font-weight: normal; + } + + #layout > div > .header, + #layout > div > .footer { + color: unset; + + a.button { + color: @color-dark-font; + } + } + + #layout-menu { + background: unset; + border-right: 1px solid @color-dark-border; + + .popover-header, + .special-buttons { + background: transparent !important; + } + + @media screen and (max-width: @screen-width-xs) { + border-left: 0; + + .popover-header { + border-bottom: 1px solid @color-dark-border; + } + } + + .special-buttons a:not(:focus) { + background: @color-dark-background; + } + } + + &.layout-phone #layout-menu { + background: @color-dark-popover-background; + } + + .searchbar { + background-color: transparent; + border-color: @color-dark-border; + + form:before, + a, + input { + color: unset; + } + + a.selected { + color: @color-success; + } + } + + #messagestack { + div { + color: @color-dark-font; + + i.icon:before { + color: @color-dark-font; + } + } + } + + .ui.alert.boxinformation, + #messagestack .alert-info { + background-color: @color-dark-message-information; + } + + .ui.alert.boxerror, + #messagestack .alert-danger { + background-color: @color-dark-message-error; + } + + .ui.alert.boxwarning, + #messagestack .alert-warning { + background-color: @color-dark-message-warning; + } + + .ui.alert.boxconfirmation, + #messagestack .alert-success { + background-color: @color-dark-message-success; + } + + #messagestack .loading { + background-color: @color-dark-message-loading; + } + + .ui.alert.boxinformation, + .ui.alert.boxerror, + .ui.alert.boxwarning, + .ui.alert.boxconfirmation { + color: @color-dark-font; + i.icon:before { + color: @color-dark-font; + } + } + + .ui.alert a:not(.btn) { + color: @color-dark-font; + text-decoration: underline; + } + + .iframe-loader { + background-color: fadeout(@color-dark-background, 10%); + + .spinner-border { + color: darken(@color-dark-font, 25%); + border-color: currentColor darken(@color-dark-font, 50%) currentColor currentColor; + } + } + + #taskmenu a, + .menu.toolbar a { + color: @color-dark-font; + + &.selected { + background-color: @color-dark-list-selected-background; + } + } + + pre, + .popover .menu li a[aria-haspopup]::after, + .menu.pagenav .pagenav-text, + .menu.pagenav a { + color: unset; + } + + #taskmenu { + .action-buttons a { + color: @color-main; + } + + a { + @media screen and (max-width: @screen-width-xs) { + border-color: @color-dark-list-border !important; + + &.selected { + background: transparent; + } + } + + @media screen and (min-width: (@screen-width-xs + 1px)) and (max-width: @screen-width-medium) { + width: @layout-menu-width-sm - 1px; + } + + @media screen and (min-width: (@screen-width-medium + 1px)) { + width: @layout-menu-width - 1px; + } + } + } + + &.layout-small, + &.layout-phone { + .popover { + border-left: 1px solid @color-dark-border; + + .menu .dropbutton a.dropdown { + background: transparent; + } + + &:not(.select-menu) .listing li:last-child { + border-color: @color-dark-list-border; + } + } + + .popover-header { + background: @color-dark-popover-background; + border-bottom: 1px solid @color-dark-border; + color: unset; + } + + .popover-overlay { + background: @color-dark-dialog-overlay-background; + } + } + + #taskmenu a:hover, + .popupmenu .listing li > a:not(.disabled):hover, + .header a.button.icon:not(.disabled):focus, + .header a.button.icon:not(.disabled):hover, + .menu.toolbar .dropbutton:not(.disabled):hover, + .menu a:not(.disabled):focus, + .menu a:not(.disabled):hover { + background-color: @color-dark-list-selected-background; + } + + .menu.toolbar a.selected { + color: @color-success; + background: transparent; + } + + .menu.toolbar .dropbutton a.dropdown:hover { + background-color: lighten(@color-dark-list-selected-background, 5%); + } + + // --------------------------------- + // Lists + // --------------------------------- + + .proplist li.with-sublist > a.dropdown, + .listing tbody td, + .listing tbody td a, + .listing li a { + color: @color-dark-font; + } + + .listing li ul, + .listing tbody td, + .listing li { + border-color: @color-dark-list-border; + } + + .listing li.selected, + .listing li.selected > a, + .listing li.selected > div > a, // this is used e.g. by kolab_addressbook + .listing tr.selected td { + color: @color-dark-list-selected; + background-color: @color-dark-list-selected-background; + } + + .listing li.selected ul { + background-color: @color-dark-background; + + div.treetoggle { + color: @color-dark-font; + } + } + + .listing { + li.disabled, + tr.disabled td { + color: @color-dark-list-deleted; + } + } + + .listing li.droptarget > a, + .listing tr.droptarget > td { + background-color: @color-dark-list-droptarget-background; + } + + .messagelist { + color: @color-dark-font; + + tr:not(.flagged):not(.deleted) { + td.subject { + span.size, + span.date, + span.fromto { + color: @color-dark-hint; + } + + span.msgicon.status { + color: @color-dark-font; + } + } + + span.flag { + color: @color-dark-font; + } + + &.selected { + td.subject { + a, + span.msgicon.status { + color: @color-dark-list-selected; + } + } + } + } + + tr.flagged:not(.deleted) { + td, + span.attachment span { + color: @color-list-flagged; + } + } + + tr.deleted { + td span.flag, + td span.attachment span, + td.subject span.msgicon.status, + td.subject span.msgicon.status.unread:before, + td.subject span.subject a, + td.subject span.date, + td.subject span.fromto { + color: @color-dark-list-deleted; + } + } + + span.attachment span { + color: @color-dark-hint; + } + } + + .folderlist li.mailbox .unreadcount { + background-color: @color-dark-list-badge-background; + color: @color-dark-list-badge; + font-weight: normal; + } + + .attachmentslist { + background-color: @color-dark-list-selected-background; + border: 0; + + a { + color: @color-dark-font; + } + + li { + .attachment-name { + color: @color-dark-font; + } + + .attachment-size { + color: @color-dark-hint; + } + } + } + // --------------------------------- + // Buttons & Forms + // --------------------------------- + + .btn { + color: @color-dark-font; + + &:focus, + &:hover { + color: @color-dark-btn; + } + + &:disabled { + opacity: .5 !important; + } + } + + .btn-primary { + background-color: @color-dark-btn-primary-background; + color: @color-dark-btn; + + &:hover:not(:disabled) { + background-color: lighten(@color-dark-btn-primary-background, 5%); + } + } + + .btn-secondary { + background-color: @color-dark-btn-secondary-background; + color: @color-dark-btn; + + &:hover:not(:disabled) { + background-color: lighten(@color-dark-btn-secondary-background, 5%); + } + } + + .btn-danger { + background-color: @color-dark-btn-danger-background; + color: @color-dark-btn; + + &:hover:not(:disabled) { + background-color: lighten(@color-dark-btn-danger-background, 5%); + } + } + + .floating-action-buttons a.button { + box-shadow: none; + background: @color-dark-main; + } + + .custom-file-label, + .form-control { + background-color: @color-dark-input-background; + color: @color-dark-input; + + &:not(.is-invalid) { + border-color: @color-dark-input-border; + } + + &:focus { + background-color: @color-dark-input-background-focus; + + &:not(.is-invalid) { + color: @color-dark-input-focus !important; + border-color: @color-dark-input-border-focus; + } + } + } + + .custom-file-label::after { + color: @color-dark-input; + background-color: @color-dark-input-addon-background; + } + + .custom-select { + @color-arrow: escape(~"@{color-dark-input}"); + background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='@{color-arrow}' viewBox='0 0 4 5'%3e%3cpath d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px; + } + + .custom-switch { + .custom-control-label::before { + background-color: @color-dark-checkbox; + } + + .custom-control-label::after { + background-color: @color-dark-font; + } + + .custom-control-input:disabled ~ .custom-control-label { + opacity: .4; + } + + .custom-control-input:checked { + & ~ .custom-control-label::before { + background-color: @color-dark-checkbox-checked; + } + + & ~ .custom-control-label::after { + background-color: @color-dark-font; + } + } + } + + input:disabled, + select:disabled { + opacity: .5; + } + + .multi-input:not(.is-invalid) > .content { + border-color: @color-dark-input-border; + + &.focused { + border-color: @color-dark-input-border-focus; + } + } + + .input-group-text { + color: @color-dark-input; + background-color: @color-dark-input-addon-background; + border-color: @color-dark-input-border; + } + + .input-group a:focus { + border-color: @color-dark-input-border-focus; + box-shadow: 0 0 0 .2rem @color-input-border-focus-shadow; + z-index: 1; + } + + .form-control-plaintext { + color: unset; + } + + .recipient-input { + &.focus { + color: @color-dark-input-focus; + background-color: @color-dark-input-background-focus; + border-color: @color-dark-input-border-focus; + } + + a.button.icon, + input { + color: @color-dark-input; + } + + .recipient { + background-color: @color-dark-input-addon-background; + border-color: @color-dark-input-border; + } + } + + .file-upload { + border-color: @color-dark-border; + + &:after { + mix-blend-mode: soft-light; + } + + &.droptarget { + &.active { + border-color: @color-dark-font; + } + + &.hover { + border-color: @color-dark-font; + background-color: @color-dark-list-selected-background; + } + } + + .attachmentslist { + background: transparent; + } + } + + .image-upload { + background-color: @color-dark-list-selected-background; + + a.button { + background-color: fadeout(@color-dark-background, 75%); + } + } + + .formcontent.raweditor { + .CodeMirror { + color: @color-dark-input; + background-color: @color-dark-input-background; + border-color: @color-dark-input-border; + } + + .CodeMirror-focused { + background-color: @color-dark-input-background-focus; + border-color: @color-dark-input-border-focus; + } + } + + .CodeMirror-selected, + .CodeMirror-line::selection, + .CodeMirror-line > span::selection, + .CodeMirror-line > span > span::selection { + background: @color-dark-list-selected-background; + } + + .CodeMirror-gutters { + background-color: darken(@color-dark-list-selected-background, 10%); + border: 0; + } + + .CodeMirror-activeline-background { + background: @color-dark-list-selected-background; + } + + .skinselection .skinthumbnail { + border-color: @color-dark-input-border; + background: transparent; + } + + // --------------------------------- + // HTML Editor (TinyMCE) + // --------------------------------- + + .html-editor { + .editor-toolbar { + background-color: @color-dark-input-addon-background; + border-color: @color-dark-input-border; + + .mce-i-html { + color: unset; + + &:hover, + &:focus { + background-color: @color-dark-input-addon-background-focus; + border-color: transparent; + } + } + } + } + + .tox { + &.tox-tinymce { + border-color: @color-dark-input-border; + } + + .tox-toolbar { + background-color: @color-dark-input-addon-background; + border-color: @color-dark-input-border; + } + + .tox-toolbar-overlord > div { + @color-overlord-border: escape(~"@{color-dark-input-border}"); + background: url("data:image/svg+xml,%3Csvg height='33px' viewBox='0 0 40 33px' width='40' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0' y='32px' width='100' height='1' fill='@{color-overlord-border}'/%3E%3C/svg%3E") @color-dark-input-addon-background; + } + + .tox-pop.tox-pop--top { + &:before, + &:after { + border-bottom-color: @color-dark-popover-border; + } + } + + .tox-pop__dialog { + box-shadow: none; + border-color: @color-dark-popover-border; + } + + .tox-tbtn, + .tox-split-button, + .tox-swatches__picker-btn { + color: @color-dark-font; + + svg { + fill: @color-dark-font !important; + } + + &:hover, + &:focus { + color: @color-dark-font; + background: @color-dark-input-addon-background-focus; + box-shadow: none; + } + } + + .tox-tbtn--enabled { + background: @color-dark-input-addon-background-focus; + } + + .tox-button--naked { + &:focus:not(:disabled), + &.tox-button--icon:hover:not(:disabled) { + color: lighten(@color-dark-font, 5%); + background-color: @color-dark-input-addon-background-focus; + border-color: transparent; + } + + &:disabled { + background: transparent; + border: transparent; + } + } + + .tox-dialog__header .tox-button--naked:hover { + background: transparent !important; + } + + .tox-selectfield { + select { + background: transparent; + color: @color-dark-input; + } + + svg { + fill: @color-dark-input; + } + } + + .tox-color-input span::before { + background-color: @color-dark-font; + } + + .tox-toolbar__group:not(:last-of-type) { + border-color: @color-dark-input-border; + } + + .tox-dialog, + .tox-dialog__header, + .tox-dialog__body, + .tox-dialog__footer, + .tox-dialog__title { + color: @color-dark-font; + border-color: @color-dark-border; + background-color: @color-dark-background; + } + + .tox-textfield, + .tox-color-input > input, + .tox-label, + .tox-dialog__body-nav-item, + .tox-button--naked, + .tox-dialog__header .tox-button, + .tox-insert-table-picker__label { + color: @color-dark-font; + } + + .tox-dialog__footer .tox-button { + background-color: @color-dark-btn-primary-background; + color: @color-dark-btn; + + &:disabled { + opacity: .5; + } + + @media screen and (max-width: @screen-width-xs) { + color: @color-dark-font !important; + } + + &:focus:not(:disabled) { + background-color: @color-dark-btn-primary-background; + } + + &:hover:not(:disabled) { + background-color: lighten(@color-dark-btn-primary-background, 5%); + } + + &.tox-button--secondary { + background-color: @color-dark-btn-secondary-background; + color: @color-dark-btn; + + &:focus:not(:disabled) { + background-color: @color-dark-btn-secondary-background; + } + + &:hover:not(:disabled) { + background-color: lighten(@color-dark-btn-secondary-background, 5%); + } + + } + } + + .tox-dialog__body-nav-item--active { + color: @color-main; + } + + .tox-dialog-wrap__backdrop { + background-color: @color-dark-dialog-overlay-background; + } + + .tox-menu { + background-color: @color-dark-popover-background; + border-color: @color-dark-popover-border; + box-shadow: none; + } + + .tox-collection__item-caret svg { + fill: @color-dark-font; + } + + .tox-collection__item { + color: @color-dark-font; + + &:not(:last-child) { + border-bottom: 1px solid @color-dark-list-border; + } + } + + .tox-collection--grid .tox-collection__item { + border: 0; + } + + .tox-collection__item--active, + .tox-collection__item--active:not(.tox-collection__item--state-disabled) { + color: @color-dark-font; + background-color: @color-dark-list-selected-background; + } + + .tox-collection__item--enabled { + color: @color-dark-list-selected; + background-color: @color-dark-list-selected-background; + } + } + + // --------------------------------- + // Mail preview + // --------------------------------- + + .message-part, + .message-htmlpart { + border-color: @color-dark-border; + + blockquote { + background-color: @color-dark-background; + border-color: @color-dark-blockquote-0-border; + color: @color-dark-blockquote-0; + + span.blockquote-link { + color: currentColor; + background: @color-dark-background; + border-color: currentColor; + } + + blockquote { + color: @color-dark-blockquote-1; + border-color: @color-dark-blockquote-1-border; + + blockquote { + color: @color-dark-blockquote-2; + border-color: @color-dark-blockquote-2-border; + } + } + } + } + + .message-part { + span.sig { + color: @color-dark-hint; + } + } + + .message-htmlpart { + background-color: white; + color: @color-font; + padding: 0; + margin-top: .5rem; + } + + #message-header .header-headers .header-title { + color: @color-dark-font; + font-weight: normal; + } + + .message-partheaders { + background-color: @color-dark-list-selected-background; + border: 0; + + table.headers-table { + color: @color-dark-font; + + * { + font-weight: normal; + } + } + } + + // this is when image thumbnails are enabled + p.image-attachment { + border-color: @color-dark-border; + background-color: @color-dark-list-selected-background; + + span { + color: @color-dark-hint; + } + } + + // this is when image thumbnails are disabled + fieldset.image-attachment { + legend { + color: @color-dark-hint; + border-color: @color-dark-border; + } + } + + // Attachment preview + #messagepartframe { + background: #fff; + } + + // ---------------------------------- + // jQuery-UI widgets' style overrides + // ---------------------------------- + + .ui-widget { + border-color: @color-dark-border; + } + + .ui-widget-overlay { + background-color: @color-dark-dialog-overlay-background; + } + + .ui-widget-header, + .ui-widget-content { + background-color: @color-dark-background; + } + + .ui-dialog { + .ui-dialog-titlebar { + border-color: @color-dark-border; + } + + .ui-dialog-title, + .ui-dialog-titlebar-close { + color: @color-dark-font; + background: transparent; + } + + .ui-dialog-buttonpane { + border-color: @color-dark-border; + + .ui-dialog-buttonset { + a.btn-link { + color: @color-dark-font; + + &:focus { + background: transparent; + } + } + + @media screen and (max-width: @screen-width-xs) { + button.btn-primary:not(.btn-danger), + button.btn-secondary { + color: @color-dark-font; + } + } + } + } + } + + .ui-datepicker { + .ui-datepicker-header { + border-color: @color-dark-border; + } + + th { + color: @color-dark-hint; + font-size: 80%; + font-weight: normal; + } + + .ui-datepicker-prev, + .ui-datepicker-next, + .ui-state-default, + &.ui-widget-content .ui-state-default { + color: @color-dark-font; + } + + .ui-state-highlight, + &.ui-widget-content .ui-state-highlight { + color: @color-main; + background-color: @color-dark-list-selected-background; + } + + .ui-datepicker-days-cell-over a { + background-color: lighten(@color-dark-list-selected-background, 10%); + } + } + + .ui-menu { + background-color: @color-dark-popover-background; + border-color: @color-dark-popover-border; + box-shadow: none; + + .ui-menu-item { + border-bottom: 1px solid @color-dark-list-border; + } + + .ui-state-active { + background-color: @color-dark-list-selected-background !important; + } + } + + .minicolors-panel { + box-shadow: none; + border-color: @color-dark-border; + background: @color-dark-popover-background; + } + + // --------------------------------- + // Other components + // --------------------------------- + + ::placeholder, + ::-webkit-input-placeholder, // Edge + .listing-info, + .listing span.secondary, + .file-upload .hint, + .contactlist span.email, + #login-footer, + #contacthead.readonly .source.row, + .formcontent .hint { + font-weight: normal; + color: @color-dark-hint; + } + + .popover { + background-color: @color-dark-popover-background; + border-color: @color-dark-popover-border; + box-shadow: none; + + .menu li.separator { + background-color: transparent; + color: darken(@color-dark-font, 20%); + } + + .menu ul + li.separator { + border-top: 1px solid @color-dark-list-border; + } + } + + .popover-body { + color: @color-dark-font; + } + + .bs-popover-auto[x-placement^="right"] > .arrow::after, + .bs-popover-right > .arrow::after { + border-right-color: @color-dark-popover-border; + } + + .bs-popover-auto[x-placement^="left"] > .arrow::after, + .bs-popover-left > .arrow::after { + border-left-color: @color-dark-popover-border; + } + + .bs-popover-auto[x-placement^="top"] > .arrow::after, + .bs-popover-top > .arrow::after { + border-top-color: @color-dark-popover-border; + } + + .bs-popover-auto[x-placement^="bottom"] > .arrow::after, + .bs-popover-bottom > .arrow::after { + border-bottom-color: @color-dark-popover-border; + } + + .listing-hover-menu { + background-color: @color-dark-popover-background; + border-color: @color-dark-border; + box-shadow: 0 0 5px black; + + a.button { + color: @color-dark-font; + + &:hover { + background: transparent; + } + } + + span.txt { + color: @color-dark-hint; + } + } + + .nav-tabs { + border-color: @color-dark-border; + + .nav-link { + color: @color-dark-font; + border-color: transparent; + border-bottom-color: @color-dark-border; + } + + .nav-link:hover { + background: @color-dark-background; + border-color: @color-dark-border; + color: @color-dark-font; + } + + .nav-link.active { + background: @color-dark-background; + border-color: @color-dark-border; + border-bottom-color: transparent; + color: #fff; + } + } + + .table { + color: @color-dark-font; + + td, + th, + thead th { + border-color: @color-dark-border; + } + } + + .table-widget { + border-color: @color-dark-border; + + & > .footer { + border-color: @color-dark-border; + } + + // Options table is a table with first column for identifier/description + // and other columns for a state flag. E.g. ACL table + table.options-table { + tr:last-child td { + border-color: @color-dark-border; + } + + tr.selected td { + background-color: @color-dark-list-selected-background; + color: @color-dark-font; + } + } + } + + #rcmdraglayer { + background-color: @color-dark-popover-background; + border: 1px solid @color-dark-popover-border; + box-shadow: none; + color: @color-dark-font; + } + + .quota-widget { + color: unset; + + .bar { + border-color: @color-dark-border; + background-color: @color-dark-border; + } + } + + .quota-info { + .root { + color: @color-dark-hint; + background-color: transparent; + } + } + + img.contactphoto, + #contactpic { + background-color: @color-dark-list-selected-background !important; + } + + .pgpkeyimport { + div.key.revoked, + div.key.disabled { + color: @color-dark-list-deleted; + } + + li.uid::before { + opacity: 1; + } + } +} diff --git a/styles/embed.less b/styles/embed.less new file mode 100644 index 0000000..8414779 --- /dev/null +++ b/styles/embed.less @@ -0,0 +1,95 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/* Style for embedded pages and TinyMCE editor content page */ + +@import "global"; + +.mce-content-body { + margin: 4px; + color: @color-input; + + div.pre { + font-family: monospace; + } + + blockquote { + border-left: #1010ff 2px solid; + margin: 0; + padding: 0 0.4em; + } +} + +.rcmail-inline-message { + .font-family(); + font-size: @page-font-size; + padding: .5em; + margin: 0 0 .5em 0; + opacity: .95; + color: @color-message; + background-color: @color-message-warning-box-background; + display: flex; + align-items: center; + + &:before { + .font-icon-class(); + font-size: 1.5em; + line-height: 1; + width: 1em; + margin-right: .3em; + content: @fa-var-exclamation-triangle; + color: @color-message-warning; + } + + span { + line-height: 1.5; + } + + a { + color: @color-link; + } + + a:hover { + color: @color-link-hover; + } + + button { + vertical-align: middle; + white-space: nowrap; + padding: .375em .75em; + margin-left: .5em; + font-size: 1em; + line-height: 1.5; + border-radius: .25em; + border: 1px solid transparent; + color: @color-btn-primary; + background: @color-btn-primary-background; + + &:focus { + box-shadow: 0 0 0 .2rem fade(@color-btn-primary-background, 50%); + } + + &:hover { + background: darken(@color-btn-primary-background, 8%); + border-color: darken(@color-btn-primary-background, 10%); + } + + &:not([disabled]):not(.disabled):active { + background: darken(@color-btn-primary-background, 11%); + border-color: darken(@color-btn-primary-background, 13%); + box-shadow: 0 0 0 .2rem fade(@color-btn-primary-background, 53%); + } + } +} + +.rcmail-inline-buttons { + margin: 0; +} diff --git a/styles/fontawesome.less b/styles/fontawesome.less new file mode 100644 index 0000000..7eaabf9 --- /dev/null +++ b/styles/fontawesome.less @@ -0,0 +1,1397 @@ +// Variables +// -------------------------- + +@fa-font-path: "../webfonts"; +@fa-font-size-base: 16px; +@fa-font-display: auto; +@fa-line-height-base: 1; +@fa-css-prefix: fa; +@fa-version: "5.9.0"; +@fa-border-color: #eee; +@fa-inverse: #fff; +@fa-li-width: 2em; + +@fa-var-500px: "\f26e"; +@fa-var-accessible-icon: "\f368"; +@fa-var-accusoft: "\f369"; +@fa-var-acquisitions-incorporated: "\f6af"; +@fa-var-ad: "\f641"; +@fa-var-address-book: "\f2b9"; +@fa-var-address-card: "\f2bb"; +@fa-var-adjust: "\f042"; +@fa-var-adn: "\f170"; +@fa-var-adobe: "\f778"; +@fa-var-adversal: "\f36a"; +@fa-var-affiliatetheme: "\f36b"; +@fa-var-air-freshener: "\f5d0"; +@fa-var-airbnb: "\f834"; +@fa-var-algolia: "\f36c"; +@fa-var-align-center: "\f037"; +@fa-var-align-justify: "\f039"; +@fa-var-align-left: "\f036"; +@fa-var-align-right: "\f038"; +@fa-var-alipay: "\f642"; +@fa-var-allergies: "\f461"; +@fa-var-amazon: "\f270"; +@fa-var-amazon-pay: "\f42c"; +@fa-var-ambulance: "\f0f9"; +@fa-var-american-sign-language-interpreting: "\f2a3"; +@fa-var-amilia: "\f36d"; +@fa-var-anchor: "\f13d"; +@fa-var-android: "\f17b"; +@fa-var-angellist: "\f209"; +@fa-var-angle-double-down: "\f103"; +@fa-var-angle-double-left: "\f100"; +@fa-var-angle-double-right: "\f101"; +@fa-var-angle-double-up: "\f102"; +@fa-var-angle-down: "\f107"; +@fa-var-angle-left: "\f104"; +@fa-var-angle-right: "\f105"; +@fa-var-angle-up: "\f106"; +@fa-var-angry: "\f556"; +@fa-var-angrycreative: "\f36e"; +@fa-var-angular: "\f420"; +@fa-var-ankh: "\f644"; +@fa-var-app-store: "\f36f"; +@fa-var-app-store-ios: "\f370"; +@fa-var-apper: "\f371"; +@fa-var-apple: "\f179"; +@fa-var-apple-alt: "\f5d1"; +@fa-var-apple-pay: "\f415"; +@fa-var-archive: "\f187"; +@fa-var-archway: "\f557"; +@fa-var-arrow-alt-circle-down: "\f358"; +@fa-var-arrow-alt-circle-left: "\f359"; +@fa-var-arrow-alt-circle-right: "\f35a"; +@fa-var-arrow-alt-circle-up: "\f35b"; +@fa-var-arrow-circle-down: "\f0ab"; +@fa-var-arrow-circle-left: "\f0a8"; +@fa-var-arrow-circle-right: "\f0a9"; +@fa-var-arrow-circle-up: "\f0aa"; +@fa-var-arrow-down: "\f063"; +@fa-var-arrow-left: "\f060"; +@fa-var-arrow-right: "\f061"; +@fa-var-arrow-up: "\f062"; +@fa-var-arrows-alt: "\f0b2"; +@fa-var-arrows-alt-h: "\f337"; +@fa-var-arrows-alt-v: "\f338"; +@fa-var-artstation: "\f77a"; +@fa-var-assistive-listening-systems: "\f2a2"; +@fa-var-asterisk: "\f069"; +@fa-var-asymmetrik: "\f372"; +@fa-var-at: "\f1fa"; +@fa-var-atlas: "\f558"; +@fa-var-atlassian: "\f77b"; +@fa-var-atom: "\f5d2"; +@fa-var-audible: "\f373"; +@fa-var-audio-description: "\f29e"; +@fa-var-autoprefixer: "\f41c"; +@fa-var-avianex: "\f374"; +@fa-var-aviato: "\f421"; +@fa-var-award: "\f559"; +@fa-var-aws: "\f375"; +@fa-var-baby: "\f77c"; +@fa-var-baby-carriage: "\f77d"; +@fa-var-backspace: "\f55a"; +@fa-var-backward: "\f04a"; +@fa-var-bacon: "\f7e5"; +@fa-var-balance-scale: "\f24e"; +@fa-var-balance-scale-left: "\f515"; +@fa-var-balance-scale-right: "\f516"; +@fa-var-ban: "\f05e"; +@fa-var-band-aid: "\f462"; +@fa-var-bandcamp: "\f2d5"; +@fa-var-barcode: "\f02a"; +@fa-var-bars: "\f0c9"; +@fa-var-baseball-ball: "\f433"; +@fa-var-basketball-ball: "\f434"; +@fa-var-bath: "\f2cd"; +@fa-var-battery-empty: "\f244"; +@fa-var-battery-full: "\f240"; +@fa-var-battery-half: "\f242"; +@fa-var-battery-quarter: "\f243"; +@fa-var-battery-three-quarters: "\f241"; +@fa-var-battle-net: "\f835"; +@fa-var-bed: "\f236"; +@fa-var-beer: "\f0fc"; +@fa-var-behance: "\f1b4"; +@fa-var-behance-square: "\f1b5"; +@fa-var-bell: "\f0f3"; +@fa-var-bell-slash: "\f1f6"; +@fa-var-bezier-curve: "\f55b"; +@fa-var-bible: "\f647"; +@fa-var-bicycle: "\f206"; +@fa-var-biking: "\f84a"; +@fa-var-bimobject: "\f378"; +@fa-var-binoculars: "\f1e5"; +@fa-var-biohazard: "\f780"; +@fa-var-birthday-cake: "\f1fd"; +@fa-var-bitbucket: "\f171"; +@fa-var-bitcoin: "\f379"; +@fa-var-bity: "\f37a"; +@fa-var-black-tie: "\f27e"; +@fa-var-blackberry: "\f37b"; +@fa-var-blender: "\f517"; +@fa-var-blender-phone: "\f6b6"; +@fa-var-blind: "\f29d"; +@fa-var-blog: "\f781"; +@fa-var-blogger: "\f37c"; +@fa-var-blogger-b: "\f37d"; +@fa-var-bluetooth: "\f293"; +@fa-var-bluetooth-b: "\f294"; +@fa-var-bold: "\f032"; +@fa-var-bolt: "\f0e7"; +@fa-var-bomb: "\f1e2"; +@fa-var-bone: "\f5d7"; +@fa-var-bong: "\f55c"; +@fa-var-book: "\f02d"; +@fa-var-book-dead: "\f6b7"; +@fa-var-book-medical: "\f7e6"; +@fa-var-book-open: "\f518"; +@fa-var-book-reader: "\f5da"; +@fa-var-bookmark: "\f02e"; +@fa-var-bootstrap: "\f836"; +@fa-var-border-all: "\f84c"; +@fa-var-border-none: "\f850"; +@fa-var-border-style: "\f853"; +@fa-var-bowling-ball: "\f436"; +@fa-var-box: "\f466"; +@fa-var-box-open: "\f49e"; +@fa-var-boxes: "\f468"; +@fa-var-braille: "\f2a1"; +@fa-var-brain: "\f5dc"; +@fa-var-bread-slice: "\f7ec"; +@fa-var-briefcase: "\f0b1"; +@fa-var-briefcase-medical: "\f469"; +@fa-var-broadcast-tower: "\f519"; +@fa-var-broom: "\f51a"; +@fa-var-brush: "\f55d"; +@fa-var-btc: "\f15a"; +@fa-var-buffer: "\f837"; +@fa-var-bug: "\f188"; +@fa-var-building: "\f1ad"; +@fa-var-bullhorn: "\f0a1"; +@fa-var-bullseye: "\f140"; +@fa-var-burn: "\f46a"; +@fa-var-buromobelexperte: "\f37f"; +@fa-var-bus: "\f207"; +@fa-var-bus-alt: "\f55e"; +@fa-var-business-time: "\f64a"; +@fa-var-buysellads: "\f20d"; +@fa-var-calculator: "\f1ec"; +@fa-var-calendar: "\f133"; +@fa-var-calendar-alt: "\f073"; +@fa-var-calendar-check: "\f274"; +@fa-var-calendar-day: "\f783"; +@fa-var-calendar-minus: "\f272"; +@fa-var-calendar-plus: "\f271"; +@fa-var-calendar-times: "\f273"; +@fa-var-calendar-week: "\f784"; +@fa-var-camera: "\f030"; +@fa-var-camera-retro: "\f083"; +@fa-var-campground: "\f6bb"; +@fa-var-canadian-maple-leaf: "\f785"; +@fa-var-candy-cane: "\f786"; +@fa-var-cannabis: "\f55f"; +@fa-var-capsules: "\f46b"; +@fa-var-car: "\f1b9"; +@fa-var-car-alt: "\f5de"; +@fa-var-car-battery: "\f5df"; +@fa-var-car-crash: "\f5e1"; +@fa-var-car-side: "\f5e4"; +@fa-var-caret-down: "\f0d7"; +@fa-var-caret-left: "\f0d9"; +@fa-var-caret-right: "\f0da"; +@fa-var-caret-square-down: "\f150"; +@fa-var-caret-square-left: "\f191"; +@fa-var-caret-square-right: "\f152"; +@fa-var-caret-square-up: "\f151"; +@fa-var-caret-up: "\f0d8"; +@fa-var-carrot: "\f787"; +@fa-var-cart-arrow-down: "\f218"; +@fa-var-cart-plus: "\f217"; +@fa-var-cash-register: "\f788"; +@fa-var-cat: "\f6be"; +@fa-var-cc-amazon-pay: "\f42d"; +@fa-var-cc-amex: "\f1f3"; +@fa-var-cc-apple-pay: "\f416"; +@fa-var-cc-diners-club: "\f24c"; +@fa-var-cc-discover: "\f1f2"; +@fa-var-cc-jcb: "\f24b"; +@fa-var-cc-mastercard: "\f1f1"; +@fa-var-cc-paypal: "\f1f4"; +@fa-var-cc-stripe: "\f1f5"; +@fa-var-cc-visa: "\f1f0"; +@fa-var-centercode: "\f380"; +@fa-var-centos: "\f789"; +@fa-var-certificate: "\f0a3"; +@fa-var-chair: "\f6c0"; +@fa-var-chalkboard: "\f51b"; +@fa-var-chalkboard-teacher: "\f51c"; +@fa-var-charging-station: "\f5e7"; +@fa-var-chart-area: "\f1fe"; +@fa-var-chart-bar: "\f080"; +@fa-var-chart-line: "\f201"; +@fa-var-chart-pie: "\f200"; +@fa-var-check: "\f00c"; +@fa-var-check-circle: "\f058"; +@fa-var-check-double: "\f560"; +@fa-var-check-square: "\f14a"; +@fa-var-cheese: "\f7ef"; +@fa-var-chess: "\f439"; +@fa-var-chess-bishop: "\f43a"; +@fa-var-chess-board: "\f43c"; +@fa-var-chess-king: "\f43f"; +@fa-var-chess-knight: "\f441"; +@fa-var-chess-pawn: "\f443"; +@fa-var-chess-queen: "\f445"; +@fa-var-chess-rook: "\f447"; +@fa-var-chevron-circle-down: "\f13a"; +@fa-var-chevron-circle-left: "\f137"; +@fa-var-chevron-circle-right: "\f138"; +@fa-var-chevron-circle-up: "\f139"; +@fa-var-chevron-down: "\f078"; +@fa-var-chevron-left: "\f053"; +@fa-var-chevron-right: "\f054"; +@fa-var-chevron-up: "\f077"; +@fa-var-child: "\f1ae"; +@fa-var-chrome: "\f268"; +@fa-var-chromecast: "\f838"; +@fa-var-church: "\f51d"; +@fa-var-circle: "\f111"; +@fa-var-circle-notch: "\f1ce"; +@fa-var-city: "\f64f"; +@fa-var-clinic-medical: "\f7f2"; +@fa-var-clipboard: "\f328"; +@fa-var-clipboard-check: "\f46c"; +@fa-var-clipboard-list: "\f46d"; +@fa-var-clock: "\f017"; +@fa-var-clone: "\f24d"; +@fa-var-closed-captioning: "\f20a"; +@fa-var-cloud: "\f0c2"; +@fa-var-cloud-download-alt: "\f381"; +@fa-var-cloud-meatball: "\f73b"; +@fa-var-cloud-moon: "\f6c3"; +@fa-var-cloud-moon-rain: "\f73c"; +@fa-var-cloud-rain: "\f73d"; +@fa-var-cloud-showers-heavy: "\f740"; +@fa-var-cloud-sun: "\f6c4"; +@fa-var-cloud-sun-rain: "\f743"; +@fa-var-cloud-upload-alt: "\f382"; +@fa-var-cloudscale: "\f383"; +@fa-var-cloudsmith: "\f384"; +@fa-var-cloudversify: "\f385"; +@fa-var-cocktail: "\f561"; +@fa-var-code: "\f121"; +@fa-var-code-branch: "\f126"; +@fa-var-codepen: "\f1cb"; +@fa-var-codiepie: "\f284"; +@fa-var-coffee: "\f0f4"; +@fa-var-cog: "\f013"; +@fa-var-cogs: "\f085"; +@fa-var-coins: "\f51e"; +@fa-var-columns: "\f0db"; +@fa-var-comment: "\f075"; +@fa-var-comment-alt: "\f27a"; +@fa-var-comment-dollar: "\f651"; +@fa-var-comment-dots: "\f4ad"; +@fa-var-comment-medical: "\f7f5"; +@fa-var-comment-slash: "\f4b3"; +@fa-var-comments: "\f086"; +@fa-var-comments-dollar: "\f653"; +@fa-var-compact-disc: "\f51f"; +@fa-var-compass: "\f14e"; +@fa-var-compress: "\f066"; +@fa-var-compress-arrows-alt: "\f78c"; +@fa-var-concierge-bell: "\f562"; +@fa-var-confluence: "\f78d"; +@fa-var-connectdevelop: "\f20e"; +@fa-var-contao: "\f26d"; +@fa-var-cookie: "\f563"; +@fa-var-cookie-bite: "\f564"; +@fa-var-copy: "\f0c5"; +@fa-var-copyright: "\f1f9"; +@fa-var-couch: "\f4b8"; +@fa-var-cpanel: "\f388"; +@fa-var-creative-commons: "\f25e"; +@fa-var-creative-commons-by: "\f4e7"; +@fa-var-creative-commons-nc: "\f4e8"; +@fa-var-creative-commons-nc-eu: "\f4e9"; +@fa-var-creative-commons-nc-jp: "\f4ea"; +@fa-var-creative-commons-nd: "\f4eb"; +@fa-var-creative-commons-pd: "\f4ec"; +@fa-var-creative-commons-pd-alt: "\f4ed"; +@fa-var-creative-commons-remix: "\f4ee"; +@fa-var-creative-commons-sa: "\f4ef"; +@fa-var-creative-commons-sampling: "\f4f0"; +@fa-var-creative-commons-sampling-plus: "\f4f1"; +@fa-var-creative-commons-share: "\f4f2"; +@fa-var-creative-commons-zero: "\f4f3"; +@fa-var-credit-card: "\f09d"; +@fa-var-critical-role: "\f6c9"; +@fa-var-crop: "\f125"; +@fa-var-crop-alt: "\f565"; +@fa-var-cross: "\f654"; +@fa-var-crosshairs: "\f05b"; +@fa-var-crow: "\f520"; +@fa-var-crown: "\f521"; +@fa-var-crutch: "\f7f7"; +@fa-var-css3: "\f13c"; +@fa-var-css3-alt: "\f38b"; +@fa-var-cube: "\f1b2"; +@fa-var-cubes: "\f1b3"; +@fa-var-cut: "\f0c4"; +@fa-var-cuttlefish: "\f38c"; +@fa-var-d-and-d: "\f38d"; +@fa-var-d-and-d-beyond: "\f6ca"; +@fa-var-dashcube: "\f210"; +@fa-var-database: "\f1c0"; +@fa-var-deaf: "\f2a4"; +@fa-var-delicious: "\f1a5"; +@fa-var-democrat: "\f747"; +@fa-var-deploydog: "\f38e"; +@fa-var-deskpro: "\f38f"; +@fa-var-desktop: "\f108"; +@fa-var-dev: "\f6cc"; +@fa-var-deviantart: "\f1bd"; +@fa-var-dharmachakra: "\f655"; +@fa-var-dhl: "\f790"; +@fa-var-diagnoses: "\f470"; +@fa-var-diaspora: "\f791"; +@fa-var-dice: "\f522"; +@fa-var-dice-d20: "\f6cf"; +@fa-var-dice-d6: "\f6d1"; +@fa-var-dice-five: "\f523"; +@fa-var-dice-four: "\f524"; +@fa-var-dice-one: "\f525"; +@fa-var-dice-six: "\f526"; +@fa-var-dice-three: "\f527"; +@fa-var-dice-two: "\f528"; +@fa-var-digg: "\f1a6"; +@fa-var-digital-ocean: "\f391"; +@fa-var-digital-tachograph: "\f566"; +@fa-var-directions: "\f5eb"; +@fa-var-discord: "\f392"; +@fa-var-discourse: "\f393"; +@fa-var-divide: "\f529"; +@fa-var-dizzy: "\f567"; +@fa-var-dna: "\f471"; +@fa-var-dochub: "\f394"; +@fa-var-docker: "\f395"; +@fa-var-dog: "\f6d3"; +@fa-var-dollar-sign: "\f155"; +@fa-var-dolly: "\f472"; +@fa-var-dolly-flatbed: "\f474"; +@fa-var-donate: "\f4b9"; +@fa-var-door-closed: "\f52a"; +@fa-var-door-open: "\f52b"; +@fa-var-dot-circle: "\f192"; +@fa-var-dove: "\f4ba"; +@fa-var-download: "\f019"; +@fa-var-draft2digital: "\f396"; +@fa-var-drafting-compass: "\f568"; +@fa-var-dragon: "\f6d5"; +@fa-var-draw-polygon: "\f5ee"; +@fa-var-dribbble: "\f17d"; +@fa-var-dribbble-square: "\f397"; +@fa-var-dropbox: "\f16b"; +@fa-var-drum: "\f569"; +@fa-var-drum-steelpan: "\f56a"; +@fa-var-drumstick-bite: "\f6d7"; +@fa-var-drupal: "\f1a9"; +@fa-var-dumbbell: "\f44b"; +@fa-var-dumpster: "\f793"; +@fa-var-dumpster-fire: "\f794"; +@fa-var-dungeon: "\f6d9"; +@fa-var-dyalog: "\f399"; +@fa-var-earlybirds: "\f39a"; +@fa-var-ebay: "\f4f4"; +@fa-var-edge: "\f282"; +@fa-var-edit: "\f044"; +@fa-var-egg: "\f7fb"; +@fa-var-eject: "\f052"; +@fa-var-elementor: "\f430"; +@fa-var-ellipsis-h: "\f141"; +@fa-var-ellipsis-v: "\f142"; +@fa-var-ello: "\f5f1"; +@fa-var-ember: "\f423"; +@fa-var-empire: "\f1d1"; +@fa-var-envelope: "\f0e0"; +@fa-var-envelope-open: "\f2b6"; +@fa-var-envelope-open-text: "\f658"; +@fa-var-envelope-square: "\f199"; +@fa-var-envira: "\f299"; +@fa-var-equals: "\f52c"; +@fa-var-eraser: "\f12d"; +@fa-var-erlang: "\f39d"; +@fa-var-ethereum: "\f42e"; +@fa-var-ethernet: "\f796"; +@fa-var-etsy: "\f2d7"; +@fa-var-euro-sign: "\f153"; +@fa-var-evernote: "\f839"; +@fa-var-exchange-alt: "\f362"; +@fa-var-exclamation: "\f12a"; +@fa-var-exclamation-circle: "\f06a"; +@fa-var-exclamation-triangle: "\f071"; +@fa-var-expand: "\f065"; +@fa-var-expand-arrows-alt: "\f31e"; +@fa-var-expeditedssl: "\f23e"; +@fa-var-external-link-alt: "\f35d"; +@fa-var-external-link-square-alt: "\f360"; +@fa-var-eye: "\f06e"; +@fa-var-eye-dropper: "\f1fb"; +@fa-var-eye-slash: "\f070"; +@fa-var-facebook: "\f09a"; +@fa-var-facebook-f: "\f39e"; +@fa-var-facebook-messenger: "\f39f"; +@fa-var-facebook-square: "\f082"; +@fa-var-fan: "\f863"; +@fa-var-fantasy-flight-games: "\f6dc"; +@fa-var-fast-backward: "\f049"; +@fa-var-fast-forward: "\f050"; +@fa-var-fax: "\f1ac"; +@fa-var-feather: "\f52d"; +@fa-var-feather-alt: "\f56b"; +@fa-var-fedex: "\f797"; +@fa-var-fedora: "\f798"; +@fa-var-female: "\f182"; +@fa-var-fighter-jet: "\f0fb"; +@fa-var-figma: "\f799"; +@fa-var-file: "\f15b"; +@fa-var-file-alt: "\f15c"; +@fa-var-file-archive: "\f1c6"; +@fa-var-file-audio: "\f1c7"; +@fa-var-file-code: "\f1c9"; +@fa-var-file-contract: "\f56c"; +@fa-var-file-csv: "\f6dd"; +@fa-var-file-download: "\f56d"; +@fa-var-file-excel: "\f1c3"; +@fa-var-file-export: "\f56e"; +@fa-var-file-image: "\f1c5"; +@fa-var-file-import: "\f56f"; +@fa-var-file-invoice: "\f570"; +@fa-var-file-invoice-dollar: "\f571"; +@fa-var-file-medical: "\f477"; +@fa-var-file-medical-alt: "\f478"; +@fa-var-file-pdf: "\f1c1"; +@fa-var-file-powerpoint: "\f1c4"; +@fa-var-file-prescription: "\f572"; +@fa-var-file-signature: "\f573"; +@fa-var-file-upload: "\f574"; +@fa-var-file-video: "\f1c8"; +@fa-var-file-word: "\f1c2"; +@fa-var-fill: "\f575"; +@fa-var-fill-drip: "\f576"; +@fa-var-film: "\f008"; +@fa-var-filter: "\f0b0"; +@fa-var-fingerprint: "\f577"; +@fa-var-fire: "\f06d"; +@fa-var-fire-alt: "\f7e4"; +@fa-var-fire-extinguisher: "\f134"; +@fa-var-firefox: "\f269"; +@fa-var-first-aid: "\f479"; +@fa-var-first-order: "\f2b0"; +@fa-var-first-order-alt: "\f50a"; +@fa-var-firstdraft: "\f3a1"; +@fa-var-fish: "\f578"; +@fa-var-fist-raised: "\f6de"; +@fa-var-flag: "\f024"; +@fa-var-flag-checkered: "\f11e"; +@fa-var-flag-usa: "\f74d"; +@fa-var-flask: "\f0c3"; +@fa-var-flickr: "\f16e"; +@fa-var-flipboard: "\f44d"; +@fa-var-flushed: "\f579"; +@fa-var-fly: "\f417"; +@fa-var-folder: "\f07b"; +@fa-var-folder-minus: "\f65d"; +@fa-var-folder-open: "\f07c"; +@fa-var-folder-plus: "\f65e"; +@fa-var-font: "\f031"; +@fa-var-font-awesome: "\f2b4"; +@fa-var-font-awesome-alt: "\f35c"; +@fa-var-font-awesome-flag: "\f425"; +@fa-var-font-awesome-logo-full: "\f4e6"; +@fa-var-fonticons: "\f280"; +@fa-var-fonticons-fi: "\f3a2"; +@fa-var-football-ball: "\f44e"; +@fa-var-fort-awesome: "\f286"; +@fa-var-fort-awesome-alt: "\f3a3"; +@fa-var-forumbee: "\f211"; +@fa-var-forward: "\f04e"; +@fa-var-foursquare: "\f180"; +@fa-var-free-code-camp: "\f2c5"; +@fa-var-freebsd: "\f3a4"; +@fa-var-frog: "\f52e"; +@fa-var-frown: "\f119"; +@fa-var-frown-open: "\f57a"; +@fa-var-fulcrum: "\f50b"; +@fa-var-funnel-dollar: "\f662"; +@fa-var-futbol: "\f1e3"; +@fa-var-galactic-republic: "\f50c"; +@fa-var-galactic-senate: "\f50d"; +@fa-var-gamepad: "\f11b"; +@fa-var-gas-pump: "\f52f"; +@fa-var-gavel: "\f0e3"; +@fa-var-gem: "\f3a5"; +@fa-var-genderless: "\f22d"; +@fa-var-get-pocket: "\f265"; +@fa-var-gg: "\f260"; +@fa-var-gg-circle: "\f261"; +@fa-var-ghost: "\f6e2"; +@fa-var-gift: "\f06b"; +@fa-var-gifts: "\f79c"; +@fa-var-git: "\f1d3"; +@fa-var-git-alt: "\f841"; +@fa-var-git-square: "\f1d2"; +@fa-var-github: "\f09b"; +@fa-var-github-alt: "\f113"; +@fa-var-github-square: "\f092"; +@fa-var-gitkraken: "\f3a6"; +@fa-var-gitlab: "\f296"; +@fa-var-gitter: "\f426"; +@fa-var-glass-cheers: "\f79f"; +@fa-var-glass-martini: "\f000"; +@fa-var-glass-martini-alt: "\f57b"; +@fa-var-glass-whiskey: "\f7a0"; +@fa-var-glasses: "\f530"; +@fa-var-glide: "\f2a5"; +@fa-var-glide-g: "\f2a6"; +@fa-var-globe: "\f0ac"; +@fa-var-globe-africa: "\f57c"; +@fa-var-globe-americas: "\f57d"; +@fa-var-globe-asia: "\f57e"; +@fa-var-globe-europe: "\f7a2"; +@fa-var-gofore: "\f3a7"; +@fa-var-golf-ball: "\f450"; +@fa-var-goodreads: "\f3a8"; +@fa-var-goodreads-g: "\f3a9"; +@fa-var-google: "\f1a0"; +@fa-var-google-drive: "\f3aa"; +@fa-var-google-play: "\f3ab"; +@fa-var-google-plus: "\f2b3"; +@fa-var-google-plus-g: "\f0d5"; +@fa-var-google-plus-square: "\f0d4"; +@fa-var-google-wallet: "\f1ee"; +@fa-var-gopuram: "\f664"; +@fa-var-graduation-cap: "\f19d"; +@fa-var-gratipay: "\f184"; +@fa-var-grav: "\f2d6"; +@fa-var-greater-than: "\f531"; +@fa-var-greater-than-equal: "\f532"; +@fa-var-grimace: "\f57f"; +@fa-var-grin: "\f580"; +@fa-var-grin-alt: "\f581"; +@fa-var-grin-beam: "\f582"; +@fa-var-grin-beam-sweat: "\f583"; +@fa-var-grin-hearts: "\f584"; +@fa-var-grin-squint: "\f585"; +@fa-var-grin-squint-tears: "\f586"; +@fa-var-grin-stars: "\f587"; +@fa-var-grin-tears: "\f588"; +@fa-var-grin-tongue: "\f589"; +@fa-var-grin-tongue-squint: "\f58a"; +@fa-var-grin-tongue-wink: "\f58b"; +@fa-var-grin-wink: "\f58c"; +@fa-var-grip-horizontal: "\f58d"; +@fa-var-grip-lines: "\f7a4"; +@fa-var-grip-lines-vertical: "\f7a5"; +@fa-var-grip-vertical: "\f58e"; +@fa-var-gripfire: "\f3ac"; +@fa-var-grunt: "\f3ad"; +@fa-var-guitar: "\f7a6"; +@fa-var-gulp: "\f3ae"; +@fa-var-h-square: "\f0fd"; +@fa-var-hacker-news: "\f1d4"; +@fa-var-hacker-news-square: "\f3af"; +@fa-var-hackerrank: "\f5f7"; +@fa-var-hamburger: "\f805"; +@fa-var-hammer: "\f6e3"; +@fa-var-hamsa: "\f665"; +@fa-var-hand-holding: "\f4bd"; +@fa-var-hand-holding-heart: "\f4be"; +@fa-var-hand-holding-usd: "\f4c0"; +@fa-var-hand-lizard: "\f258"; +@fa-var-hand-middle-finger: "\f806"; +@fa-var-hand-paper: "\f256"; +@fa-var-hand-peace: "\f25b"; +@fa-var-hand-point-down: "\f0a7"; +@fa-var-hand-point-left: "\f0a5"; +@fa-var-hand-point-right: "\f0a4"; +@fa-var-hand-point-up: "\f0a6"; +@fa-var-hand-pointer: "\f25a"; +@fa-var-hand-rock: "\f255"; +@fa-var-hand-scissors: "\f257"; +@fa-var-hand-spock: "\f259"; +@fa-var-hands: "\f4c2"; +@fa-var-hands-helping: "\f4c4"; +@fa-var-handshake: "\f2b5"; +@fa-var-hanukiah: "\f6e6"; +@fa-var-hard-hat: "\f807"; +@fa-var-hashtag: "\f292"; +@fa-var-hat-wizard: "\f6e8"; +@fa-var-haykal: "\f666"; +@fa-var-hdd: "\f0a0"; +@fa-var-heading: "\f1dc"; +@fa-var-headphones: "\f025"; +@fa-var-headphones-alt: "\f58f"; +@fa-var-headset: "\f590"; +@fa-var-heart: "\f004"; +@fa-var-heart-broken: "\f7a9"; +@fa-var-heartbeat: "\f21e"; +@fa-var-helicopter: "\f533"; +@fa-var-highlighter: "\f591"; +@fa-var-hiking: "\f6ec"; +@fa-var-hippo: "\f6ed"; +@fa-var-hips: "\f452"; +@fa-var-hire-a-helper: "\f3b0"; +@fa-var-history: "\f1da"; +@fa-var-hockey-puck: "\f453"; +@fa-var-holly-berry: "\f7aa"; +@fa-var-home: "\f015"; +@fa-var-hooli: "\f427"; +@fa-var-hornbill: "\f592"; +@fa-var-horse: "\f6f0"; +@fa-var-horse-head: "\f7ab"; +@fa-var-hospital: "\f0f8"; +@fa-var-hospital-alt: "\f47d"; +@fa-var-hospital-symbol: "\f47e"; +@fa-var-hot-tub: "\f593"; +@fa-var-hotdog: "\f80f"; +@fa-var-hotel: "\f594"; +@fa-var-hotjar: "\f3b1"; +@fa-var-hourglass: "\f254"; +@fa-var-hourglass-end: "\f253"; +@fa-var-hourglass-half: "\f252"; +@fa-var-hourglass-start: "\f251"; +@fa-var-house-damage: "\f6f1"; +@fa-var-houzz: "\f27c"; +@fa-var-hryvnia: "\f6f2"; +@fa-var-html5: "\f13b"; +@fa-var-hubspot: "\f3b2"; +@fa-var-i-cursor: "\f246"; +@fa-var-ice-cream: "\f810"; +@fa-var-icicles: "\f7ad"; +@fa-var-icons: "\f86d"; +@fa-var-id-badge: "\f2c1"; +@fa-var-id-card: "\f2c2"; +@fa-var-id-card-alt: "\f47f"; +@fa-var-igloo: "\f7ae"; +@fa-var-image: "\f03e"; +@fa-var-images: "\f302"; +@fa-var-imdb: "\f2d8"; +@fa-var-inbox: "\f01c"; +@fa-var-indent: "\f03c"; +@fa-var-industry: "\f275"; +@fa-var-infinity: "\f534"; +@fa-var-info: "\f129"; +@fa-var-info-circle: "\f05a"; +@fa-var-instagram: "\f16d"; +@fa-var-intercom: "\f7af"; +@fa-var-internet-explorer: "\f26b"; +@fa-var-invision: "\f7b0"; +@fa-var-ioxhost: "\f208"; +@fa-var-italic: "\f033"; +@fa-var-itch-io: "\f83a"; +@fa-var-itunes: "\f3b4"; +@fa-var-itunes-note: "\f3b5"; +@fa-var-java: "\f4e4"; +@fa-var-jedi: "\f669"; +@fa-var-jedi-order: "\f50e"; +@fa-var-jenkins: "\f3b6"; +@fa-var-jira: "\f7b1"; +@fa-var-joget: "\f3b7"; +@fa-var-joint: "\f595"; +@fa-var-joomla: "\f1aa"; +@fa-var-journal-whills: "\f66a"; +@fa-var-js: "\f3b8"; +@fa-var-js-square: "\f3b9"; +@fa-var-jsfiddle: "\f1cc"; +@fa-var-kaaba: "\f66b"; +@fa-var-kaggle: "\f5fa"; +@fa-var-key: "\f084"; +@fa-var-keybase: "\f4f5"; +@fa-var-keyboard: "\f11c"; +@fa-var-keycdn: "\f3ba"; +@fa-var-khanda: "\f66d"; +@fa-var-kickstarter: "\f3bb"; +@fa-var-kickstarter-k: "\f3bc"; +@fa-var-kiss: "\f596"; +@fa-var-kiss-beam: "\f597"; +@fa-var-kiss-wink-heart: "\f598"; +@fa-var-kiwi-bird: "\f535"; +@fa-var-korvue: "\f42f"; +@fa-var-landmark: "\f66f"; +@fa-var-language: "\f1ab"; +@fa-var-laptop: "\f109"; +@fa-var-laptop-code: "\f5fc"; +@fa-var-laptop-medical: "\f812"; +@fa-var-laravel: "\f3bd"; +@fa-var-lastfm: "\f202"; +@fa-var-lastfm-square: "\f203"; +@fa-var-laugh: "\f599"; +@fa-var-laugh-beam: "\f59a"; +@fa-var-laugh-squint: "\f59b"; +@fa-var-laugh-wink: "\f59c"; +@fa-var-layer-group: "\f5fd"; +@fa-var-leaf: "\f06c"; +@fa-var-leanpub: "\f212"; +@fa-var-lemon: "\f094"; +@fa-var-less: "\f41d"; +@fa-var-less-than: "\f536"; +@fa-var-less-than-equal: "\f537"; +@fa-var-level-down-alt: "\f3be"; +@fa-var-level-up-alt: "\f3bf"; +@fa-var-life-ring: "\f1cd"; +@fa-var-lightbulb: "\f0eb"; +@fa-var-line: "\f3c0"; +@fa-var-link: "\f0c1"; +@fa-var-linkedin: "\f08c"; +@fa-var-linkedin-in: "\f0e1"; +@fa-var-linode: "\f2b8"; +@fa-var-linux: "\f17c"; +@fa-var-lira-sign: "\f195"; +@fa-var-list: "\f03a"; +@fa-var-list-alt: "\f022"; +@fa-var-list-ol: "\f0cb"; +@fa-var-list-ul: "\f0ca"; +@fa-var-location-arrow: "\f124"; +@fa-var-lock: "\f023"; +@fa-var-lock-open: "\f3c1"; +@fa-var-long-arrow-alt-down: "\f309"; +@fa-var-long-arrow-alt-left: "\f30a"; +@fa-var-long-arrow-alt-right: "\f30b"; +@fa-var-long-arrow-alt-up: "\f30c"; +@fa-var-low-vision: "\f2a8"; +@fa-var-luggage-cart: "\f59d"; +@fa-var-lyft: "\f3c3"; +@fa-var-magento: "\f3c4"; +@fa-var-magic: "\f0d0"; +@fa-var-magnet: "\f076"; +@fa-var-mail-bulk: "\f674"; +@fa-var-mailchimp: "\f59e"; +@fa-var-male: "\f183"; +@fa-var-mandalorian: "\f50f"; +@fa-var-map: "\f279"; +@fa-var-map-marked: "\f59f"; +@fa-var-map-marked-alt: "\f5a0"; +@fa-var-map-marker: "\f041"; +@fa-var-map-marker-alt: "\f3c5"; +@fa-var-map-pin: "\f276"; +@fa-var-map-signs: "\f277"; +@fa-var-markdown: "\f60f"; +@fa-var-marker: "\f5a1"; +@fa-var-mars: "\f222"; +@fa-var-mars-double: "\f227"; +@fa-var-mars-stroke: "\f229"; +@fa-var-mars-stroke-h: "\f22b"; +@fa-var-mars-stroke-v: "\f22a"; +@fa-var-mask: "\f6fa"; +@fa-var-mastodon: "\f4f6"; +@fa-var-maxcdn: "\f136"; +@fa-var-medal: "\f5a2"; +@fa-var-medapps: "\f3c6"; +@fa-var-medium: "\f23a"; +@fa-var-medium-m: "\f3c7"; +@fa-var-medkit: "\f0fa"; +@fa-var-medrt: "\f3c8"; +@fa-var-meetup: "\f2e0"; +@fa-var-megaport: "\f5a3"; +@fa-var-meh: "\f11a"; +@fa-var-meh-blank: "\f5a4"; +@fa-var-meh-rolling-eyes: "\f5a5"; +@fa-var-memory: "\f538"; +@fa-var-mendeley: "\f7b3"; +@fa-var-menorah: "\f676"; +@fa-var-mercury: "\f223"; +@fa-var-meteor: "\f753"; +@fa-var-microchip: "\f2db"; +@fa-var-microphone: "\f130"; +@fa-var-microphone-alt: "\f3c9"; +@fa-var-microphone-alt-slash: "\f539"; +@fa-var-microphone-slash: "\f131"; +@fa-var-microscope: "\f610"; +@fa-var-microsoft: "\f3ca"; +@fa-var-minus: "\f068"; +@fa-var-minus-circle: "\f056"; +@fa-var-minus-square: "\f146"; +@fa-var-mitten: "\f7b5"; +@fa-var-mix: "\f3cb"; +@fa-var-mixcloud: "\f289"; +@fa-var-mizuni: "\f3cc"; +@fa-var-mobile: "\f10b"; +@fa-var-mobile-alt: "\f3cd"; +@fa-var-modx: "\f285"; +@fa-var-monero: "\f3d0"; +@fa-var-money-bill: "\f0d6"; +@fa-var-money-bill-alt: "\f3d1"; +@fa-var-money-bill-wave: "\f53a"; +@fa-var-money-bill-wave-alt: "\f53b"; +@fa-var-money-check: "\f53c"; +@fa-var-money-check-alt: "\f53d"; +@fa-var-monument: "\f5a6"; +@fa-var-moon: "\f186"; +@fa-var-mortar-pestle: "\f5a7"; +@fa-var-mosque: "\f678"; +@fa-var-motorcycle: "\f21c"; +@fa-var-mountain: "\f6fc"; +@fa-var-mouse-pointer: "\f245"; +@fa-var-mug-hot: "\f7b6"; +@fa-var-music: "\f001"; +@fa-var-napster: "\f3d2"; +@fa-var-neos: "\f612"; +@fa-var-network-wired: "\f6ff"; +@fa-var-neuter: "\f22c"; +@fa-var-newspaper: "\f1ea"; +@fa-var-nimblr: "\f5a8"; +@fa-var-node: "\f419"; +@fa-var-node-js: "\f3d3"; +@fa-var-not-equal: "\f53e"; +@fa-var-notes-medical: "\f481"; +@fa-var-npm: "\f3d4"; +@fa-var-ns8: "\f3d5"; +@fa-var-nutritionix: "\f3d6"; +@fa-var-object-group: "\f247"; +@fa-var-object-ungroup: "\f248"; +@fa-var-odnoklassniki: "\f263"; +@fa-var-odnoklassniki-square: "\f264"; +@fa-var-oil-can: "\f613"; +@fa-var-old-republic: "\f510"; +@fa-var-om: "\f679"; +@fa-var-opencart: "\f23d"; +@fa-var-openid: "\f19b"; +@fa-var-opera: "\f26a"; +@fa-var-optin-monster: "\f23c"; +@fa-var-osi: "\f41a"; +@fa-var-otter: "\f700"; +@fa-var-outdent: "\f03b"; +@fa-var-page4: "\f3d7"; +@fa-var-pagelines: "\f18c"; +@fa-var-pager: "\f815"; +@fa-var-paint-brush: "\f1fc"; +@fa-var-paint-roller: "\f5aa"; +@fa-var-palette: "\f53f"; +@fa-var-palfed: "\f3d8"; +@fa-var-pallet: "\f482"; +@fa-var-paper-plane: "\f1d8"; +@fa-var-paperclip: "\f0c6"; +@fa-var-parachute-box: "\f4cd"; +@fa-var-paragraph: "\f1dd"; +@fa-var-parking: "\f540"; +@fa-var-passport: "\f5ab"; +@fa-var-pastafarianism: "\f67b"; +@fa-var-paste: "\f0ea"; +@fa-var-patreon: "\f3d9"; +@fa-var-pause: "\f04c"; +@fa-var-pause-circle: "\f28b"; +@fa-var-paw: "\f1b0"; +@fa-var-paypal: "\f1ed"; +@fa-var-peace: "\f67c"; +@fa-var-pen: "\f304"; +@fa-var-pen-alt: "\f305"; +@fa-var-pen-fancy: "\f5ac"; +@fa-var-pen-nib: "\f5ad"; +@fa-var-pen-square: "\f14b"; +@fa-var-pencil-alt: "\f303"; +@fa-var-pencil-ruler: "\f5ae"; +@fa-var-penny-arcade: "\f704"; +@fa-var-people-carry: "\f4ce"; +@fa-var-pepper-hot: "\f816"; +@fa-var-percent: "\f295"; +@fa-var-percentage: "\f541"; +@fa-var-periscope: "\f3da"; +@fa-var-person-booth: "\f756"; +@fa-var-phabricator: "\f3db"; +@fa-var-phoenix-framework: "\f3dc"; +@fa-var-phoenix-squadron: "\f511"; +@fa-var-phone: "\f095"; +@fa-var-phone-alt: "\f879"; +@fa-var-phone-slash: "\f3dd"; +@fa-var-phone-square: "\f098"; +@fa-var-phone-square-alt: "\f87b"; +@fa-var-phone-volume: "\f2a0"; +@fa-var-photo-video: "\f87c"; +@fa-var-php: "\f457"; +@fa-var-pied-piper: "\f2ae"; +@fa-var-pied-piper-alt: "\f1a8"; +@fa-var-pied-piper-hat: "\f4e5"; +@fa-var-pied-piper-pp: "\f1a7"; +@fa-var-piggy-bank: "\f4d3"; +@fa-var-pills: "\f484"; +@fa-var-pinterest: "\f0d2"; +@fa-var-pinterest-p: "\f231"; +@fa-var-pinterest-square: "\f0d3"; +@fa-var-pizza-slice: "\f818"; +@fa-var-place-of-worship: "\f67f"; +@fa-var-plane: "\f072"; +@fa-var-plane-arrival: "\f5af"; +@fa-var-plane-departure: "\f5b0"; +@fa-var-play: "\f04b"; +@fa-var-play-circle: "\f144"; +@fa-var-playstation: "\f3df"; +@fa-var-plug: "\f1e6"; +@fa-var-plus: "\f067"; +@fa-var-plus-circle: "\f055"; +@fa-var-plus-square: "\f0fe"; +@fa-var-podcast: "\f2ce"; +@fa-var-poll: "\f681"; +@fa-var-poll-h: "\f682"; +@fa-var-poo: "\f2fe"; +@fa-var-poo-storm: "\f75a"; +@fa-var-poop: "\f619"; +@fa-var-portrait: "\f3e0"; +@fa-var-pound-sign: "\f154"; +@fa-var-power-off: "\f011"; +@fa-var-pray: "\f683"; +@fa-var-praying-hands: "\f684"; +@fa-var-prescription: "\f5b1"; +@fa-var-prescription-bottle: "\f485"; +@fa-var-prescription-bottle-alt: "\f486"; +@fa-var-print: "\f02f"; +@fa-var-procedures: "\f487"; +@fa-var-product-hunt: "\f288"; +@fa-var-project-diagram: "\f542"; +@fa-var-pushed: "\f3e1"; +@fa-var-puzzle-piece: "\f12e"; +@fa-var-python: "\f3e2"; +@fa-var-qq: "\f1d6"; +@fa-var-qrcode: "\f029"; +@fa-var-question: "\f128"; +@fa-var-question-circle: "\f059"; +@fa-var-quidditch: "\f458"; +@fa-var-quinscape: "\f459"; +@fa-var-quora: "\f2c4"; +@fa-var-quote-left: "\f10d"; +@fa-var-quote-right: "\f10e"; +@fa-var-quran: "\f687"; +@fa-var-r-project: "\f4f7"; +@fa-var-radiation: "\f7b9"; +@fa-var-radiation-alt: "\f7ba"; +@fa-var-rainbow: "\f75b"; +@fa-var-random: "\f074"; +@fa-var-raspberry-pi: "\f7bb"; +@fa-var-ravelry: "\f2d9"; +@fa-var-react: "\f41b"; +@fa-var-reacteurope: "\f75d"; +@fa-var-readme: "\f4d5"; +@fa-var-rebel: "\f1d0"; +@fa-var-receipt: "\f543"; +@fa-var-recycle: "\f1b8"; +@fa-var-red-river: "\f3e3"; +@fa-var-reddit: "\f1a1"; +@fa-var-reddit-alien: "\f281"; +@fa-var-reddit-square: "\f1a2"; +@fa-var-redhat: "\f7bc"; +@fa-var-redo: "\f01e"; +@fa-var-redo-alt: "\f2f9"; +@fa-var-registered: "\f25d"; +@fa-var-remove-format: "\f87d"; +@fa-var-renren: "\f18b"; +@fa-var-reply: "\f3e5"; +@fa-var-reply-all: "\f122"; +@fa-var-replyd: "\f3e6"; +@fa-var-republican: "\f75e"; +@fa-var-researchgate: "\f4f8"; +@fa-var-resolving: "\f3e7"; +@fa-var-restroom: "\f7bd"; +@fa-var-retweet: "\f079"; +@fa-var-rev: "\f5b2"; +@fa-var-ribbon: "\f4d6"; +@fa-var-ring: "\f70b"; +@fa-var-road: "\f018"; +@fa-var-robot: "\f544"; +@fa-var-rocket: "\f135"; +@fa-var-rocketchat: "\f3e8"; +@fa-var-rockrms: "\f3e9"; +@fa-var-route: "\f4d7"; +@fa-var-rss: "\f09e"; +@fa-var-rss-square: "\f143"; +@fa-var-ruble-sign: "\f158"; +@fa-var-ruler: "\f545"; +@fa-var-ruler-combined: "\f546"; +@fa-var-ruler-horizontal: "\f547"; +@fa-var-ruler-vertical: "\f548"; +@fa-var-running: "\f70c"; +@fa-var-rupee-sign: "\f156"; +@fa-var-sad-cry: "\f5b3"; +@fa-var-sad-tear: "\f5b4"; +@fa-var-safari: "\f267"; +@fa-var-salesforce: "\f83b"; +@fa-var-sass: "\f41e"; +@fa-var-satellite: "\f7bf"; +@fa-var-satellite-dish: "\f7c0"; +@fa-var-save: "\f0c7"; +@fa-var-schlix: "\f3ea"; +@fa-var-school: "\f549"; +@fa-var-screwdriver: "\f54a"; +@fa-var-scribd: "\f28a"; +@fa-var-scroll: "\f70e"; +@fa-var-sd-card: "\f7c2"; +@fa-var-search: "\f002"; +@fa-var-search-dollar: "\f688"; +@fa-var-search-location: "\f689"; +@fa-var-search-minus: "\f010"; +@fa-var-search-plus: "\f00e"; +@fa-var-searchengin: "\f3eb"; +@fa-var-seedling: "\f4d8"; +@fa-var-sellcast: "\f2da"; +@fa-var-sellsy: "\f213"; +@fa-var-server: "\f233"; +@fa-var-servicestack: "\f3ec"; +@fa-var-shapes: "\f61f"; +@fa-var-share: "\f064"; +@fa-var-share-alt: "\f1e0"; +@fa-var-share-alt-square: "\f1e1"; +@fa-var-share-square: "\f14d"; +@fa-var-shekel-sign: "\f20b"; +@fa-var-shield-alt: "\f3ed"; +@fa-var-ship: "\f21a"; +@fa-var-shipping-fast: "\f48b"; +@fa-var-shirtsinbulk: "\f214"; +@fa-var-shoe-prints: "\f54b"; +@fa-var-shopping-bag: "\f290"; +@fa-var-shopping-basket: "\f291"; +@fa-var-shopping-cart: "\f07a"; +@fa-var-shopware: "\f5b5"; +@fa-var-shower: "\f2cc"; +@fa-var-shuttle-van: "\f5b6"; +@fa-var-sign: "\f4d9"; +@fa-var-sign-in-alt: "\f2f6"; +@fa-var-sign-language: "\f2a7"; +@fa-var-sign-out-alt: "\f2f5"; +@fa-var-signal: "\f012"; +@fa-var-signature: "\f5b7"; +@fa-var-sim-card: "\f7c4"; +@fa-var-simplybuilt: "\f215"; +@fa-var-sistrix: "\f3ee"; +@fa-var-sitemap: "\f0e8"; +@fa-var-sith: "\f512"; +@fa-var-skating: "\f7c5"; +@fa-var-sketch: "\f7c6"; +@fa-var-skiing: "\f7c9"; +@fa-var-skiing-nordic: "\f7ca"; +@fa-var-skull: "\f54c"; +@fa-var-skull-crossbones: "\f714"; +@fa-var-skyatlas: "\f216"; +@fa-var-skype: "\f17e"; +@fa-var-slack: "\f198"; +@fa-var-slack-hash: "\f3ef"; +@fa-var-slash: "\f715"; +@fa-var-sleigh: "\f7cc"; +@fa-var-sliders-h: "\f1de"; +@fa-var-slideshare: "\f1e7"; +@fa-var-smile: "\f118"; +@fa-var-smile-beam: "\f5b8"; +@fa-var-smile-wink: "\f4da"; +@fa-var-smog: "\f75f"; +@fa-var-smoking: "\f48d"; +@fa-var-smoking-ban: "\f54d"; +@fa-var-sms: "\f7cd"; +@fa-var-snapchat: "\f2ab"; +@fa-var-snapchat-ghost: "\f2ac"; +@fa-var-snapchat-square: "\f2ad"; +@fa-var-snowboarding: "\f7ce"; +@fa-var-snowflake: "\f2dc"; +@fa-var-snowman: "\f7d0"; +@fa-var-snowplow: "\f7d2"; +@fa-var-socks: "\f696"; +@fa-var-solar-panel: "\f5ba"; +@fa-var-sort: "\f0dc"; +@fa-var-sort-alpha-down: "\f15d"; +@fa-var-sort-alpha-down-alt: "\f881"; +@fa-var-sort-alpha-up: "\f15e"; +@fa-var-sort-alpha-up-alt: "\f882"; +@fa-var-sort-amount-down: "\f160"; +@fa-var-sort-amount-down-alt: "\f884"; +@fa-var-sort-amount-up: "\f161"; +@fa-var-sort-amount-up-alt: "\f885"; +@fa-var-sort-down: "\f0dd"; +@fa-var-sort-numeric-down: "\f162"; +@fa-var-sort-numeric-down-alt: "\f886"; +@fa-var-sort-numeric-up: "\f163"; +@fa-var-sort-numeric-up-alt: "\f887"; +@fa-var-sort-up: "\f0de"; +@fa-var-soundcloud: "\f1be"; +@fa-var-sourcetree: "\f7d3"; +@fa-var-spa: "\f5bb"; +@fa-var-space-shuttle: "\f197"; +@fa-var-speakap: "\f3f3"; +@fa-var-speaker-deck: "\f83c"; +@fa-var-spell-check: "\f891"; +@fa-var-spider: "\f717"; +@fa-var-spinner: "\f110"; +@fa-var-splotch: "\f5bc"; +@fa-var-spotify: "\f1bc"; +@fa-var-spray-can: "\f5bd"; +@fa-var-square: "\f0c8"; +@fa-var-square-full: "\f45c"; +@fa-var-square-root-alt: "\f698"; +@fa-var-squarespace: "\f5be"; +@fa-var-stack-exchange: "\f18d"; +@fa-var-stack-overflow: "\f16c"; +@fa-var-stackpath: "\f842"; +@fa-var-stamp: "\f5bf"; +@fa-var-star: "\f005"; +@fa-var-star-and-crescent: "\f699"; +@fa-var-star-half: "\f089"; +@fa-var-star-half-alt: "\f5c0"; +@fa-var-star-of-david: "\f69a"; +@fa-var-star-of-life: "\f621"; +@fa-var-staylinked: "\f3f5"; +@fa-var-steam: "\f1b6"; +@fa-var-steam-square: "\f1b7"; +@fa-var-steam-symbol: "\f3f6"; +@fa-var-step-backward: "\f048"; +@fa-var-step-forward: "\f051"; +@fa-var-stethoscope: "\f0f1"; +@fa-var-sticker-mule: "\f3f7"; +@fa-var-sticky-note: "\f249"; +@fa-var-stop: "\f04d"; +@fa-var-stop-circle: "\f28d"; +@fa-var-stopwatch: "\f2f2"; +@fa-var-store: "\f54e"; +@fa-var-store-alt: "\f54f"; +@fa-var-strava: "\f428"; +@fa-var-stream: "\f550"; +@fa-var-street-view: "\f21d"; +@fa-var-strikethrough: "\f0cc"; +@fa-var-stripe: "\f429"; +@fa-var-stripe-s: "\f42a"; +@fa-var-stroopwafel: "\f551"; +@fa-var-studiovinari: "\f3f8"; +@fa-var-stumbleupon: "\f1a4"; +@fa-var-stumbleupon-circle: "\f1a3"; +@fa-var-subscript: "\f12c"; +@fa-var-subway: "\f239"; +@fa-var-suitcase: "\f0f2"; +@fa-var-suitcase-rolling: "\f5c1"; +@fa-var-sun: "\f185"; +@fa-var-superpowers: "\f2dd"; +@fa-var-superscript: "\f12b"; +@fa-var-supple: "\f3f9"; +@fa-var-surprise: "\f5c2"; +@fa-var-suse: "\f7d6"; +@fa-var-swatchbook: "\f5c3"; +@fa-var-swimmer: "\f5c4"; +@fa-var-swimming-pool: "\f5c5"; +@fa-var-symfony: "\f83d"; +@fa-var-synagogue: "\f69b"; +@fa-var-sync: "\f021"; +@fa-var-sync-alt: "\f2f1"; +@fa-var-syringe: "\f48e"; +@fa-var-table: "\f0ce"; +@fa-var-table-tennis: "\f45d"; +@fa-var-tablet: "\f10a"; +@fa-var-tablet-alt: "\f3fa"; +@fa-var-tablets: "\f490"; +@fa-var-tachometer-alt: "\f3fd"; +@fa-var-tag: "\f02b"; +@fa-var-tags: "\f02c"; +@fa-var-tape: "\f4db"; +@fa-var-tasks: "\f0ae"; +@fa-var-taxi: "\f1ba"; +@fa-var-teamspeak: "\f4f9"; +@fa-var-teeth: "\f62e"; +@fa-var-teeth-open: "\f62f"; +@fa-var-telegram: "\f2c6"; +@fa-var-telegram-plane: "\f3fe"; +@fa-var-temperature-high: "\f769"; +@fa-var-temperature-low: "\f76b"; +@fa-var-tencent-weibo: "\f1d5"; +@fa-var-tenge: "\f7d7"; +@fa-var-terminal: "\f120"; +@fa-var-text-height: "\f034"; +@fa-var-text-width: "\f035"; +@fa-var-th: "\f00a"; +@fa-var-th-large: "\f009"; +@fa-var-th-list: "\f00b"; +@fa-var-the-red-yeti: "\f69d"; +@fa-var-theater-masks: "\f630"; +@fa-var-themeco: "\f5c6"; +@fa-var-themeisle: "\f2b2"; +@fa-var-thermometer: "\f491"; +@fa-var-thermometer-empty: "\f2cb"; +@fa-var-thermometer-full: "\f2c7"; +@fa-var-thermometer-half: "\f2c9"; +@fa-var-thermometer-quarter: "\f2ca"; +@fa-var-thermometer-three-quarters: "\f2c8"; +@fa-var-think-peaks: "\f731"; +@fa-var-thumbs-down: "\f165"; +@fa-var-thumbs-up: "\f164"; +@fa-var-thumbtack: "\f08d"; +@fa-var-ticket-alt: "\f3ff"; +@fa-var-times: "\f00d"; +@fa-var-times-circle: "\f057"; +@fa-var-tint: "\f043"; +@fa-var-tint-slash: "\f5c7"; +@fa-var-tired: "\f5c8"; +@fa-var-toggle-off: "\f204"; +@fa-var-toggle-on: "\f205"; +@fa-var-toilet: "\f7d8"; +@fa-var-toilet-paper: "\f71e"; +@fa-var-toolbox: "\f552"; +@fa-var-tools: "\f7d9"; +@fa-var-tooth: "\f5c9"; +@fa-var-torah: "\f6a0"; +@fa-var-torii-gate: "\f6a1"; +@fa-var-tractor: "\f722"; +@fa-var-trade-federation: "\f513"; +@fa-var-trademark: "\f25c"; +@fa-var-traffic-light: "\f637"; +@fa-var-train: "\f238"; +@fa-var-tram: "\f7da"; +@fa-var-transgender: "\f224"; +@fa-var-transgender-alt: "\f225"; +@fa-var-trash: "\f1f8"; +@fa-var-trash-alt: "\f2ed"; +@fa-var-trash-restore: "\f829"; +@fa-var-trash-restore-alt: "\f82a"; +@fa-var-tree: "\f1bb"; +@fa-var-trello: "\f181"; +@fa-var-tripadvisor: "\f262"; +@fa-var-trophy: "\f091"; +@fa-var-truck: "\f0d1"; +@fa-var-truck-loading: "\f4de"; +@fa-var-truck-monster: "\f63b"; +@fa-var-truck-moving: "\f4df"; +@fa-var-truck-pickup: "\f63c"; +@fa-var-tshirt: "\f553"; +@fa-var-tty: "\f1e4"; +@fa-var-tumblr: "\f173"; +@fa-var-tumblr-square: "\f174"; +@fa-var-tv: "\f26c"; +@fa-var-twitch: "\f1e8"; +@fa-var-twitter: "\f099"; +@fa-var-twitter-square: "\f081"; +@fa-var-typo3: "\f42b"; +@fa-var-uber: "\f402"; +@fa-var-ubuntu: "\f7df"; +@fa-var-uikit: "\f403"; +@fa-var-umbrella: "\f0e9"; +@fa-var-umbrella-beach: "\f5ca"; +@fa-var-underline: "\f0cd"; +@fa-var-undo: "\f0e2"; +@fa-var-undo-alt: "\f2ea"; +@fa-var-uniregistry: "\f404"; +@fa-var-universal-access: "\f29a"; +@fa-var-university: "\f19c"; +@fa-var-unlink: "\f127"; +@fa-var-unlock: "\f09c"; +@fa-var-unlock-alt: "\f13e"; +@fa-var-untappd: "\f405"; +@fa-var-upload: "\f093"; +@fa-var-ups: "\f7e0"; +@fa-var-usb: "\f287"; +@fa-var-user: "\f007"; +@fa-var-user-alt: "\f406"; +@fa-var-user-alt-slash: "\f4fa"; +@fa-var-user-astronaut: "\f4fb"; +@fa-var-user-check: "\f4fc"; +@fa-var-user-circle: "\f2bd"; +@fa-var-user-clock: "\f4fd"; +@fa-var-user-cog: "\f4fe"; +@fa-var-user-edit: "\f4ff"; +@fa-var-user-friends: "\f500"; +@fa-var-user-graduate: "\f501"; +@fa-var-user-injured: "\f728"; +@fa-var-user-lock: "\f502"; +@fa-var-user-md: "\f0f0"; +@fa-var-user-minus: "\f503"; +@fa-var-user-ninja: "\f504"; +@fa-var-user-nurse: "\f82f"; +@fa-var-user-plus: "\f234"; +@fa-var-user-secret: "\f21b"; +@fa-var-user-shield: "\f505"; +@fa-var-user-slash: "\f506"; +@fa-var-user-tag: "\f507"; +@fa-var-user-tie: "\f508"; +@fa-var-user-times: "\f235"; +@fa-var-users: "\f0c0"; +@fa-var-users-cog: "\f509"; +@fa-var-usps: "\f7e1"; +@fa-var-ussunnah: "\f407"; +@fa-var-utensil-spoon: "\f2e5"; +@fa-var-utensils: "\f2e7"; +@fa-var-vaadin: "\f408"; +@fa-var-vector-square: "\f5cb"; +@fa-var-venus: "\f221"; +@fa-var-venus-double: "\f226"; +@fa-var-venus-mars: "\f228"; +@fa-var-viacoin: "\f237"; +@fa-var-viadeo: "\f2a9"; +@fa-var-viadeo-square: "\f2aa"; +@fa-var-vial: "\f492"; +@fa-var-vials: "\f493"; +@fa-var-viber: "\f409"; +@fa-var-video: "\f03d"; +@fa-var-video-slash: "\f4e2"; +@fa-var-vihara: "\f6a7"; +@fa-var-vimeo: "\f40a"; +@fa-var-vimeo-square: "\f194"; +@fa-var-vimeo-v: "\f27d"; +@fa-var-vine: "\f1ca"; +@fa-var-vk: "\f189"; +@fa-var-vnv: "\f40b"; +@fa-var-voicemail: "\f897"; +@fa-var-volleyball-ball: "\f45f"; +@fa-var-volume-down: "\f027"; +@fa-var-volume-mute: "\f6a9"; +@fa-var-volume-off: "\f026"; +@fa-var-volume-up: "\f028"; +@fa-var-vote-yea: "\f772"; +@fa-var-vr-cardboard: "\f729"; +@fa-var-vuejs: "\f41f"; +@fa-var-walking: "\f554"; +@fa-var-wallet: "\f555"; +@fa-var-warehouse: "\f494"; +@fa-var-water: "\f773"; +@fa-var-wave-square: "\f83e"; +@fa-var-waze: "\f83f"; +@fa-var-weebly: "\f5cc"; +@fa-var-weibo: "\f18a"; +@fa-var-weight: "\f496"; +@fa-var-weight-hanging: "\f5cd"; +@fa-var-weixin: "\f1d7"; +@fa-var-whatsapp: "\f232"; +@fa-var-whatsapp-square: "\f40c"; +@fa-var-wheelchair: "\f193"; +@fa-var-whmcs: "\f40d"; +@fa-var-wifi: "\f1eb"; +@fa-var-wikipedia-w: "\f266"; +@fa-var-wind: "\f72e"; +@fa-var-window-close: "\f410"; +@fa-var-window-maximize: "\f2d0"; +@fa-var-window-minimize: "\f2d1"; +@fa-var-window-restore: "\f2d2"; +@fa-var-windows: "\f17a"; +@fa-var-wine-bottle: "\f72f"; +@fa-var-wine-glass: "\f4e3"; +@fa-var-wine-glass-alt: "\f5ce"; +@fa-var-wix: "\f5cf"; +@fa-var-wizards-of-the-coast: "\f730"; +@fa-var-wolf-pack-battalion: "\f514"; +@fa-var-won-sign: "\f159"; +@fa-var-wordpress: "\f19a"; +@fa-var-wordpress-simple: "\f411"; +@fa-var-wpbeginner: "\f297"; +@fa-var-wpexplorer: "\f2de"; +@fa-var-wpforms: "\f298"; +@fa-var-wpressr: "\f3e4"; +@fa-var-wrench: "\f0ad"; +@fa-var-x-ray: "\f497"; +@fa-var-xbox: "\f412"; +@fa-var-xing: "\f168"; +@fa-var-xing-square: "\f169"; +@fa-var-y-combinator: "\f23b"; +@fa-var-yahoo: "\f19e"; +@fa-var-yammer: "\f840"; +@fa-var-yandex: "\f413"; +@fa-var-yandex-international: "\f414"; +@fa-var-yarn: "\f7e3"; +@fa-var-yelp: "\f1e9"; +@fa-var-yen-sign: "\f157"; +@fa-var-yin-yang: "\f6ad"; +@fa-var-yoast: "\f2b1"; +@fa-var-youtube: "\f167"; +@fa-var-youtube-square: "\f431"; +@fa-var-zhihu: "\f63f"; diff --git a/styles/global.less b/styles/global.less new file mode 100644 index 0000000..0982107 --- /dev/null +++ b/styles/global.less @@ -0,0 +1,149 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +@import (reference) "variables"; +@import (reference) "mixins"; + +/*** Fonts ***/ + +@font-face { + font-family: 'Icons'; + font-style: normal; + font-weight: 900; + src: url("../fonts/fa-solid-900.woff2") format('woff2'), + url("../fonts/fa-solid-900.woff") format('woff'); +} + +@font-face { + font-family: 'Icons'; + font-style: normal; + font-weight: 400; + src: url("../fonts/fa-regular-400.woff2") format('woff2'), + url("../fonts/fa-regular-400.woff") format('woff'); +} + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + src: local('Roboto'), local('Roboto-Regular'), + url('../fonts/roboto-v29-regular.woff2') format('woff2'), // Chrome 26+, Opera 23+, Firefox 39+ + url('../fonts/roboto-v29-regular.woff') format('woff'); // Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ +} + +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 400; + src: local('Roboto Italic'), local('Roboto-Italic'), + url('../fonts/roboto-v29-italic.woff2') format('woff2'), // Chrome 26+, Opera 23+, Firefox 39+ + url('../fonts/roboto-v29-italic.woff') format('woff'); // Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ +} + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: local('Roboto Bold'), local('Roboto-Bold'), + url('../fonts/roboto-v29-regular-700.woff2') format('woff2'), // Chrome 26+, Opera 23+, Firefox 39+ + url('../fonts/roboto-v29-regular-700.woff') format('woff'); // Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ +} + +@font-face { + font-family: 'Roboto'; + font-style: italic; + font-weight: 700; + src: local('Roboto Bold Italic'), local('Roboto-BoldItalic'), + url('../fonts/roboto-v29-italic-700.woff2') format('woff2'), // Chrome 26+, Opera 23+, Firefox 39+ + url('../fonts/roboto-v29-italic-700.woff') format('woff'); // Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ +} + +/* Reset some Bootstrap style */ + +body, button, input, optgroup, select, textarea, .popover { + .font-family(); +} + +button, input, select, textarea { + line-height: initial; +} + +input { + vertical-align: middle; +} + +a { + color: @color-link; + + &:hover { + color: @color-link-hover; + } + + &.disabled { + pointer-events: none; + } + + &.disabled:not(.btn) { + opacity: .5; + } +} + +/* Scrollbar styles */ + +html when not (@scrollbar-width = unset) { + // Ignore thin width setting for Firefox, it makes the scrollbar very very thin in Firefox >= 100 + & when not (@scrollbar-width = thin) { + scrollbar-width: @scrollbar-width; + + textarea, + select, + .popover-body, + .popupmenu, + .ui-menu, + .ui-dialog-content, + .frame-content, + .formcontent, + .table-responsive, + .table-responsive-sm, + .tox-menu, + .tox-dialog__body-nav, + .tox-collection__group, + .scroller { + // Firefox does not inherit scrollbar size from the html element + scrollbar-width: @scrollbar-width; + } + } + + &:not(.touch) { + ::-webkit-scrollbar when (@scrollbar-width = auto) { + // Note: If we do not set the width a default scrollbar is used in Chrome. + // And the custom colors set below do not work + width: 12px; + } + ::-webkit-scrollbar when (@scrollbar-width = thin) { + width: 6px; + } + } +} + +html { + scrollbar-color: @color-scrollbar-thumb @color-scrollbar-track; + + &:not(.touch) { + ::-webkit-scrollbar-track { + background-color: @color-scrollbar-track; + } + + ::-webkit-scrollbar-thumb { + background-color: @color-scrollbar-thumb; + } + } +} diff --git a/styles/layout.less b/styles/layout.less new file mode 100644 index 0000000..912d314 --- /dev/null +++ b/styles/layout.less @@ -0,0 +1,414 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/*** Responsive design - Layout ***/ + +/* +- Large screen (width > 1200px) + ----------------------------------------------------------------------------------------------------- + | menu | sidebar | list | content | + ----------------------------------------------------------------------------------------------------- +- Normal screen (1200px => width => 768px) - typical: 768x1024 (iPad Mini/Air) + ------------------------------------------------------------------- + |menu| sidebar/list | content | + ------------------------------------------------------------------- +- Small (480px < width < 768px) + ------------------------------------------ + |menu| sidebar/list/content | + ------------------------------------------ +- Phone (width <= 480px) - typical: 320x480 (iPhone 5), 375x667 (iPhone 6-7), 360x564 (Galaxy S6) + ------------------------ + | sidebar/list/content | + ------------------------ +*/ + +html { + height: 100%; + font-size: @page-font-size; +} + +body { + min-width: @page-min-width; + height: 100%; + color: @color-font; + overflow: hidden; + + html.iframe & { + overflow: auto; + } +} + +#layout { + overflow: hidden; + display: flex; + height: 100%; + width: 100%; + + & > div { + & > .scroller { + flex: 1; + position: relative; // for .listing-info positioning + } + + & > .header, + & > .footer { + font-size: @layout-header-font-size; + font-weight: bold; + line-height: @layout-header-height; + height: @layout-header-height; + min-height: @layout-header-height; + padding: 0 .25em; + margin: 0; + position: relative; // for absolute positioning of searchbar + overflow: hidden; + white-space: nowrap; + display: flex; + justify-content: center; + } + + & > .header { + border-bottom: 1px solid @color-layout-border; + color: @color-layout-header; + background-color: @color-layout-header-background; + + .header-title { + .overflow-ellipsis(); + flex: 1; + text-align: center; + margin: 0 -20rem; + } + + a.button { + color: @color-toolbar-button; + } + + a.toolbar-list-button, + a.toolbar-menu-button { + order: 99; // always the last button + } + } + + & > .footer { + border-top: 1px solid @color-layout-border; + background-color: @color-layout-footer-background; + + & when not (@layout-footer-height = @layout-header-height) { + height: @layout-footer-height; + min-height: @layout-footer-height; + line-height: @layout-footer-height; + } + + &.small { + height: @layout-footer-small-height; + min-height: @layout-footer-small-height; + line-height: @layout-footer-small-height; + } + + &:empty { + display: none; + } + } + } +} + +#layout-sidebar { + position: relative; // e.g. for .column-resizer + display: flex; + flex-direction: column; + flex: 2; + max-width: 30%; + min-width: 220px; + border-right: 1px solid @color-layout-border; + background-color: @color-layout-sidebar-background; + + &.sidebar-right { + order: 2; + border-right: 0; + border-left: 1px solid @color-layout-border; + // sidebar on right is unusual situation, probably there's no list in layout, + // in such a case we can make it a little bit wider + flex: 3; + } +} + +#layout-list { + position: relative; // e.g. for .column-resizer + display: flex; + flex-direction: column; + flex: 3; + max-width: 30%; + min-width: 300px; + border-right: 1px solid @color-layout-border; + background-color: @color-layout-list-background; +} + +#layout-content { + display: flex; + flex: 6; + flex-direction: column; + background-color: @color-layout-content-background; + width: 100%; + + html.iframe & { + height: 100%; + } + + & > .formcontent, // e.g. Help plugin + & > .content { + height: 100%; + width: 100%; + overflow: auto; + flex: 1; + } + + .iframe-wrapper { + width: 100%; + flex: 1; + + iframe { + width: 100%; + height: 100%; + border: 0; + } + } + + &.only > .scroller { + overflow: auto; + } +} + +#layout-menu { + &.popover { + left: 0 !important; + } + + .popover-header { + height: @layout-header-height; + line-height: @layout-header-height; + border: 0; + border-radius: 0; + text-align: center; + + img { + max-height: @layout-header-height; + max-width: @layout-menu-width; + padding: .25rem; + + @media screen and (min-width: (@screen-width-xs + 1px)) and (max-width: @screen-width-medium) { + max-width: @layout-menu-width * 0.45; + } + } + + @media screen and (min-width: (@screen-width-xs + 1px)) { + padding: 0 !important; + background-color: @color-taskmenu-background !important; + + a { + display: none !important; + } + } + + html.layout-phone & { + display: flex !important; + align-items: center; + justify-content: center; + padding: 0 .5rem; + + img { + max-width: @layout-mobile-menu-width - 50px; + } + + a { + width: auto; + flex: 1; + + &:before { + height: @layout-touch-header-height; + float: right; + } + + .inner { + display: none; + } + } + } + } +} + +.column-resizer { + cursor: col-resize; + z-index: 1; + position: absolute; + top: 0; + right: -3px; + width: 6px; + height: 100%; + + &.inverted { + right: auto; + left: -3px; + } + + &.active { + width: 10000px; + right: -5000px; + + &.inverted { + right: auto; + left: -5000px; + } + } +} + +@media screen and (max-width: @screen-width-large) { + #layout-sidebar, + #layout-list { + min-width: 260px; + flex: 3; + } + + #layout-list > .header > a.button { + padding: 0 .25rem; + margin: 0 .25rem; + } +} + +@media screen and (max-width: @screen-width-medium) { + // Disable column resizing by hiding splitters and resetting columns width + .column-resizer { + display: none; + } + #layout-sidebar, + #layout-list { + width: auto !important; + flex: 3 !important; + } +} + +@media screen and (max-width: @screen-width-small) { + #layout-sidebar, + #layout-list { + max-width: none; + border: 0 !important; + } + + #layout > div > .header { + background-color: @color-layout-mobile-header-background; + + a.button { + // make the button active area smaller on touch devices + margin: 0 .3rem !important; + padding: 0 !important; + + &:before { + font-size: 1.75rem; + height: @layout-touch-header-height; + margin: 0; + } + + &.filter:before { + font-size: 1.6rem; // this icon is too big in FA5 + } + + .inner { + display: none; + } + } + } + + #layout > div > .footer { + background-color: @color-layout-mobile-footer-background; + } + + a.toolbar-list-button { + display: none; + } +} + +@media screen and (max-width: @screen-width-xs) { +} + +@media screen and (max-width: @screen-width-mini) { + #layout-sidebar, + #layout-list { + min-width: @page-min-width; + } +} + +@media screen and (min-width: (@screen-width-xs + 1px)) { + a.task-menu-button { + display: none; + } + + #layout-menu { + // FIXME: we set background color here not in taskmenu.less, because + // otherwise background is partially white on Android/iOS + background-color: @color-taskmenu-background; + width: @layout-menu-width-sm; + } +} + +@media screen and (min-width: (@screen-width-small + 1px)) { + .floating-action-buttons, + #layout-content > .header > .header-title, + #layout > div > .header > .buttons, + a.toolbar-menu-button { + display: none; + } +} + +@media screen and (min-width: (@screen-width-medium + 1px)) { + #layout-menu { + width: @layout-menu-width; + } +} + +@media screen and (min-width: (@screen-width-large + 1px)) { + #layout-list > .header > .header-title:not(.all-sizes), + a.toolbar-list-button, + a.back-list-button, + a.back-sidebar-button { + display: none; + } +} + +html.layout-phone { + .hidden-phone { + display: none !important; + } +} + +html.layout-phone, +html.layout-small { + .hidden-small { + display: none !important; + } +} + +html.layout-small { + .hidden-lbs { + display: none !important; + } +} + +html.layout-large, +html.layout-normal { + .hidden-lbs, + .hidden-big { + display: none !important; + } +} + +html.layout-large { + .hidden-large { + display: none !important; + } +} diff --git a/styles/mixins.less b/styles/mixins.less new file mode 100644 index 0000000..7e4fabe --- /dev/null +++ b/styles/mixins.less @@ -0,0 +1,62 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/*** Font-icons ***/ + +.font-icon-class { + font-size: 1.25em; + // FIXME: with inline-block we have some problems with icon alignment + // display: inline-block; + display: block; + float: left; + margin: 0 .25rem 0 0; + width: 1.18em; + height: 1em; + font-family: 'Icons'; + font-style: normal; + font-weight: 900; + text-decoration: inherit; + text-align: center; + speak: none; + font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; +} + +.animated-icon-class { + // spinner-border is defined in Bootstrap + -webkit-animation: spinner-border 1.5s infinite linear; + animation: spinner-border 1.5s infinite linear; +} + +.font-icon-solid(@icon) { + content: @icon; + font-weight: 900; +} + +.font-icon-regular(@icon) { + content: @icon; + font-weight: 400; +} + +.overflow-ellipsis { + overflow: hidden; + text-overflow: ellipsis; +} + +.font-family { + font-family: Roboto, sans-serif; +} + +.style-input-focus { + border-color: @color-input-border-focus; + box-shadow: 0 0 0 .2rem @color-input-border-focus-shadow; +} diff --git a/styles/print.less b/styles/print.less new file mode 100644 index 0000000..2f06232 --- /dev/null +++ b/styles/print.less @@ -0,0 +1,78 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/*** Additional styles for printouts ***/ + +body { + overflow: auto; + height: auto; +} + +#print-layout { + margin: 1rem; + + #logo { + max-height: 80px; + } + + // Overwrites for mail message printouts + + .image-attachment { + .image-link { + margin-bottom: .5rem; + } + + .attachment-links { + display: none; + } + } + + #message-header { + margin-bottom: .5rem; + } + + .attachment-size { + padding-left: .1rem; + } + + blockquote { + page-break-inside: auto; + } + + // Overwrites for contact printouts + + .formcontent { + padding: 0; + + legend { + margin-top: .5rem; + } + + .row .form-control-plaintext { + padding: .1rem; + } + + .contactfield { + padding: .2rem 0; + } + } + + .propform.grouped .row.input-group .input-group-text { + padding: 0; + min-width: 12rem; + background: #fff; + border: 0; + } + + .contact-header { + margin-bottom: 0; + } +} diff --git a/styles/styles.less b/styles/styles.less new file mode 100644 index 0000000..b6932ed --- /dev/null +++ b/styles/styles.less @@ -0,0 +1,458 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +@import "global"; +@import "layout"; +@import "widgets/common"; +@import "widgets/buttons"; +@import "widgets/jqueryui"; +@import "widgets/dialogs"; +@import "widgets/menu"; +@import "widgets/messages"; +@import "widgets/lists"; +@import "widgets/forms"; +@import "widgets/editor"; + + +/*** Login form ***/ + +.task-login { + #layout-content { + text-align: center; + width: 100%; + display: block; + } + + #logo { + display: inline-block; + position: relative; + top: 16vh; + max-height: 100px; + } +} + +#login-form { + margin: 0 auto; + top: 20vh; + width: 95%; + max-width: 320px; + position: relative; + + // Fixes table width in IE11 + table, tbody { + display: block; + } + + // Fixes input width in IE11 + .row { + margin-right: 0; + margin-left: 0; + } + + .oauthlogin { + margin-top: 1em; + padding-top: 1em; + } + + .formbuttons + .oauthlogin { + border-top: 1px solid #ccc; + } +} + +#rcmloginsubmit { + &:before { + display: none !important; + } +} + +#login-footer { + flex: 1; + color: @color-black-shade-text; + + & > div { + margin-top: 1rem; + padding: 1rem; + background: @color-black-shade-bg; + border-radius: .3rem; + } +} + +#login-addon { + position: absolute; + bottom: 0; + max-height: 30%; + margin: 1rem !important; + width: auto !important; + overflow: auto; + + @media screen and (min-width: (@screen-width-small + 1px)) { + max-width: @screen-width-small; + margin: auto !important; + bottom: 1rem; + left: 0; + right: 0; + } +} + +body.task-error-login #layout { + #layout-menu, + #layout-content > .header { + display: none; + } +} + +/*** Addressbook UI ***/ + +#contactpic { + width: @layout-contact-icon-width; + height: @layout-contact-icon-height; + border-radius: .5rem; + overflow: hidden; + display:table-cell; + vertical-align:middle; + text-align: center; + background-color: @color-image-upload-background; + + img { + max-width: @layout-contact-icon-width; + max-height: @layout-contact-icon-height; + } +} + +#contacthead { + .names { + margin-bottom: .5rem; + + span.namefield { + font-size: 1.5rem; + font-weight: bold; + line-height: 1.2; + } + } + + &.readonly { + .source.row { + color: @color-form-hint; + font-size: 90%; + margin-bottom: .25rem; + } + } +} + +/*** Mail UI ***/ + +#message-header { + margin-bottom: 1rem; + + & > .subject { + font-size: 1.5rem; + font-weight: bold; + + body.status-flagged &:before { + &:extend(.font-icon-class); + display: inline; + float: none; + content: @fa-var-flag; + font-size: 1em; + color: @color-error; + } + + a.extwin { + text-decoration: none; + + &:before { + &:extend(.font-icon-class); + float: none; + display: inline-block; + font-size: 75%; + line-height: 1.5; + margin: 0; + content: @fa-var-external-link-square-alt; + } + } + + span.inner { + display: none; + } + } + + & > .header { + display: flex; + + img.contactphoto { + margin: 0 1rem 0 0; + border-radius: 50%; + width: @mail-header-photo-height; + height: @mail-header-photo-height; + object-fit: cover; + background: @color-image-upload-background; + } + } + + .header-content { + min-height: @mail-header-photo-height; + flex: 1; + + &.details-view { + .header-summary { + display: none; + } + .header-headers { + display: initial; + } + } + } + + .header-summary { + margin-top: .25rem; + + & > span { + display: inline-block; + } + } + + .header-headers { + display: none; + + .header-title { + white-space: nowrap; + color: @color-black-shade-text; + font-weight: bold; + padding-right: 1rem; + vertical-align: top; + } + } + + .header-links { + margin-top: .25rem; + + a { + font-size: 90%; + margin-right: .5rem; + text-decoration: none; + white-space: nowrap; + display: inline-block; + + &:before { + &:extend(.font-icon-class); + height: 1.5rem; + line-height: 1.3; + } + + &.headers-details:before { + content: @fa-var-envelope; + } + + &.headers-summary:before { + .font-icon-regular(@fa-var-envelope); + } + + &.headers-all:before { + content: @fa-var-info-circle; + } + + &.html:before { + content: @fa-var-image; + } + + &.plain:before { + content: @fa-var-align-justify; + } + + &.zipdownload:before { + content: @fa-var-download; + } + } + } +} + +.message-partheaders { + padding: .25rem .5rem; + margin: .5rem 0 -.5rem 0; + border-top: 1px solid @color-messagepart-border; + background-color: @color-messagepart-background; + + table.headers-table { + font-size: 90%; + color: @color-mail-headers; + + .header-title { + .overflow-ellipsis(); + white-space: nowrap; + max-width: 8em; + font-weight: bold; + padding-right: 1rem; + vertical-align: top; + } + + .subject { + font-weight: bold; + } + + & + .message-part, + & + .message-htmlpart { + border-top: 0; + margin: 0; + } + } +} + +#message-content { + .attachmentslist:not(:empty) { + margin-bottom: 1rem; + } +} + +#messagebody { + &.mailvelope { + iframe { + min-height: 75vh; + } + } +} + +.message-part, +.message-htmlpart { + padding-top: .5rem; + // Fixes absolute positioned mail message content + position: relative; + + &:not(:first-child) { + border-top: 1px solid @color-messagepart-border; + margin-top: .5rem; + } + + &:last-child { + margin-bottom: .5rem; + } + + div.rcmBody { + // Remove margins that can be set by the mail message styles + margin: 0 auto !important; + } + + blockquote { + .overflow-ellipsis(); + color: @color-blockquote-0; + border-left: 2px solid @color-blockquote-0-border; + border-right: 2px solid @color-blockquote-0-border; + background-color: @color-blockquote-background; + margin: 2px 0; + padding: 0 .4em; + + blockquote { + color: @color-blockquote-1; + border-left: 2px solid @color-blockquote-1-border; + border-right: 2px solid @color-blockquote-1-border; + + blockquote { + color: @color-blockquote-2; + border-left: 2px solid @color-blockquote-2-border; + border-right: 2px solid @color-blockquote-2-border; + } + } + + span.blockquote-link { + top: 0; + cursor: pointer; + right: .5rem; + min-width: 4rem; + padding: .2rem .25rem .2rem .5rem; + font-size: 90%; + text-align: center; + color: @color-black-shade-text; + background: @color-black-shade-bg; + border: 1px solid @color-black-shade-border; + border-radius: .3rem; + line-height: 1; + .font-family(); // don't inherit monospace font + + &:after { + &:extend(.font-icon-class); + content: @fa-var-angle-down; + display: inline-block; + float: none; + margin: 0; + font-size: 90%; + } + + &.collapsed:after { + content: @fa-var-angle-up; + } + } + + &.blockquote-header { + text-overflow: ellipsis !important; + padding-right: 5rem !important; + } + } +} + +.message-part { + span.sig { + color: @color-mail-signature; + } + + div.pre { + font-family: monospace; + font-size: 13px; + } + + // This is needed for proper display of quoted plain text + blockquote { + display: inline-block; + min-width: 100%; + + & + br { + // compensate the spacing "removed" by the inline-block style above + display: block; + margin-top: 1em; + } + } +} + +#compose-attachments { + margin: 1rem 1rem 0 1rem; +} + +#composestatusbar { + opacity: .3; + right: 2.5rem; + + @media screen and (min-width: (@screen-width-small + 1px)) { + display: none; + } + + a.button { + display: inline-block; + + &:before { + line-height: @layout-touch-header-height; + font-size: 1.25rem !important; + } + } +} + +/*** Settings UI ***/ + +// A default icon for settings menu entries added by plugins +.settings-default-icon { + tr > td.section::before, + li > a:before { + content: @fa-var-cog; + } +} + +& when (@dark-mode-enabled = true) { + @import "dark"; +} + +@import (optional) "_styles"; diff --git a/styles/variables.less b/styles/variables.less new file mode 100644 index 0000000..6d3c90c --- /dev/null +++ b/styles/variables.less @@ -0,0 +1,63 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +@import (reference) "fontawesome"; +@import (reference) "colors"; + +@dark-mode-enabled: true; // on change also have to change dark_mode_support in meta.json + +@screen-width-large: 1200px; +@screen-width-medium: 1024px; +@screen-width-small: 768px; +@screen-width-xs: 480px; +@screen-width-mini: 320px; +@screen-width-touch: @screen-width-medium; +@screen-width-bs-phone: 576px; + +@page-font-size: 14px; +@page-min-width: 240px; + +// Note: we'll set some values in pixels instead of rem to eliminate +// Firefox sub-pixel rendering bug(s) + +@layout-menu-width: floor(5.6 * @page-font-size); +@layout-menu-width-sm: floor(3 * @page-font-size); +@layout-header-height: floor(4.2 * @page-font-size); +@layout-footer-height: @layout-header-height; +@layout-footer-small-height: floor(2.5 * @page-font-size); +@layout-header-font-size: 1rem; +@layout-searchbar-height: floor(2.6 * @page-font-size); + +@layout-touch-header-height: @layout-header-height; +@layout-touch-header-font-size: floor(1.2 * @page-font-size); +@layout-touch-menu-record-height: floor(3.4 * @page-font-size); +@layout-touch-menu-record-font-size: floor(1.2 * @page-font-size); +@layout-touch-icon-width: 2.2em; + +@layout-mobile-menu-width: (@screen-width-mini * .85); + +@layout-contact-icon-width: 112px; +@layout-contact-icon-height: 135px; + +@listing-line-height: floor(2.5 * @page-font-size); +@listing-touch-line-height: floor(3.4 * @page-font-size); +@listing-treetoggle-width: 1.5em; + +@mail-header-photo-height: 4rem; + +// Scrollbars +@scrollbar-width: thin; // 'auto' or 'thin' or 'unset' + +// Additional icons +@icon-resize-corner: data-uri("image/svg+xml;charset=utf-8", "../images/corner-handle.svg"); // size: 16x16 +@icon-file-drop: data-uri("image/svg+xml;charset=utf-8", "../images/download.svg"); + +@import (reference, optional) "_variables"; diff --git a/styles/widgets/buttons.less b/styles/widgets/buttons.less new file mode 100644 index 0000000..b4c02e4 --- /dev/null +++ b/styles/widgets/buttons.less @@ -0,0 +1,349 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/*** Buttons ***/ + + +.button.disabled { + opacity: .5; +} + +a.button { + text-decoration: none !important; +} + + +/* font-icons */ + +a.button.icon, +button.btn { + &:before { + &:extend(.font-icon-class); + } + &.sidebar-menu:before, + &.toolbar-menu-button:before, + &.toolbar-list-button:before { + content: @fa-var-ellipsis-v; + width: 1em; + } + &.task-menu-button:before { + content: @fa-var-bars; + } + &.back-sidebar-button:before, + &.back-content-button:before, + &.back-list-button:before { + content: @fa-var-chevron-left; + } + &.refresh:before { + content: @fa-var-sync; + } + &.generate:before, + &.yes:before, + &.submit:before, + &.continue:before, + &.save:before { + content: @fa-var-check; + } + &.create:before { + content: @fa-var-plus-square; + } + &.edit:before { + content: @fa-var-pencil-alt; + } + &.qrcode:before { + content: @fa-var-qrcode; + } + &.search:before { + content: @fa-var-search; + } + &.filter:before { + content: @fa-var-filter; + font-size: 1.2em; // this icon is too-big in FA5 + } + &.import:before { + content: @fa-var-upload; + } + &.export:before { + content: @fa-var-download; + } + &.discard:before, + &.delete:before { + .font-icon-regular(@fa-var-trash-alt); + } + &.next:before { + content: @fa-var-arrow-right; + } + &.restore:before { + content: @fa-var-undo; + } + &.send:before, + &.bounce:before { + content: @fa-var-paper-plane; + } + &.attach:before { + content: @fa-var-paperclip; + } + &.attach.vcard:before { + content: @fa-var-user; + } + &.no:before, + &.close:before, + &.cancel:before { + content: @fa-var-times; + } + &.back:before { + content: @fa-var-chevron-left; + } + &.remove:before { + content: @fa-var-times; + } + &.unlock:before { + content: @fa-var-unlock; + } + &.help:before { + .font-icon-regular(@fa-var-life-ring); + } + &.folders:before { + content: @fa-var-folder-open; + } + &.options:before { + content: @fa-var-sliders-h; + } + &.tools:before, + &.settings:before { + content: @fa-var-cog; + } + &.properties:before { + content: @fa-var-info-circle; + } + &.selection:before { + .font-icon-regular(@fa-var-check-square); + } + &.insert.recipient:before { + content: @fa-var-user-plus; + } + &.encrypt:before { + content: @fa-var-lock; + } + &.sign:before { + content: @fa-var-signature; + } + &.sso:before { + content: @fa-var-sign-in-alt; + } + &.extwin:before { + content: @fa-var-external-link-square-alt; + } +} + +a.btn, +button.btn { + &:before { + display: inline !important; + float: none !important; + vertical-align: middle; + margin-right: .4rem !important; // !important needed for a.btn + } + + &.oauth.google:before, + &.oauth.outlook:before { + content: " "; + display: inline-block !important; + height: 1.5rem; + width: 1.5rem; + margin-right: .8rem !important; + background-size: 100% auto; + } + + &.oauth.google:before { + background: url('../images/google-icon.svg') top left no-repeat; + } + + &.oauth.outlook:before { + background: url('../images/microsoft-icon.svg') top left no-repeat; + } +} + +a.button.icon { + &.dropdown:before { + content: @fa-var-caret-down; + font-size: 1em; + } + & > span.inner { + display: none; + } +} + +html.touch { + .btn:focus { + box-shadow: none !important; + } +} + +@floating-action-button-size: 4rem; + +.floating-action-buttons { + position: absolute; + right: 0; + bottom: 0; + + .footer:not(:empty) + & { + bottom: @layout-footer-small-height; + } + + a.button { + display: block; + float: left; + width: @floating-action-button-size; + height: @floating-action-button-size; + border-radius: 50%; + background: @color-main; + color: white; + opacity: .95; + box-shadow: 0 0 5px 5px lighten(@color-main, 35%); + margin: 0 1rem 1rem 0; + + &:before { + &:extend(.font-icon-class); + content: @fa-var-plus; + width: @floating-action-button-size; + height: @floating-action-button-size; + line-height: @floating-action-button-size; + } + + &.compose { + &:before { + content: @fa-var-pen; + } + } + + .inner { + display: none; + } + } +} + +/*** Bootstrap button style overrides ***/ + +.btn { + &:focus { + box-shadow: 0 0 0 .2rem fade(@color-btn-primary-background, 30%); + } +} + +.btn-link { + color: @color-link; +} + +.btn-secondary { + color: @color-btn-secondary; + background: @color-btn-secondary-background; + border-color: @color-btn-secondary-background; + + &:focus { + background: darken(@color-btn-secondary-background, 5%); + border-color: darken(@color-btn-secondary-background, 7%); + box-shadow: 0 0 0 .2rem fade(@color-btn-secondary-background, 50%); + } + + &:hover { + background: darken(@color-btn-secondary-background, 5%); + border-color: darken(@color-btn-secondary-background, 7%); + } + + &.disabled, + &:disabled { + background: @color-btn-secondary-background; + border-color: @color-btn-secondary-background; + } + + &:not(:disabled):not(.disabled) { + &:active, + &.active { + background: darken(@color-btn-secondary-background, 10%); + border-color: darken(@color-btn-secondary-background, 12%); + + &:focus { + box-shadow: 0 0 0 .2rem fade(@color-btn-secondary-background, 53%); + } + } + } +} + +.btn-primary { + color: @color-btn-primary; + background: @color-btn-primary-background; + border-color: @color-btn-primary-background; + + &:focus { + background: darken(@color-btn-primary-background, 5%); + border-color: darken(@color-btn-primary-background, 7%); + box-shadow: 0 0 0 .2rem fade(@color-btn-primary-background, 50%); + } + + &:hover { + background: darken(@color-btn-primary-background, 5%); + border-color: darken(@color-btn-primary-background, 7%); + } + + &.disabled, + &:disabled { + background: @color-btn-primary-background; + border-color: @color-btn-primary-background; + } + + &:not(:disabled):not(.disabled) { + &:active, + &.active { + background: darken(@color-btn-primary-background, 10%); + border-color: darken(@color-btn-primary-background, 12%); + + &:focus { + box-shadow: 0 0 0 .2rem fade(@color-btn-primary-background, 53%); + } + } + } +} + +.btn-danger { + color: @color-btn-danger; + background: @color-btn-danger-background; + border-color: @color-btn-danger-background; + + &:focus { + background: darken(@color-btn-danger-background, 5%); + border-color: darken(@color-btn-danger-background, 7%); + box-shadow: 0 0 0 .2rem fade(@color-btn-danger-background, 50%); + } + + &:hover { + background: darken(@color-btn-danger-background, 5%); + border-color: darken(@color-btn-danger-background, 7%); + } + + &.disabled, + &:disabled { + background: @color-btn-danger-background; + border-color: @color-btn-danger-background; + } + + &:not(:disabled):not(.disabled) { + &:active, + &.active { + background: darken(@color-btn-danger-background, 10%); + border-color: darken(@color-btn-danger-background, 12%); + + &:focus { + box-shadow: 0 0 0 .2rem fade(@color-btn-danger-background, 53%); + } + } + } +} diff --git a/styles/widgets/common.less b/styles/widgets/common.less new file mode 100644 index 0000000..87a16ff --- /dev/null +++ b/styles/widgets/common.less @@ -0,0 +1,585 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/*** Common UI elements ***/ + +.rcmaddcontact, +.hidden, +.voice { + display: none !important; +} + +font.bold { + font-weight: bold; +} + +#rcmdraglayer { + min-width: 260px; + width: 260px; + background-color: @color-drag-layer-background; + color: @color-drag-layer; + box-shadow: 3px 3px 5px @color-drag-layer-shadow; + border-radius: .3rem; + z-index: 250; + opacity: .92; + padding: .5rem; + white-space: nowrap; + + div { + line-height: 1.6em; + .overflow-ellipsis(); + } +} + +.frame-content { + padding: 1rem; + + h2 { + font-weight: bold; + font-size: 1.5em; + } + + h3 { + font-weight: bold; + font-size: 1.25em; + } +} + +.listbox { + .scroller { + width: 100%; + overflow-x: hidden; + overflow-y: auto; + } + + .navlist { + height: 0; + flex: initial !important; + + .listing { + tr:last-child td, + li:last-child { + border-bottom: 0; + } + } + } + + .popup & { + height: 100%; + display: flex; + flex-direction: column; + + .scroller { + flex: 1; + } + + .footer { + border-top: 1px solid @color-layout-border; + background-color: @color-searchbar-background; + } + } +} + +.contact-header { + display: flex; + margin-bottom: 1rem; + + .contact-photo { + min-width: @layout-contact-icon-width; + } + + .contact-head { + margin-left: 1rem; + margin-top: 0 !important; + + legend { + display: none; + } + } +} + + +@image-attachment-size: 250px; + +// this is when image thumbnails are enabled +p.image-attachment { + position: relative; + border: 1px solid @color-border; + border-radius: .3rem; + background-color: @color-message-background; + float: left; + margin: .5rem; + min-width: 47%; + min-height: @image-attachment-size; + overflow: hidden; + // use flexbox to center the image + display: flex; + justify-content: center; + + @media screen and (max-width: @screen-width-xs) { + float: none; + margin: .5rem 0 .5rem 0; + } + + .image-link { + align-self: center; + text-align: center; + margin: 1.6rem .5rem; + } + + span { + color: @color-form-hint; + padding: 0 .5rem; + font-size: 90%; + white-space: nowrap; + position: absolute; + line-height: 1.5rem; + } + + .image-filename { + .overflow-ellipsis(); + left: 0; + top: 0; + right: 0; + padding-right: 4rem; + } + + .image-filesize { + right: 0; + top: 0; + } + + .attachment-links { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + text-align: center; + + a { + text-decoration: none; + display: inline-block; + padding: 0 .5rem; + line-height: 1.5rem; + } + + a:before { + &:extend(.font-icon-class); + display: inline-block; + } + + a.open:before { + content: @fa-var-external-link-square-alt; + } + + a.download:before { + content: @fa-var-download; + } + } +} + +// this is when image thumbnails are disabled +fieldset.image-attachment { + margin-top: .5rem; + + legend { + color: @color-form-hint; + font-size: .9rem; + border-top: 1px solid lighten(@color-mail-headers, 50%); + margin: 0; + } + + img { + max-width: 100%; + } +} + +#folder-selector { + overflow-y: auto; +} + +.noselect { + user-select: none; + -moz-user-select: none; + -khtml-user-select: none; + -ms-user-select: none; + -webkit-user-select: none; +} + +.iframe-loader { + width: 100%; + position: absolute; + top: 0; + bottom: 0; + background-color: rgba(255, 255, 255, .95); + display: flex; + align-items: center; + justify-content: center; + z-index: 3; + + .spinner-border { + width: 7rem; + height: 7rem; + color: @color-spinner-circle; + border: 1rem solid; + border-color: currentColor @color-spinner-item currentColor currentColor; + } +} + +.footer.toolbar + .iframe-loader { + top: @layout-header-height; + bottom: @layout-header-height; +} + +// iOS: Fix scrolling of iframe, display scrollbars on scrollable elements +.ios-scroll { + padding: 0; + -webkit-overflow-scrolling: touch !important; + overflow: scroll !important; + + &.iframe-wrapper { + margin-top: 1px; // FIXME: without this scrolling hides the wrapper neighbours' border + } +} + +.webkit-scroller { + &::-webkit-scrollbar { + -webkit-appearance: none; + } + + &::-webkit-scrollbar:vertical { + width: .5rem; + } + + &::-webkit-scrollbar:horizontal { + height: .5rem; + } + + &::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, .3); + border-radius: .25rem; + border: 2px solid #fff; + } +} + +.quota-widget { + width: 100%; + max-width: 15em; + padding: .5rem 1rem; + display: flex; + align-items: center; + color: @color-quota-text; + + &:before { + &:extend(.font-icon-class); + content: @fa-var-hdd; + line-height: 1; + } + + .count { + font-size: 80%; + order: 2; + } + + .bar { + flex: 1; + height: .5rem; + margin: 0 1rem; + background-color: @color-quota-background; + border: 1px solid @color-layout-border; + border-radius: .25rem; + overflow: hidden; + } + + .value { + display: block; + background-color: @color-quota-value; + height: 1rem; + opacity: .75; + + &.warning { + background-color: @color-quota-value-warning; + } + } +} + +.image-tools { + position: absolute; + top: 5rem; + left: 0; + height: @layout-header-height; + overflow: hidden; + transform: translateX(-87%); + transition: transform 0.3s ease-in-out; + background-color: @color-image-tools-background; + border-radius: 0 .3rem .3rem 0; + + .menu { + float: left; + } + + a.button.icon.tools { + padding: 0 .25rem; + display: inline-block; + height: @layout-header-height; + + span.inner { + display: none; + } + + &:before { + line-height: @layout-header-height; + margin: 0; + } + } + + &.open { + transform: translateX(0); + + a.button.icon.tools:before { + content: @fa-var-chevron-left; + } + } + + a { + color: @color-image-tools !important; + + &:focus, + &:hover { + background-color: @color-image-tools-hover !important; + outline: 0; + } + } +} + +.quota-info { + width: 100%; + display: table !important; + + td,th { + text-align: center; + white-space: nowrap; + } + + th { + border-top: 0; + } + + .root { + line-height: 1; + font-style: italic; + color: @color-popover-separator; + background-color: @color-popover-separator-background; + } + + th:first-child, + .name { + text-align: left; + } +} + +// Make Bootstrap tabs non-wrappable +.nav-tabs { + flex-wrap: nowrap; + + .nav-item { + white-space: nowrap; + overflow: hidden; + } + + .nav-link { + .overflow-ellipsis(); + } +} + +.props-table { + td.title { + width: 7em; + } +} + +.table-widget { + display: flex; + flex-direction: column; + margin-bottom: .5rem; + border: 1px solid @color-table-border; + + & > .content { + overflow-x: auto; + flex-grow: 1; + height: 18.5em; + + table th { + border-top: 0; + } + } + + & > .footer { + height: 3.5rem; + border-top: 1px solid @color-table-border; + text-align: left; + + a { + padding: .2rem .45rem !important; + height: ~"calc(3.5rem - 1px)" !important; + } + } + + table { + margin: 0; + max-height: 18.5em; + } + + // Options table is a table with first column for identifier/description + // and other columns for a state flag. E.g. ACL table + table.options-table { + td,th { + text-align: center; + vertical-align: middle; + + &:first-child { + .overflow-ellipsis(); + text-align: left; + } + } + + tr:last-child td { + border-bottom: 1px solid @color-table-border; + } + + tr.selected td { + background-color: @color-table-selected-background; + color: @color-table-selected; + outline: 0; + } + + td:not(:first-child) span { + display: inline-block; + line-height: 1.25; + + &:before { + &:extend(.font-icon-class); + } + } + + td.enabled span:before { + content: @fa-var-check; + } + + td.partial span:before { + opacity: .3; + content: @fa-var-check; + } + } +} + +table.compact-table { + margin: 0; + width: 100%; + + *:not(.invalid-feedback) { + font-size: inherit; + } + + td { + padding: .25rem; + border: 0; + } + + td:first-child { + padding-left: 0; + } + + td:last-child { + padding-right: 0; + } +} + +table.table { + .checkbox-cell { + width: 3rem; + white-space: nowrap; + overflow: hidden; + text-align: center; + padding: .5rem; + + html.touch & { + padding: .5rem .3rem; + } + } + + th.checkbox-cell { + padding: .75rem 0; + max-width: 1rem; + + &:before { + &:extend(.font-icon-class); + cursor: pointer; + margin: 0 1rem; + line-height: 1; + } + + &.subscription:before { + content: @fa-var-rss-square; + } + + &.alarm:before { + .font-icon-regular(@fa-var-bell); + } + + &.read:before { + content: @fa-var-eye; + } + + &.write:before { + content: @fa-var-pencil-alt; + } + } + + .buttons-cell { + width: 1%; + white-space: nowrap; + text-align: center; + + a.button:before { + line-height: 1; + float: none; + display: inline-block; + } + + @media screen and (min-width: @screen-width-xs) { + a.button .inner { + display: inline; + } + } + } + + label { + margin: 0; + display: inline; + } + + fieldset.tab-pane & thead th { + border: 0; + } + + tr.deleted td { + color: @color-list-deleted !important; + } +} + +/* Bootstrap's .table style overwrites */ +.table { + thead th { + border-width: 1px; + white-space: nowrap; + } +} diff --git a/styles/widgets/dialogs.less b/styles/widgets/dialogs.less new file mode 100644 index 0000000..3cae8a3 --- /dev/null +++ b/styles/widgets/dialogs.less @@ -0,0 +1,263 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/*** Dialogs and popovers ***/ + +.popupmenu { + display: none; + padding: 0; + min-width: 180px; + height: 100%; + + li > a { + width: 100%; + } + + &.propform { + overflow: hidden; + padding: .25rem; // so overflow do not truncate focus outline on inputs + } + + &.simplelist { + min-width: 80px; + } +} + +.popup.justified { + display: flex; + justify-content: space-around; +} + +.popover-body { + padding: 0; + overflow-x: hidden; + + & > .popupmenu { + display: block !important; + } +} + +.popover { + box-shadow: 3px 3px 5px @color-popover-shadow; + border-color: @color-layout-border; + padding: 0; + z-index: 1300; + + .popover-header { + // On mobile don't display popup arrows and titles + display: none; + } + + @media screen and (min-width: (@screen-width-small + 1px)) { + .listing { + li:first-child { + border-radius: .25rem .25rem 0 0; + } + + li:last-child { + border-bottom-right-radius: .25rem; + border-bottom-left-radius: .25rem; + } + + ul.rounded-0 > li { + border-radius: 0; + } + } + } +} + +html.layout-small, +html.layout-phone { + .popover:not(.select-menu) { + margin: 0 !important; + padding: 0; + right: 0; + left: initial !important; + bottom: 0; + top: 0; + width: @layout-mobile-menu-width; + transform: none !important; + border-radius: 0; + border: 0; + display: flex; + flex-direction: column; + box-shadow: none; + + div.arrow { + display: none; + } + + .listing li:last-child { + border-bottom: 1px solid @color-list-border; + } + } + + .popover-overlay { + z-index: 1299; + background-color: @color-dialog-overlay-background; + position: absolute; + top: 0; + bottom: 0; + width: 100%; + } + + .popover-header { + display: block; + border-radius: 0; + border: 0; + padding: 0 .5em; + height: @layout-touch-header-height; + min-height: @layout-touch-header-height; // for when it's a flex item + line-height: @layout-touch-header-height; + font-size: @layout-touch-header-font-size; + color: @color-popover-mobile-header; + background-color: @color-popover-mobile-header-background; + + &:before { + display: none; // hide the Bootstrap's popover arrow element + } + + a { + display: inline-block; + width: 100%; + color: @color-popover-mobile-header; + } + } + + .popover-body > * { + max-height: 100% !important; + } +} + +html.touch .popover { + .listing { + li a { + line-height: @layout-touch-menu-record-height; + font-size: @layout-touch-menu-record-font-size; + padding: 0 .5em; + + &:before { + float: left; // overwrite icon float to have unified element height + } + } + } +} + +.select-menu { + max-width: initial; + margin: 0; + height: auto; + z-index: 1301; // above TinyMCE dialogs + + .popover-header { + border-radius: .25rem .25rem 0 0 !important; + } + + .listing li { + a { + padding-left: .25rem; + outline: 0; // for Android browser + } + + &:last-child { + border-bottom-right-radius: .25rem; + border-bottom-left-radius: .25rem; + } + } + + // Use 'inline' class for menus that have a list elements with no inside + // and no header + &.inline { + .listing li { + padding-right: .5rem; + + &:first-child { + border-top-left-radius: .25rem; + border-top-right-radius: .25rem; + } + } + } +} + +/** PGP Key search/import dialog **/ + +.pgpkeyimport { + div.key { + position: relative; + padding: .5rem 0; + + &.revoked, + &.disabled { + color: @color-list-secondary; + } + + label { + display: inline-block; + margin-right: 0.5em; + margin-bottom: 0; + + &:after { + content: ":"; + } + + &.keyid { + display: none; + } + } + + label + a, + label + span { + line-height: 2.6rem; + margin-right: 1em; + white-space: nowrap; + text-decoration: none; + } + + label.keyid + a { + font-weight: bold; + + &:before { + &:extend(.font-icon-class); + content: @fa-var-key; + } + } + } + + ul.uids { + margin: 0; + padding: 0; + } + + li.uid { + border: 0; + padding: .25rem 0 0 1.5em; + line-height: 1.5rem !important; + list-style-type: none; + + &:before { + &:extend(.font-icon-class); + content: @fa-var-user; + opacity: 0.25; + font-size: 1em; + line-height: 1.25; + } + } + + button.importkey { + position: absolute; + top: .5rem; + right: 0; + } + + button:disabled { + display: none; + } +} diff --git a/styles/widgets/editor.less b/styles/widgets/editor.less new file mode 100644 index 0000000..a71860f --- /dev/null +++ b/styles/widgets/editor.less @@ -0,0 +1,537 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + + +/*** Text Editor widget (and TinyMCE editor) ***/ + +// use of div.tox instead of just .tox is to have prio over TinyMCE styles +div.tox { + font-size: 1rem; + + &, :not(.svg) { + .font-family(); + } + + &.tox-tinymce { + border-radius: .25rem; + border: 1px solid @color-input-border; + } + + &.focused { + border-color: @color-input-border-focus !important; + box-shadow: 0 0 0 .2rem @color-input-border-focus-shadow !important; + } + + .tox-toolbar-overlord { + z-index: 1; // for sticky header feature + + & > div { + // The svg is copied from TinyMCE with modified height params + background: url("data:image/svg+xml;charset=utf8,%3Csvg height='33px' viewBox='0 0 40 33px' width='40' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0' y='32px' width='100' height='1' fill='%23cccccc'/%3E%3C/svg%3E"); + background-color: @color-input-addon-background; + } + } + + .tox-toolbar__primary { + border-top: 0; + } + + // This one is for mobile + .tox-toolbar { + background-color: @color-input-addon-background; + } + + .tox-edit-area { + border: 0; + } + + .tox-dialog { + border-radius: 0; + border-color: @color-layout-border; + box-shadow: none; + align-self: unset !important; + + .tox-form__group { + margin-top: 0; + margin-bottom: .75rem; + } + + .tox-dialog__body-nav-item--active { + color: @color-link; + border-color: transparent; + + &:hover { + color: @color-link-hover; + } + } + } + + .tox-dialog__body-content { + overflow: unset; + } + + .tox-dialog__content-js { + overflow: auto; + } + + .tox-dialog-wrap__backdrop { + background-color: @color-dialog-overlay-background; + } + + .tox-dialog__header { + height: (@layout-header-height - 1px); + border-bottom: 1px solid @color-dialog-header-border; + justify-content: flex-end; // fixes close button position when dialog has no title + padding: 0; + + .tox-button { + color: @color-dialog-header; + right: 0; + height: (@layout-header-height - .7rem); + width: 2.25em; + margin-right: .4rem; + + &:hover { + background: transparent; + border-color: transparent; + } + + .tox-icon { + display: none; + } + + &:before { + &:extend(.font-icon-class); + content: @fa-var-times; + line-height: 1.5rem; + margin: 0 !important; + } + } + } + + .tox-dialog__footer { + height: (@layout-footer-height - 1px) !important; + border: 0; + margin: 0; + padding: 0 1rem; + + @media screen and (max-width: @screen-width-xs) { + border-top: 1px solid @color-dialog-header-border; + } + + & > div { + white-space: nowrap; + max-height: (@layout-footer-height - 1px); + + button:first-child { + margin: 0; + } + } + + .tox-button { + .btn-primary(); + font-weight: normal; + padding: .5rem .75rem; + + &:before { + &:extend(.font-icon-class); + width: 1em; + content: @fa-var-check; + line-height: 1; + } + + // this is redundant, but required because of tinymce styles interference + &:focus:not(:disabled) { + background: @color-btn-primary-background; + border-color: @color-btn-primary-background; + } + + &.tox-button--secondary { + .btn-secondary(); + color: @color-btn-secondary; + + &:before { + content: @fa-var-times; + } + + // this is redundant, but required because of tinymce styles interference + &:focus:not(:disabled) { + background: @color-btn-secondary-background; + border-color: @color-btn-secondary-background; + } + } + } + } + + .tox-search-dialog { + .tox-form__group:not(:first-child) { + flex: initial !important; + } + + .tox-dialog__footer-start { + button { + padding: .25rem; + } + } + + .tox-dialog__footer-end { + button { + &:before { + content: @fa-var-pencil-alt !important; + } + + &:nth-of-type(1):before { + content: @fa-var-search !important; + } + } + } + } + + .tox-dialog__title { + line-height: calc(@layout-header-height - 1px); + font-size: 1.25rem; + font-weight: bold; + padding: 0 0 0 1rem; + width: 100%; + color: @color-dialog-header; + } + + // Make toolbar buttons smaller + .tox-tbtn { + height: 28px; + + &:not(.tox-tbtn--select,.tox-split-button__chevron) { + width: 32px; + } + } + + .tox-button { + line-height: 1.5; + } + + .tox-label { + color: @color-font; + padding-bottom: .25rem; + } + + // Adding .form-control does not work with TinyMCE skins, + // so we have to overwrite some props here + .tox-color-input > input, + .tox-listboxfield .tox-listbox--select, + .tox-textarea, + .tox-textfield { + .font-family() !important; + font-size: @page-font-size; + line-height: 1.5; + color: @color-font; + border-radius: .25rem; + min-height: 0; + padding: .375rem .75rem; + + &:focus { + border-color: @color-input-border-focus; + box-shadow: 0 0 0 .2rem @color-input-border-focus-shadow; + } + } + + .tox-listbox__select-label { + margin: 0; + } + + .tox-color-input span { + top: 5px; + } + + .custom-switch { + position: relative; + font-size: 1rem; + margin-top: .15rem; + + .tox-checkbox__icons { + display: none; + } + + .tox-checkbox__label { + margin: 0; + } + } + + .image-selector { + font-size: 1rem; + button { + .btn-secondary(); + padding: .5rem .75rem; + line-height: 1.5; + } + } + + // small fix for image dialog + .tox-form__controls-h-stack div:not(:last-child) { + flex: 1; + } + + .tox-collection__item-label { + white-space: nowrap; // fix TinyMCE bug + } +} + +@media screen and (max-width: @screen-width-xs) { + div.tox { + .tox-dialog { + margin: 0 !important; + width: 100% !important; + height: 100%; + left: 0 !important; + top: 0 !important; + border-width: 0 !important; + } + + .tox-dialog__header { + background-color: @color-layout-mobile-header-background; + + .tox-button { + display: none; + } + } + + .tox-dialog__title { + font-size: 1rem; + text-align: center; + padding: 0 1rem; + } + + .tox-dialog__footer { + background-color: @color-layout-mobile-footer-background; + + .tox-button { + color: @color-font !important; + background: transparent !important; + padding: .45rem; + margin: 0 !important; + border: 0; + font-size: 90%; + + &:before { + display: block; + float: none; + width: 100%; + margin: 0; + line-height: 1.75; + height: 1.75rem; + } + + &:active, + &:focus, + &:hover { + background: transparent; + border: 0; + box-shadow: none; + color: @color-font; + } + } + + & > div { + justify-content: space-evenly; + display: flex; + width: 100%; + + &:empty { + display: none; + } + } + } + } +} + +/*** Media file selector for TinyMCE ***/ + +.image-selector { + padding: 1rem .5rem 10rem .5rem !important; + + &.droptarget { + border: .2rem dashed @color-table-border; + + &:after { + margin-top: 2rem; + } + } + + form { + position: absolute; + top: 0; + } + + .attachmentslist { + margin: 0; + overflow-x: hidden; + overflow-y: auto; + height: 19.1em; + padding: 0 !important; + + li { + padding: .25rem; + cursor: pointer; + + &:before { + display: none; + } + + &:hover, + &:focus { + background: @color-list-selected-background; + } + + span.name { + flex: 1; + margin: auto; + padding-left: 1rem; + .overflow-ellipsis(); + } + + span.img { + height: 80px; + width: 80px; + display: flex; + border: 1px solid @color-list-border; + background: white; + border-radius: .75rem; + overflow: hidden; + } + + img { + margin: auto; + } + } + + html.layout-phone & { + height: auto; + } + } +} + + +/*** HTML editor widget ***/ + +.html-editor { + position: relative; + margin-bottom: .2rem; + + .editor-toolbar { + position: absolute; + left: 1px; + top: 1px; + right: 1px; + border-radius: .25rem .25rem 0 0; + border-bottom: 1px solid @color-input-border; + background-color: @color-input-addon-background; + + .mce-i-html { + display: block; + margin: 2px 2px 2px 4px; + width: 34px; + height: 28px; + border-radius: .25rem; + color: #222f3e; // from TinyMCE + + &:focus, + &:hover { + text-decoration: none; + border-color: #e2e4e7; + background-color: #dee0e2; // from TinyMCE + } + + &:before { + &:extend(.font-icon-class); + content: @fa-var-image; + margin: 0; + width: 34px; + line-height: 28px; + } + + &[disabled] { + opacity: .7; + cursor: not-allowed; + } + } + } + + // hide toolbar in html mode and in mailvelope mode + &.mailvelope .editor-toolbar, + .tox-tinymce + .editor-toolbar { + display: none; + } + + & > .googie_edit_layer, + & > textarea { + font-family: monospace; + font-size: 13px; + width: 100% !important; + padding-top: 40px; + resize: none; + } + + & > iframe { // e.g. mailvelope frame + border-radius: .3rem; + border: 1px solid @color-input-border; + min-height: 30em; + } +} + + +/*** GoogieSpell widget ***/ + +.googie_window { + width: 16rem; + height: auto; +} + +.googie_edit_layer { + font-family: monospace; + + // from Bootstrap's textarea + padding: .5rem .75rem; + border: 1px solid @color-input-border; + border-radius: .3rem; + line-height: 1.5; +} + +.googie_link { + color: @color-spellcheck-link; + text-decoration: underline; + cursor: pointer; +} + +.googie_list { + li { + min-width: 8rem; + width: auto; + + &.googie_list_onhover { + color: @color-menu-hover; + background-color: @color-menu-hover-background; + } + + .googie_list_revert:before { + &:extend(.font-icon-class); + content: @fa-var-undo; + } + + .googie_add_to_dict:before { + &:extend(.font-icon-class); + content: @fa-var-plus-square; + } + } + + input { + display: inline-block; + margin: .25rem .5rem; + } +} diff --git a/styles/widgets/forms.less b/styles/widgets/forms.less new file mode 100644 index 0000000..876bebd --- /dev/null +++ b/styles/widgets/forms.less @@ -0,0 +1,1431 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/*** Common form elements ***/ + +#uploadform { + display: none; +} + +form.smart-upload, +input.smart-upload { + visibility: hidden; + width: 1px; + height: 1px; + opacity: 0; +} + + +.propform { + // TODO: do we need this? + &:not(.popupmenu) { + width: 100%; + } + + // This is the way we can have multiple checkboxes in a single form field + .form-check td:not(.title) > label { + display: block; + margin: 0; + line-height: 2rem; + + label { + margin-right: .5rem; + } + } + + td.datetime { + display: flex; + + input:first-child { + margin-right: .5rem; + } + input:last-child { + width: 75%; + } + } + + td.rowbuttons { + width: 1%; + white-space: nowrap; + vertical-align: top; + + span { + display: none; + } + + a { + padding: 0; + line-height: 2.3rem; + height: 2.3rem; + font-size: 1rem; + + &:before { + &:extend(.font-icon-class); + content: @fa-var-plus; + vertical-align: unset; + + @media screen and (min-width: (@screen-width-bs-phone + 1px)) { + margin: 0 !important; + } + } + + &.delete:before { + content: @fa-var-trash-alt; + } + + &.advanced:before { + content: @fa-var-cog; + } + + &:not(:last-child) { + margin-right: .25rem; + } + } + } + + td.rowactions { + width: 1%; + vertical-align: top; + + .form-control { + width: auto; + } + } + + td.rowtargets { + vertical-align: top; + + .composite { + input, textarea, select, .multi-input, .input-group { + margin-bottom: .5rem; + } + + .input-group { + input, textarea, select, .multi-input { + margin-bottom: 0; + } + } + + br { + display: block; + } + } + + .input-group { + margin-bottom: .25rem; + + *:first-child.input-group-prepend { + text-align: left; + min-width: 7.5em; + + & > * { + width: 100%; + } + } + } + + & > .advanced { + margin-top: .25rem; + } + } + + td.title { + padding-top: 0; + padding-bottom: 0; + } + + td > .flexbox { + display: flex; + + & > .multi-input { + width: 100%; + margin-left: .25rem; + } + } + + &.grouped { + &.readonly { + legend { + margin: 0; + } + + .row.input-group { + margin-bottom: 0 !important; + } + + label { + min-width: 7rem; + // Overwrite Bootstrap .input-group-* style to make the label transparent + background-color: transparent; + border: 0; + border-radius: 0; + } + } + + .row.input-group { + margin-bottom: .5rem; + flex-wrap: nowrap; + + & > *:first-child { + .overflow-ellipsis(); + min-width: 8rem; + + &:not(select) { + padding: 0; + } + + @media screen and (max-width: @screen-width-xs) { + min-width: 6rem; + width: 6rem; + flex-grow: unset; + } + + label { + width: 100%; + } + } + + & > *:nth-child(2) { + flex-grow: 30; + } + + &:last-child { + margin-bottom: 1rem; + } + + select { + text-align: left; + } + + &.composite select { + height: auto; + } + + .content { + padding: 0; + display: flex; + flex-wrap: wrap; + border-radius: 0; + border-left-color: transparent; + + input { + border-radius: 0; + border-color: transparent; + } + + .ff_street { + width: 100%; + } + + .ff_locality { + width: 75%; + } + + .ff_zipcode { + width: 25%; + } + + .ff_country, .ff_region { + width: 50%; + } + } + } + + .form-control-plaintext { + flex-grow: 1; + border: 0; + } + } + + .addfield { + margin: 0; + + select { + width: 8rem; + margin-top: .5rem; + } + } + + .form-text { + font-size: 90%; + color: @color-form-hint; + } + + // Some dialogs may use simple one-row forms like this + &.row.form-group { + margin-left: 0; + margin-right: 0; + + label, div { + padding-left: 0; + padding-right: 0; + } + } + + // Some forms may use multiple elements that are not part of .input-group + // add proper spacing + select + select, + select + .input-group { + padding-top: .5rem; + } + + &.text-only { + margin-bottom: .25rem; + + tr { + margin: 0; + } + + label { + padding-bottom: 0 !important; + } + + @media screen and (max-width: @screen-width-bs-phone) { + tr { + display: table-row; + } + + td { + width: auto; + + &:first-child { + width: 33%; + } + } + + :not(tr).form-group.row { + .col-form-label { + width: 33%; + } + + & > :last-child { + width: 67%; + } + } + } + } +} + +@media screen and (max-width: @screen-width-bs-phone) { + .propform { + table.compact-table { + .rowactions > select, + .flexbox > select { + width: 100%; + } + + tr { + display: flex; + flex-direction: column; + + td { + width: 100%; + padding: .25rem 0 0 0; + + &.rowbuttons { + text-align: right; + padding-top: 0; + + a { + margin-left: .5rem; + + & > span { + display: inline; + } + } + } + } + } + } + } +} + +.propform, +.formcontent { + fieldset:not(.tab-pane):nth-of-type(n+2) { + margin-top: 1em; + } + + legend { + font-weight: bold; + font-size: 1.2em; + } + + label { + -webkit-hyphens: auto; + -ms-hyphens: auto; + hyphens: auto; + overflow: hidden; + margin-bottom: 0; + } +} + +fieldset.advanced { + > legend { + width: auto; + cursor: pointer; + + &:after { + &:extend(.font-icon-class); + float: right; + margin: 0 0 0 .25rem; + line-height: inherit; + font-size: inherit; + content: @fa-var-angle-up; + } + + &.closed:after { + content: @fa-var-angle-down; + } + } +} + +@media screen and (max-width: @screen-width-bs-phone) { + .formcontent .text-only { + .form-group:not(tr) { + margin-bottom: .25rem; + + .col-form-label { + width: 33%; + + & + span { + width: 67%; + } + } + } + } + + html.iframe .formcontent > .propform { + padding: .25rem; + } +} + +// Forms fixes for IE and Edge +html.ms .propform { + .row:not(.form-check) > td { + display: flex; + flex-wrap: wrap; // puts "hint" element below the input + } + @media screen and (min-width: @screen-width-bs-phone) { + .row.form-check > td { + display: flex; + } + } +} + + +.formcontainer { + display: flex; + flex-direction: column; + justify-content:flex-start; + overflow-y: hidden !important; + + .formcontent { + overflow-x: hidden; + overflow-y: auto; + } + + .formbuttons { + padding: 0.5rem 1rem; + + button { + margin-right: .5rem; + } + } + + // Prevent button truncation on tablets + html.iframe.ipad &, + html.iframe.webkit.tablet & { + .formbuttons { + min-height: 4rem; + } + } + + // We don't need buttons element on small devices, nor flex display + html.layout-small &, + html.layout-phone & { + display: initial; + overflow-y: auto !important; + + .formcontent { + overflow: initial !important; + } + + .formbuttons { + display: none; + } + } +} + + +.formcontent { + &:not(.popupmenu) { + padding: 1rem; + } + + .row { + margin-right: 0; // without these the form is too wide causing horizontal scrollbar appearance + margin-left: 0; + + // Note: We never use odd numbers here + .col, .col-2, .col-4, .col-6, .col-8, .col-10, .col-12, + .col-sm, .col-sm-2, .col-sm-4, .col-sm-6, .col-sm-8, .col-sm-10, .col-sm-12 { + // overwrite Bootstrap's redundant padding + padding: 0; + } + + .form-control-plaintext, + label.col-form-label { + padding: floor(.375 * @page-font-size) floor(.375 * @page-font-size) floor(.375 * @page-font-size) 0; + } + + .form-control-plaintext { + padding-bottom: 0; + border: 0; + } + + @media screen and (max-width: @screen-width-bs-phone) { + &.form-group { + & > td label { + padding-bottom: 0; + } + } + } + } + + .row.form-check { + padding: 0; // without these e.g. inputs in compose screen are not aligned properly + display: flex; // https://github.com/twbs/bootstrap/issues/22348 + flex-wrap: nowrap; + + // alignment fixes needed because we do not stick precisely to Bootstrap's form structure + @media screen and (max-width: @screen-width-bs-phone) { + .col-6 { + max-width: 100%; + flex: auto; + } + + & > *:last-child { + width: 1%; + min-width: 2.6rem; // for .custom-switch + } + + &.with-link > *:last-child { + min-width: 8rem; + } + } + + .form-check-input { + margin: .5rem 0; // fixes checkbox alignment with other inputs in a form + } + + .custom-switch + a { + line-height: 2; + vertical-align: bottom; + } + + td > label { + padding-bottom: 0; + } + } + + .nav-tabs { + margin-bottom: 1rem; + + &:empty { + display: none; + } + } + + .hint { + font-style: italic; + color: @color-form-hint; + } + + // RAW (CodeMirror) editor + &.raweditor { + height: 100%; + + form { + height: 100%; + } + + textarea { + font-family: monospace; + height: 100%; + } + + .CodeMirror { + border: 1px solid @color-input-border; + border-radius: .3rem; + height: 100%; + color: @color-font; + } + + .CodeMirror-focused { + border-color: @color-input-border-focus; + box-shadow: 0 0 0 .2rem @color-input-border-focus-shadow; + } + + .CodeMirror-linebackground.line-error { + background-color: @color-error; + opacity: 0.4; + } + + .errorGutter { + width: .8em; + } + } +} + +@media screen and (max-width: @screen-width-mini) { + .formcontent { + .col-form-label { + flex: auto; + max-width: 100%; + } + .col-6, .col-8, .col-10 { + flex: auto; + max-width: 100%; + } + } +} + + +/* Some common icons for "iconized inputs" */ +.input-group .icon { + text-decoration: none; + padding: floor(.375 * @page-font-size) .5rem; + + &.input-group-text { + min-width: 2.4rem; + } + + &:before { + &:extend(.font-icon-class); + margin: 0 !important; + line-height: 1; + font-size: 1.1rem; + } + &.user:before { + content: @fa-var-user; + } + &.pass:before { + content: @fa-var-lock; + } + &.host:before { + content: @fa-var-home; + } + &.language:before { + content: @fa-var-globe; + } + &.cancel:before { + content: @fa-var-times; + } + &.delete:before { + content: @fa-var-trash-alt; + } + &.edit:before { + content: @fa-var-pencil-alt; + } + &.add:before { + content: @fa-var-plus; + } + &.add.recipient:before { + content: @fa-var-users; + } + &.search:before { + content: @fa-var-search; + } + &.filter:before { + content: @fa-var-filter; + } + &.key:before { + content: @fa-var-key; + } + + .inner { + display: none; + } +} + +.input-group a { + &:focus { + background-color: @color-input-border-focus-shadow; + outline: 0; + } +} + +@proplist-record-height: 2rem; +.proplist { + margin-bottom: 0; + padding: 0; + + li { + list-style-type: none; + line-height: @proplist-record-height; + margin-bottom: .25rem; + display: flex; + align-items: center; + + &:last-child { + margin-bottom: 0; + } + + input[type=radio] { + margin-right: .5em; + + &:disabled + label { + opacity: .5; + } + } + + label:not(.input-group-text) { + margin: 0; + line-height: @proplist-record-height; + } + + select { + width: auto; + display: inline; + } + + &.with-sublist { + flex-wrap: wrap; + position: relative; + + & > :first-child { + width: 100%; + margin-right: 2em; + } + + & > .proplist { + margin-left: 2.5rem; + } + + & > a.dropdown { + position: absolute; + right: 0; + top: 0; + height: 2em; + color: @color-font; + } + } + } +} + +.checklist { + & > div { + line-height: 2rem; + display: block; // overwrite .custom-switch + } + + .custom-control-label { + &:before, + &:after { + margin: calc(floor(.15 * @page-font-size) * -1) 0 0 0; + } + } + + & > div + br { + display: none; + } +} + +/*** Forms in popups ***/ + +.popup form.propform { + padding: .25rem; + overflow-x: hidden; +} + +.popupmenu.form { + &.nolist { + padding: 0 .5rem; + } + + ul { + list-style-type: none; + padding: 0; + margin: 0; + } + + li:not(.separator) { + padding: 0 1rem; + + label { + margin: 0; + line-height: @listing-line-height; + + input { + margin-right: .5rem; + } + } + } + + input { + vertical-align: middle; + } + + select { + margin: .5rem 0; + } + + .buttons { + text-align: center; + padding: .5rem; + } +} + + +/*** Smart list (multiple input) field ***/ + +.multi-input { + & > .content { + max-height: 11.65em; + overflow: hidden; + overflow-y: auto; + border-radius: .25rem; + border: 1px solid @color-input-border; + + &.focused { + .style-input-focus(); + } + + // TODO: style button focus + } + + a.icon { + &.reset:before { + &:extend(.font-icon-class); + content: @fa-var-trash-alt; + } + } + + input.form-control { + padding-left: .75rem; + height: auto; // fixes input height + } + + input, + input:focus, + .input-group-text { + border-radius: 0; + border: 0; + border-bottom: 1px solid @color-input-border; + box-shadow: none; + } + + .input-group-text { + border-left: 1px solid @color-input-border; + } + + .input-group-append { + margin-left: 0; + } + + .input-group { + margin: 0 !important; + flex-wrap: nowrap; // Bootstrap makes them wrappable (imho) + + &:last-child * { + border-bottom: 0; + } + } + + & + .btn { + margin-top: .5rem; + } + + &.is-invalid { + & > .content { + border: 1px solid @color-input-border-invalid; + &.focused { + border-color: @color-input-border-invalid; + box-shadow: 0 0 0 .2rem @color-input-border-invalid-shadow; + } + } + + & > .invalid-feedback { + display: inline-block; + line-height: 1.5; + } + } +} + + +/*** Files upload widget with list of files, upload form and drop area ***/ + +.file-upload { + padding: 1rem 1rem 12rem; + margin: 0 1rem .25rem 1rem; + border-radius: .5rem; + border: .2rem dashed @color-table-border; + + fieldset & { + margin: 0; + } + + .upload-form { + text-align: center; + padding-bottom: 1em; + + a.btn, + button { + margin-bottom: .25rem; + } + } + + .hint { + margin-bottom: .5rem; + color: @color-form-hint; + text-align: center; + } + + .attachmentslist { + border: 0; + background: transparent; + + li { + position: relative; + display: flex; + padding-right: 1.5em; + margin: 0.15em 0; + + a.filename { + flex: 1; + } + + a.delete, + a.cancelupload { + position: absolute; + right: 0.25em; + width: auto; // fix button width if the widget is in a .popupmenu + } + + a.dropdown { + margin-right: .5em; + } + + .inner { + display: none; + } + } + } + + &.droptarget { + padding-bottom: .5rem !important; + + &:after { + content: @icon-file-drop; + width: 10rem; + margin: 5rem auto 0 auto; + display: block; + } + + &.active { + border-color: darken(@color-toolbar-button-background-hover, 20%); + } + + &.hover { + border-color: darken(@color-toolbar-button-background-hover, 20%); + background-color: @color-toolbar-button-background-hover; + } + } +} + + +/*** Smart recipient input field ***/ + +@recipient-input-margin-fix: round(.25 * @page-font-size); + +.recipient-input { + display: flex; + flex-wrap: wrap; + padding: 0 .75rem @recipient-input-margin-fix .75rem; + list-style-type: none; + cursor: text; + height: auto; // reset .form-control height + + &.focus { + .style-input-focus(); + } + + li { + max-width: 100%; + + &:not(.recipient) { + user-select: text; + } + + &.input { + flex: 1; + min-width: 100px; + } + } + + input { + width: 100%; + background: transparent !important; + border: 0 !important; + margin-top: @recipient-input-margin-fix; + outline: 0; + line-height: 1.5; + + &::-ms-clear { + display: none; // removes clear icon in IE11 + } + } +} + +.recipient-input li.recipient, +body > li.recipient.ui-sortable-helper { + display: flex; + position: relative; + max-width: ~"calc(50% - 3px)"; + border: 1px solid @color-recipient-input-border; + background-color: @color-recipient-input-background; + border-radius: .25rem; + padding: 0 .25rem; + margin-top: @recipient-input-margin-fix; + margin-right: .2em; + white-space: nowrap; + cursor: default; + + @media screen and (max-width: 450px) { + width: 100%; + max-width: 100%; + } + + .name { + .overflow-ellipsis(); + flex-grow: 1; + line-height: 1.1; + padding: floor(.25 * @page-font-size); + vertical-align: middle; + } + + .email { + text-indent: -5000rem; + display: inline-block; + width: 0; + } + + .quotes { + position: absolute; + width: 0; + opacity: 0; + } + + a.button.icon { + font-size: .75em; + cursor: pointer; + padding: 0; + color: @color-font; + + &:before { + display: inline-block; + width: 1em; + line-height: 1.6; + } + } + + &.ui-sortable-helper { + // fix element width while dragging + padding: 0 0 0 .25rem !important; + } +} + +/*** Tagedit widget (from jqueryui plugin) ***/ + +.tagedit-list { + display: flex; + flex-wrap: wrap; + padding: 0 .75rem @recipient-input-margin-fix .75rem; + margin: 0; + list-style-type: none; + min-height: 2.3rem; + + & + .placeholder { + display: none; + } + + &[tabindex="-1"] { + .style-input-focus(); + } + + li.tagedit-listelement-new { + margin-top: @recipient-input-margin-fix; + + input { + width: 15px; + background: transparent !important; + border: 0; + outline: 0; + margin: 0; + padding: 0; + line-height: 1.5; + + &.tagedit-input-disabled { + visibility: hidden; + } + } + } + + li.tagedit-listelement-old { + max-width: 50%; + border: 1px solid @color-recipient-input-border; + background-color: @color-recipient-input-background; + border-radius: .25em; + margin-top: @recipient-input-margin-fix; + margin-right: .2em; + white-space: nowrap; + + a /* TODO: .tagedit-close, .tagedit-break, .tagedit-delete, .tagedit-save */ { + font-size: .8em; + cursor: pointer; + display: inline-block; + width: 1.1em; + overflow: hidden; + vertical-align: middle; + margin-right: .2rem; + color: inherit; + text-decoration: none; + + &:before { + &:extend(.font-icon-class); + content: @fa-var-times; + width: 1em; + line-height: 1.2; + } + } + + span { + .overflow-ellipsis(); + flex-grow: 1; + display: inline-block; + line-height: 1.4; + padding: 0 .25rem; + vertical-align: middle; + } + } + + li.tagedit-listelement-focus { + // TODO + } +} + + +/*** Skin selection widget ***/ + +.skinselection { + white-space: nowrap; + display: table-row; + + & > span { + display: table-cell; + vertical-align: middle; + padding: .1em .5em; + white-space: normal; + + &:last-child { + padding-right: 0; + } + } + + .skinitem input { + width: auto; + } + + .skinname { + font-weight: bold; + } + + .skinlicense, + .skinlicense a { + font-style: italic; + text-decoration: none; + } + + .skinlicense a:hover { + text-decoration: underline; + } + + .skinlicense, + .skinauthor { + font-size: 90%; + } + + .skinthumbnail { + width: 64px; + height: 64px; + border: 1px solid @color-input-border; + background: #fff; + border-radius: 4px; + } +} + +/*** Percent input with jQuery-UI slider ***/ + +// Structure: +.input-percent-slider { + display: flex; + align-items: center; + + input { + max-width: 4em; + } + + span.label { + line-height: 2.4; + padding: 0 .5rem 0 .25rem; + } + + div.ui-slider { + flex: 1; + margin: 0 .5em; + } +} + + +/*** Image upload widget ***/ + +.image-upload { + position: relative; + overflow: hidden; + cursor: pointer; + background-color: @color-image-upload-background; + + a.button { + display: none; + position: absolute; + left: 0; + top: 0; + background-color: rgba(255, 255, 255, .85); + border-radius: 5px; + width: 2.5em; + padding: .5em; + margin: .5em; + line-height: 1; + } + + &.changed a.button { + display: inline; + } +} + +.input-group-combo { + select:first-of-type { + &.alone { + border-radius: .25rem !important; + } + + &:not(.alone) { + flex: unset; + width: auto; + } + } + + .input-group { + padding: 0 !important; + flex: 2; + } + + select + select, + .input-group :first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } +} + + +/*** General browser hacks ***/ + +// Remove outline on selects in Firefox +@-moz-document url-prefix() { + select:-moz-focusring { + color: transparent !important; + text-shadow: 0 0 0 @color-font !important; + } +} + + +/*** Bootstrap style overrides and improvements ***/ + +.form-control { + color: @color-font; + + &:focus { + color: @color-font; + border-color: @color-input-border-focus; + box-shadow: 0 0 0 .2rem @color-input-border-focus-shadow; + } + + // FIXME: This fixes style of required inputs in Firefox/Edge, but + // makes inputs on login form red-bordered, commented for now + // &:invalid, + &.is-invalid { + border-color: @color-input-border-invalid; + box-shadow: none; + + &:focus { + border-color: @color-input-border-invalid; + box-shadow: 0 0 0 .2rem @color-input-border-invalid-shadow; + } + } + + &::placeholder { + color: @color-input-placeholder; + } + + // Note: This must be a separate rule + &::-ms-input-placeholder, + &::-webkit-input-placeholder { + color: @color-input-placeholder; + } +} + +.invalid-feedback { + color: @color-error; + font-size: 90%; +} + +.form-group { + margin-bottom: .5rem; +} + +// This one is to fix height of an input-group child that usually we put +// in between inputs, e.g. in managesieve forms it is '@' in email input +// with a separate local part and domain selector. +.input-group-append.input-group-prepend { + display: inline; +} + +.input-group-text { + color: @color-input; + background-color: @color-input-addon-background; + + input:focus { + z-index: 1; + border-color: @color-input-border-focus !important; + } +} + +.custom-switch { + padding-left: 0; + display: inline-block; + + .custom-control-input { + left: 0; + opacity: 0 !important; // fixes input in dark mode + + &:focus ~ .custom-control-label:before { + box-shadow: 0 0 0 .2rem @color-checkbox-focus-shadow; + } + + &:focus:not(:checked) ~ .custom-control-label::before { + border-color: @color-checkbox-focus; + } + + &:checked ~ .custom-control-label::before { + border-color: @color-checkbox; + background-color: @color-checkbox; + } + + &:checked:disabled ~ .custom-control-label::before { + border-color: @color-checkbox-checked-disabled; + background-color: @color-checkbox-checked-disabled; + } + } + + // Make switches bigger, we use smaller font than Bootstrap's default + + .custom-control-label { + padding-left: 2.5rem; + min-height: 2rem; + line-height: 2; + display: inline-block; + + html.touch & { + padding-left: 3rem; + } + + &:before, + &:after { + border-radius: .6rem; + margin: floor(.15 * @page-font-size) 0; + + html.touch & { + border-radius: .8rem; + margin: 0; + } + } + + &:before { + left: 2px; + top: 4px; + width: floor(1.9 * @page-font-size); + height: floor(1.2 * @page-font-size); + + html.touch & { + top: floor(.2 * @page-font-size); + width: floor(2.5 * @page-font-size); + height: floor(1.6 * @page-font-size); + } + } + + &:after { + left: 4px; + top: 6px; + width: floor(1.2 * @page-font-size) - 4; + height: floor(1.2 * @page-font-size) - 4; + + html.touch & { + top: floor(.2 * @page-font-size) + 2; + height: floor(1.6 * @page-font-size) - 4; + width: floor(1.6 * @page-font-size) - 4; + } + } + } + + .custom-control-input:checked ~ .custom-control-label::after { + transform: translateX(floor(1.2 * @page-font-size) - 6); + + html.touch & { + transform: translateX(floor(1.6 * @page-font-size) - 9); + } + } + + .custom-control-input:not(:disabled) ~ .custom-control-label { + &:after, &:before { + cursor: pointer; + } + } +} + +.custom-file { + display: block; + + .custom-file-label { + white-space: nowrap; + .overflow-ellipsis(); + padding-right: 100px; + } + + & + .hint { + margin-top: floor(.25 * @page-font-size); + } +} + +.custom-file-input:focus ~ .custom-file-label { + border-color: @color-input-border-focus; + box-shadow: 0 0 0 .2rem @color-input-border-focus-shadow; +} diff --git a/styles/widgets/jqueryui.less b/styles/widgets/jqueryui.less new file mode 100644 index 0000000..cd11bbb --- /dev/null +++ b/styles/widgets/jqueryui.less @@ -0,0 +1,440 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/*** jQuery-UI widgets' style overrides ***/ + +.ui-widget-overlay { + background-color: @color-dialog-overlay-background; + opacity: 1 !important; // override jQuery-UI opacity, the color above is semi-transparent + + &.datepicker { + z-index: 119; // above Bootstrap's form controls, below datepicker + } +} + +.ui-widget { + border: 1px solid @color-datepicker-border; + box-shadow: 3px 3px 5px @color-popover-shadow; + border-radius: .3rem; +} + +.ui-menu { + overflow-y: auto; + overflow-x: hidden; + max-height: 400px; + border-radius: .3rem; + z-index: 240; + position: absolute; + + .ui-state-active { + border: 0 !important; + background-color: @color-menu-hover-background !important; + } + + .ui-menu-item { + white-space: nowrap; + cursor: default; + } + + .ui-menu-item-wrapper { + margin: 0 !important; + } +} + +.ui-dialog { + border-radius: 0; + box-shadow: none; + + &.no-titlebar { + .ui-dialog-titlebar { + display: none; + } + } + + .ui-dialog-titlebar { + height: @layout-header-height; + border-bottom: 1px solid @color-dialog-header-border; + + button { + &:before { + margin: 0; + } + } + } + + .ui-dialog-title { + line-height: @layout-header-height; + font-size: 1.25rem; + padding: 0 3rem 0 1rem; + color: @color-dialog-header; + } + + .ui-dialog-titlebar-close { + border: 0; + color: @color-dialog-header; + background: transparent; + right: 0; + top: 0; + position: absolute; + padding: .25rem .5rem; + margin: ((@layout-header-height - 2 * @page-font-size) / 2) .5rem; + + &:before { + &:extend(.font-icon-class); + content: @fa-var-times; + line-height: 1.5rem; + margin: 0 !important; + } + } + + .ui-dialog-content { + & > .popupmenu { + display: block !important; + } + } + + .ui-dialog-buttonpane { + .ui-dialog-buttonset { + display: flex; + justify-content: flex-end; + + a.btn-link, + button { + .overflow-ellipsis(); + min-width: 5rem; + margin: floor(.65 * @page-font-size) floor(.3 * @page-font-size); + + &:last-child { + margin-right: 0; + } + } + + a.btn-link { + padding-right: 0; + padding-left: 0; + text-decoration: none; + color: @color-font; + + &:focus { + background-color: fade(@color-btn-primary-background, 50%); + } + + &.options { + order: -1; + padding: .375rem .25rem; + margin-right: .3rem; + + &:before { + // this icon is for mobile version + &:extend(.font-icon-class); + content: @fa-var-cog; + width: 100%; + height: 1.25em; + } + } + } + } + } + + iframe, + .ui-dialog-content.iframe { + padding: 0; + width: 100% !important; + height: 100%; + border: 0; + overflow: hidden; + } +} + +// Fix scrollbar/resize issue e.g. in qr-code dialog +.ui-dialog, +.ui-dialog-content { + box-sizing: initial; +} + +// Overwriting this icon generally prevents from loading bigger images sprite from jQuery-UI +.ui-widget-content .ui-icon.ui-resizable-se { + background: @icon-resize-corner; +} + +/* FIXME: why do I need !important here? */ + +@media screen and (max-width: @screen-width-xs) { + .ui-dialog { + width: 100% !important; + height: 100% !important; + display: flex; + flex-direction: column; + border: 0; + top: 0 !important; // for Chrome + + .ui-resizable-handle, + .ui-dialog-titlebar-close { + display: none !important; + } + + .ui-dialog-titlebar { + height: @layout-touch-header-height; + text-align: center; + background-color: @color-layout-mobile-header-background; + } + + .ui-dialog-title { + line-height: @layout-touch-header-height; + font-size: @layout-header-font-size; + padding: 0 1rem; + } + + .ui-dialog-content { + flex: 1; + &:not(.iframe) { + padding: 1rem; + } + } + + .ui-dialog-buttonpane { + padding: 0 !important; + text-align: center !important; + border-top: 1px solid @color-dialog-header-border; + height: @layout-header-height !important; + background-color: @color-layout-mobile-footer-background; + + .ui-dialog-buttonset { + justify-content: space-around; + + button { + margin: 0 !important; + padding: .45rem; + border: 0 !important; + height: @layout-header-height; + box-shadow: none; + font-size: 90%; + line-height: 1.5; + + &:before { + display: block !important; + float: none; + width: auto; + height: 1.75rem; + line-height: 1.75; + margin: 0 !important; + } + + &:active { + box-shadow: none; + } + + &.btn-primary, + &.btn-secondary { + color: @color-toolbar-button; + background: transparent; + } + + &.btn-danger { + color: @color-btn-danger-background; + background: transparent; + } + + &.disabled, + &:disabled { + opacity: .5; + } + + &.cancel { + order: 100; // makes Cancel/close button the last one + } + } + + a.btn-link { + color: @color-toolbar-button; + margin: 0; + padding: .45rem; + font-size: 90%; + + &.options:before { + display: block !important; + height: 1.75rem; + line-height: 1.75; + margin: 0; + } + } + } + } + } +} + +/* Slider widget */ + +.ui-slider { + box-shadow: none; + + .ui-slider-range { + border-radius: .3rem; + background: lighten(@color-main, 30%); + } + + .ui-slider-handle { + border-radius: .3rem; + + &.ui-state-active { + background: @color-main; + border-color: @color-main-dark; + } + } +} + +/* Datepicker widget */ + +.ui-datepicker { + // Always display datepicker centered, overwriting widgets position + margin: ~"calc(50vh - 10em) calc(50vw - 10em) !important"; + top: 0 !important; + left: 0 !important; + box-shadow: none; + user-select: none; + + &:not(.ui-datepicker-inline) { + z-index: 120 !important; // fixes datepicker over input-group and dialogs + } + + .ui-datepicker-header, + .ui-datepicker-title { + line-height: 4rem; + height: 4rem; + padding: 0; + } + + .ui-datepicker-header { + border-bottom: 1px solid @color-dialog-header-border; + + a { + height: 4rem; + } + + select { + display: inline-block; + } + } + + .ui-icon { + background-image: none !important; + background-position: none !important; + } + + .ui-datepicker-prev, + .ui-datepicker-next { + cursor: pointer; + width: auto; + color: @color-font; + text-decoration: none; + + &:before { + &:extend(.font-icon-class); + content: "\f053"; + margin: 0 .25em; + height: auto; + width: 1em; + } + } + + .ui-datepicker-prev:before { + content: "\f053"; + } + + .ui-datepicker-next:before { + content: "\f054"; + } + + td a { + padding: 0; + line-height: 1.8em; + border-radius: .3rem; + } + + .ui-state-default, + &.ui-widget-content .ui-state-default { + border: 0; + background: transparent; + color: @color-datepicker-font; + } + + .ui-datepicker-days-cell-over a, + .ui-datepicker-days-cell-over a.ui-state-default, + .ui-state-highlight, + &.ui-widget-content .ui-state-highlight { + background: @color-datepicker-highlight-background; + color: @color-datepicker-highlight; + } + + a.ui-state-active { + background: @color-datepicker-active-background !important; + color: @color-datepicker-active !important; + font-weight: bold; + } + + html.touch { + & { + td a { + font-size: 1.2em; + line-height: 2.2em; + } + } + } +} + +// Fixes datepicker z-index issue on input-group inputs in dialogs +// With non-relative position the input's z-index is ignored +.input-group > .form-control.hasDatepicker { + position: initial; +} + +.minicolors-panel { + border: 1px solid @color-datepicker-border; + box-shadow: 3px 3px 5px @color-popover-shadow; + border-radius: .3rem; + height: 152px; + padding: 1px; +} + +.input-group { + .minicolors-input { + width: 100%; + // needed so minicolors panel is not out of screen + // when the input is on the right side, e.g. Calendar plugin settings + // This is obviously minicolors script issue + min-width: 130px; + border-left: 0; + border-right: 0; + } +} + +@media screen and (max-width: @screen-width-mini) { + .ui-widget-content { + border-radius: 0; + } + + .ui-menu { + border-radius: .3rem; + left: 15px !important; + right: 15px; + width: auto; + } + + .ui-dialog { + .ui-dialog-content:not(.iframe) { + padding: .65rem; + } + } + + .ui-autocomplete { + // TODO: e.g. time input autocompletion on mobile + } +} diff --git a/styles/widgets/lists.less b/styles/widgets/lists.less new file mode 100644 index 0000000..b0e35dd --- /dev/null +++ b/styles/widgets/lists.less @@ -0,0 +1,1084 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/*** List and treelist widgets ***/ + +.listing { + tbody td, + li { + border-bottom: 1px solid @color-list-border; + cursor: default; + font-weight: normal; + line-height: @listing-line-height; + } + + tbody td, + li a { + padding: 0 .5rem; + white-space: nowrap; + vertical-align: middle; + color: @color-list; + } + + tbody td { + .overflow-ellipsis(); + outline: none; + + a { + color: @color-list; + } + } + + li a { + display: block; + text-decoration: none; + cursor: default; + width: 100%; + } + + li.selected, + tr.selected td { + color: @color-list-selected; + background-color: @color-list-selected-background; + } + + td.selection { + padding: 0 0 0 .5em; + width: 2em; + text-align: center; + + & > input { + vertical-align: middle; + } + } + + &:not(.withselection) td.selection { + display: none; + } + + td.name { + .overflow-ellipsis(); + } + + td.action { + padding: 0 .5em; + width: 2em; + text-align: center; + + &:empty { + width: 0; + } + + a { + display: block; + overflow: hidden; + text-decoration: none; + + &:before { + &:extend(.font-icon-class); + margin: 0; + font-size: 1rem; + } + } + + a.pushgroup:before { + content: @fa-var-chevron-right; + } + } + + li.droptarget > a, + tr.droptarget > td { + background-color: @color-list-droptarget-background; + } + + li.disabled, + tr.disabled td { + color: @color-list-deleted; + } + + li > a.virtual, + li.virtual > a { + opacity: .4; + } + + span.secondary { + color: @color-list-secondary; + } +} + +// Focus indicator +html:not(.touch) { + .listing { + li > a, + tbody tr > td:first-child, + &:not(.withselection) tbody tr > td.selection + td { + border-left: 2px solid transparent; + } + + li > a:focus, + &.focus tbody tr.focused > td:first-child, + &.focus:not(.withselection) tbody tr.focused > td.selection + td { + border-left: 2px solid @color-list-focus-indicator; + outline: 0; + } + } +} + +table.listing { + width: 100%; + table-layout: fixed; + // border-spacing/border-collapse here fix problem with our focus indicator + // when the table cells use overflow: hidden. I.e. we use border-spacing:0 + // instead of Bootstrap's border-collapse:collapse. Is this cross-browser? + border-spacing: 0; + border-collapse: unset; +} + +ul.listing { + margin: 0; + padding: 0; + + & > ul { + padding: 0; + } + + li { + .overflow-ellipsis(); + white-space: nowrap; + position: relative; + list-style: none; + + ul { + border-top: 1px solid @color-list-border; + padding-left: 1.5em; + + li:last-child { + border-bottom: none; + } + } + + .custom-switch { + position: absolute; + padding: 0; + top: 0; + right: 0; + height: @listing-line-height; + vertical-align: middle; + + .custom-control-label { + &:before, + &:after { + margin-top: .4rem; + + html.touch & { + margin-top: .75rem; + } + } + } + + html.touch & { + height: @listing-touch-line-height; + } + } + } + + &.simplelist { + li { + padding: 0 .5rem; + } + } +} + +.listing-info { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 80%; + text-align: center; + font-weight: bold; + color: @color-list-secondary; +} + +.listing-hover-menu { + position: absolute; + right: 5px; + top: -1000px; + height: 2.4em; + background-color: white; + border: 1px solid #ddd; + padding: 0.25em; + box-shadow: 0 0 5px lightgrey; + border-radius: 0.25em; + + a.button { + cursor: pointer; + display: inline-block; + width: 1.5em; + line-height: 1; + margin: 0.25em 0.25em; + color: @color-font; + + &:hover { + background: transparent; + } + } + + span.txt { + font-size: 90%; + color: @color-black-shade-text; + display: inline-block; + vertical-align: middle; + margin: -1.25em 0.25em 0; + } +} + +html.touch { + .listing:not(.toolbar) li, + .listing tbody td { + line-height: @listing-touch-line-height; + font-size: 1.2rem; + } + + li input[type=checkbox] { + height: @listing-touch-line-height; + } + + td.selection { + padding: 0; + width: 3em; + } +} + +@media screen and (max-width: @screen-width-large) { + .listing.selection-large-only { + li.selected { + color: @color-list; + background-color: transparent; + } + } +} + + +/* icons */ + +.listing.iconized li { + a:before { + &:extend(.font-icon-class); + height: 2em; // TODO: ? + margin-right: .5rem; + } + &.preferences > a:before { + content: @fa-var-sliders-h; + } + &.folders > a:before { + content: @fa-var-folder; + } + &.responses > a:before { + content: @fa-var-comment; + } + &.identities > a:before { + content: @fa-var-id-card; + } + &.password > a:before { + content: @fa-var-lock; + } + &.addressbook a:before { + .font-icon-regular(@fa-var-address-book); + } + &.contactgroup a:before { + .font-icon-solid(@fa-var-users); + } + &.contactsearch a:before { + content: @fa-var-search; + } + &.filter > a:before { + content: @fa-var-filter; + } + &.vacation > a:before { + .font-icon-regular(@fa-var-clock); + } + &.forward > a:before { + content: @fa-var-share-square; + } + &.enigma.keys > a:before { + content: @fa-var-key; + } + &.info > a:before, + &.userinfo > a:before { + content: @fa-var-info-circle; + } + &.twofactorauth > a:before { + content: @fa-var-sign-in-alt; + } + + a.help:before { + content: @fa-var-life-ring; + } + a.about:before { + .font-icon-regular(@fa-var-question-circle); + } + a.license:before { + content: @fa-var-shield-alt; + } + + // autocomplete popup + & > i:before { + &:extend(.font-icon-class); + content: @fa-var-user; + margin-left: .5rem; + } + &.group > i:before { + content: @fa-var-users; + } +} + +html.ie11 .listing.iconized li a:before { + font-size: 1.25rem; +} + +.listing.iconized tr { + td:before { + &:extend(.font-icon-class); + margin-right: .5rem; + } + &.contact.person td.name:before { + content: @fa-var-user; + } + &.contact.group td.name:before { + content: @fa-var-users; + } + &.general > td.section:before { + content: @fa-var-desktop; + } + &.mailbox > td.section:before { + .font-icon-regular(@fa-var-envelope); + } + &.mailview > td.section:before { + content: @fa-var-inbox; + } + &.compose > td.section:before { + content: @fa-var-paper-plane; + } + &.addressbook > td.section:before { + content: @fa-var-users; + } + &.folders > td.section:before { + .font-icon-regular(@fa-var-folder); + } + &.server > td.section:before { + content: @fa-var-server; + } + &.encryption > td.section:before { + content: @fa-var-lock; + } + &.calendar > td.section:before { + content: @fa-var-calendar; + } + &.chat > td.section:before { + content: @fa-var-comments; + } +} + +/* selectable list: e.g. spellcheck language selection */ +.listing.iconized.selectable li { + a:before { + &:extend(.font-icon-class); + content: ""; + } + a.selected:before { + content: @fa-var-check; + } +} + +.popupmenu .listing { + li > a { + border-left: 0; + + &:not(.disabled):hover { + color: @color-menu-hover; + background-color: @color-menu-hover-background; + } + } + + li.selected { + color: @color-menu-hover; + background-color: @color-menu-hover-background; + } + + td { + .overflow-ellipsis(); + } +} + +ul.treelist { + li { + div.treetoggle { + position: absolute; + top: 0; + left: 0; + width: @listing-treetoggle-width; + cursor: pointer; + background-color: transparent; + + &:before { + &:extend(.font-icon-class); + content: @fa-var-angle-right; + margin-left: .25em; + font-size: 1em; + } + + &.expanded:before { + content: @fa-var-angle-down; + } + } + + & > a { + .overflow-ellipsis(); + padding-left: @listing-treetoggle-width; + } + + &.selected { + // reset .listing selection style + color: inherit; + background-color: transparent; + + & > div > a, // this is used e.g. by kolab_addressbook + & > a { + color: @color-list-selected; + background-color: @color-list-selected-background; + } + } + + ul { + padding: 0; + + li { + padding-left: 0; + a { padding-left: (2 * @listing-treetoggle-width); } + div.treetoggle { left: @listing-treetoggle-width; } + + li { + a { padding-left: (3 * @listing-treetoggle-width); } + div.treetoggle { left: (2 * @listing-treetoggle-width); } + + li { + a { padding-left: (4 * @listing-treetoggle-width); } + div.treetoggle { left: (3 * @listing-treetoggle-width); } + + li { + a { padding-left: (5 * @listing-treetoggle-width); } + div.treetoggle { left: (4 * @listing-treetoggle-width); } + + li { + a { padding-left: (6 * @listing-treetoggle-width); } + div.treetoggle { left: (5 * @listing-treetoggle-width); } + } + } + } + } + } + } + } + + &.notree { + div.treetoggle { + display: none; + } + + li > a { + padding-left: .5em; + } + } +} + +/*** Folders list widget ***/ + +.folderlist { + li { + &.mailbox { + &.unread { + & > a { + padding-right: 2.8em; + font-weight: bold; + } + } + + .unreadcount { + position: absolute; + top: 0; + right: 0; + min-width: 2em; + line-height: 1.4rem; + margin: ((@listing-line-height - 1.4 * @page-font-size) / 2); + padding: 0 .3em; + border-radius: .4em; + background: @color-list-badge-background; + color: @color-list-badge; + text-align: center; + font-weight: bold; + + html.touch & { + line-height: 2rem; + margin: ((@listing-touch-line-height - 2 * @page-font-size) / 2); + } + } + + &.recent { + & > a { + color: @color-list-recent; + + & > .unreadcount { + background: @color-list-recent-badge-background; + color: @color-list-recent-badge; + } + } + } + + &.root { + display: none !important; + // FIXME: This element is confusing, I propose to not use it + } + } + + a:before { + &:extend(.font-icon-class); + .font-icon-regular(@fa-var-folder); + margin-right: .5rem; + } + + &.inbox > a:before { + .font-icon-solid(@fa-var-inbox); + } + &.trash a:before { + .font-icon-solid(@fa-var-trash-alt); + } + &.trash.empty > a:before { + .font-icon-regular(@fa-var-trash-alt); + } + &.drafts a:before { + .font-icon-solid(@fa-var-pencil-alt); + } + &.sent a:before { + .font-icon-solid(@fa-var-paper-plane); + } + &.junk a:before { + .font-icon-solid(@fa-var-fire-alt); + } + &.archive > a:before { + .font-icon-solid(@fa-var-archive); + } + &.ns-shared > a:before { + .font-icon-solid(@fa-var-share-alt); + } + &.ns-other > a:before { + .font-icon-solid(@fa-var-user-friends); + } + } + + // folder-selector fix for left padding + &.menu a:before { + margin-left: .5em; + } +} + + +/*** Messages list widget ***/ + +.messagelist > thead, +.messagelist .branch, +table.fixedcopy { + display: none; +} + +.messagelist { + td { + border-left: 0; + width: 2em; + vertical-align: top; + font-size: 1rem !important; + } + + td.subject { + width: 100%; + padding-right: 0; + display: flex; + flex-wrap: wrap; + + a { + text-decoration: none; + cursor: default; + } + + span { + line-height: 2em; + + &.size, + &.date { + font-size: 90%; + color: @color-list-secondary; + } + + &.fromto { + .overflow-ellipsis(); + flex: 1; + font-size: 90%; + color: @color-list-secondary; + padding-left: 1.5em; + padding-right: .5rem; + } + + &.subject { + .overflow-ellipsis(); + width: 100%; + user-select: none + } + } + } + + td.threads { + padding: 0 0 0 .25rem; + width: 1.5em; + } + + td.flags { + width: 2.5em; + + & > span { + height: 1.7em; + line-height: 1.7em; + display: block; + + &.flag { + cursor: pointer; + } + } + } + + tr.flagged td, + tr.flagged span.size, + tr.flagged td.subject span.subject a, + tr.flagged td.subject span.date, + tr.flagged td.subject span.fromto { + color: @color-list-flagged; + } + + tr.deleted td, + tr.deleted td.subject span.subject a, + tr.deleted td.subject span.date, + tr.deleted td.subject span.fromto { + color: @color-list-deleted; + } + + tr.unread td.subject span.subject { + font-weight: bold; + } + + // thread parent message with unread children + tr.unroot td.subject a { + text-decoration: underline; + } + + tr.thread td.threads div:before { + &:extend(.font-icon-class); + content: @fa-var-angle-right; + cursor: pointer; + width: 1em; + } + + tr.thread.expanded td.threads div:before { + content: @fa-var-angle-down; + } + + td.subject span.msgicon.status { + &:before { + &:extend(.font-icon-class); + content: @fa-var-circle; + cursor: pointer; + font-size: .4rem; + width: 1.1rem; + height: 2rem; + } + + &.unread:before { + content: @fa-var-circle; + font-size: .5rem; + } + + &.unreadchildren:before { + .font-icon-regular(@fa-var-circle); + font-size: .5rem; + } + + &.replied:before { + .font-icon-solid(@fa-var-reply); + font-size: 1rem; + } + + &.forwarded:before { + .font-icon-solid(@fa-var-share); + font-size: 1rem; + } + + &.replied.forwarded:before { + .font-icon-solid(@fa-var-reply); + font-size: 1rem; + } + + &.replied.forwarded:after { + &:extend(.font-icon-class); + .font-icon-solid(@fa-var-share); + font-size: 1rem; + opacity: .5; + margin: 0 -0.1em 0 -1.25em; + } + } + + span.attachment span { + &:extend(.font-icon-class); + color: @color-list-icon; + + &:before { + margin: 0; + content: @fa-var-paperclip; + } + &.report:before { + .font-icon-regular(@fa-var-file-alt); + } + &.encrypted:before { + content: @fa-var-lock; + } + &.vcard:before { + .font-icon-regular(@fa-var-user); // vcard_attachments plugin + } + } + + span.flagged:before { + &:extend(.font-icon-class); + content: @fa-var-flag; + } + + tr.flaggedroot:not(:hover) span.unflagged:before { + &:extend(.font-icon-class); + content: @fa-var-flag; + color: @color-list-icon; + } + + span.size { + display: none; + } + + &.sort-size { + span.date { + display: none; + } + span.size { + display: inline; + } + } +} + +// On touch devices hide flag icon, but do it in a way +// that saves as much room as possible, keeping the attachment icon +html.layout-phone, +html.touch { + .messagelist { + tr { + position: relative; + display: flex; // Safari fix (#8433) + } + + td.selection, + td.threads { + line-height: 3.8em; // because of display:flex above + } + + td.flags { + position: absolute; + top: .25rem; + right: 0; + bottom: 0; + background-color: transparent; + + .flag { + visibility: hidden; + } + } + + td.subject { + padding-right: .5em; + + .subject { + padding-right: 1.5rem; + } + } + } +} + + +/* Contacts list */ + +.contactlist { + .contact.readonly td { + font-style: italic; + } + + td.action { + // TODO + a { + // TODO + } + } + + // for contacts list in mail compose + td.contact:before { + &:extend(.font-icon-class); + content: @fa-var-user; + } + + // for contacts list in mail compose + td.contactgroup:before { + &:extend(.font-icon-class); + content: @fa-var-users; + } + + span.email { + display: inline; + color: @color-list-secondary; + font-style: italic; + margin-left: .5em; + } + + li { + a:before { + &:extend(.font-icon-class); + margin-right: .5rem; + } + + a.addressbook::before { + .font-icon-regular(@fa-var-address-book); + } + + a.contactgroup::before { + .font-icon-solid(@fa-var-users); + } + } +} + + +/* Attachments list */ + +@attachmentslist-item-height: 2rem; + +.attachmentslist { + padding: 0; + margin: 0; + + background-color: @color-attachmentlist-background; + border: 1px solid @color-attachmentlist-border; + + &:empty { + padding: 0; + border: 0; + } + + li { + list-style: none; + display: inline-flex; + white-space: nowrap; + line-height: @attachmentslist-item-height; + padding: 0 .25em; + max-width: 100%; + + &:before { + &:extend(.font-icon-class); + .font-icon-regular(@fa-var-file); + height: @attachmentslist-item-height; + margin: 0; + } + + &.txt:before, + &.text:before { + .font-icon-regular(@fa-var-file-alt); + } + + &.pdf:before { + .font-icon-regular(@fa-var-file-pdf); + } + + &.odt:before, + &.doc:before, + &.docx:before, + &.msword:before { + .font-icon-regular(@fa-var-file-word); + } + + &.ods:before, + &.xls:before, + &.xlsx:before, + &.msexcel:before { + .font-icon-regular(@fa-var-file-excel); + } + + &.rar:before, + &.zip:before, + &.gz:before { + .font-icon-regular(@fa-var-file-archive); + } + + &.image:before, + &.jpg:before, + &.jpeg:before, + &.png:before { + .font-icon-regular(@fa-var-file-image); + } + + &.mp3:before, + &.audio:before { + .font-icon-regular(@fa-var-file-audio); + } + + &.m4p:before, + &.video:before { + .font-icon-regular(@fa-var-file-video); + } + + &.ics:before, + &.calendar:before { + // TODO + } + + &.vcard:before { + .font-icon-regular(@fa-var-address-card); + } + + &.html:before { + .font-icon-regular(@fa-var-file-code); + } + + &.eml:before, + &.rfc822:before { + // TODO + } + + &.odp:before, + &.otp:before, + &.ppt:before, + &.pptx:before, + &.ppsx:before, + &.vnd.mspowerpoint:before { + .font-icon-regular(@fa-var-file-powerpoint); + } + + &.sig:before, + &.pgp-signature:before, + &.pkcs7-signature:before { + // TODO + } + + &.application.asc:before { + // TODO + } + + &.application.pgp-keys:before { + // TODO + } + + a { + text-decoration: none; + line-height: @attachmentslist-item-height; + height: @attachmentslist-item-height; + } + + a.cancelupload:before, + a.delete:before { + &:extend(.font-icon-class); + content: @fa-var-trash-alt; + line-height: @attachmentslist-item-height; + height: @attachmentslist-item-height; + margin: 0; + } + + a.dropdown:before { + margin: 0; + } + + &.uploading:before { + .animated-icon-class(); + .font-icon-solid(@fa-var-circle-notch); + } + + a.filename { + display: flex; + overflow: hidden; + padding: 0 .2em; + } + + .attachment-name { + .overflow-ellipsis(); + color: @color-font; + } + + .attachment-size { + color: @color-list-secondary; + padding-left: .25em; + } + } +} + +.keylist { + padding: 0; + list-style: none; + + li { + line-height: 2; + + &:before { + &:extend(.font-icon-class); + content: @fa-var-key; + line-height: 1.5; + } + } +} + +#identities-table { + td.mail:before { + &:extend(.font-icon-class); + content: @fa-var-id-card; + } +} + +#responses-table { + td.name:before { + &:extend(.font-icon-class); + content: @fa-var-comment; + } +} + +#filterslist { + td.name:before { + &:extend(.font-icon-class); + content: @fa-var-filter; + } +} + +#filtersetslist { + td.name:before { + &:extend(.font-icon-class); + content: @fa-var-file-alt; + } +} + +#subscription-table { + li.mailbox a { + padding-right: 2.5rem; + } +} diff --git a/styles/widgets/menu.less b/styles/widgets/menu.less new file mode 100644 index 0000000..d15ccff --- /dev/null +++ b/styles/widgets/menu.less @@ -0,0 +1,952 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/*** Toolbar widget ***/ + +.menu { + margin: 0; + text-align: center; + white-space: nowrap; + + a { + .overflow-ellipsis(); + text-decoration: none; + + &:before { + &:extend(.font-icon-class); + content: "\00a0"; // blank placeholder + } + + &:hover, + &:focus { + outline: 0; + } + + &:not(.disabled):focus, + &:not(.disabled):hover { + background-color: @color-toolbar-button-background-hover; + } + } + + &.toolbar { + li { + display: inline-block; + height: @layout-touch-header-height; + } + + a { + color: @color-toolbar-button; + display: block; + float: left; + border: 0 !important; + height: @layout-header-height; + min-width: 3.2rem; + max-width: 6rem; + width: auto; // reset width defined for links in .listing + padding: .45rem; + line-height: 1.5; + cursor: pointer; + font-size: 1rem; + text-align: center; + + &:before { + height: 1.75rem !important; + float: none !important; + width: auto !important; + margin: 0 !important; + } + + &.selected { + color: @color-success; + } + } + + & > .spacer { + width: 1em; + } + + .dropbutton { + &:not(.disabled):hover { + background-color: @color-toolbar-button-background-hover; + } + + a.dropdown { + padding: 0 .3rem; + + &:before { + line-height: @layout-header-height; + } + + &:hover { + background-color: darken(@color-toolbar-button-background-hover, 5%); + } + } + } + } + + span.inner { + font-size: 90%; + font-weight: normal; + } + + .dropbutton { + display: inline-block; + + a.dropdown { + font-size: 75%; + min-width: 0; + + html.ie11 &:before { + font-size: 80%; + } + + span.inner { + display: none; + } + } + + a:first-child { + padding-right: 0; + } + } + + &.pagenav { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 !important; + font-size: 100%; // in case this is .footer.small + + a { + flex-grow: 1; + display: inline-block; + min-width: 2rem !important; + height: @layout-footer-small-height; + color: @color-toolbar-button; + + &:before { + margin: 0; + display: inline; + float: none; + line-height: @layout-footer-small-height; + } + } + + .pagenav-text { + .overflow-ellipsis(); + color: @color-list-pagenav; + flex-grow: 4; + font-size: 80%; + } + + input { + width: 3rem; + max-width: 5rem; + font-size: 90%; + text-align: center; + max-height: 1.6rem; + margin: 0 .2rem; + + html.layout-phone & { + display: none; + } + } + + span.inner { + display: none; + } + + &.pagenav-list { + cursor: pointer; + background-color: @color-searchbar-background; + border-bottom: 1px solid @color-list-border; + + a { + flex-grow: unset; + } + + .pagenav-text { + text-align: left; + font-size: 100%; + } + + & + .navlist { + background-color: #fbfbfb; + } + + &.expanded + .navlist { + border-bottom: 1px solid @color-layout-border; + } + } + } + + &.content-frame-navigation.hide-nav-buttons { + a.next, + a.prev { + display: none; + } + } + + .listselectors { + max-width: 100%; + display: flex; + justify-content: space-around; + } + + .buttons { + display: block; + + button { + display: block; + float: left; + cursor: pointer; + color: @color-toolbar-button; + background-color: transparent; + border: 0; + padding: 0; + height: @layout-touch-header-height; + line-height: @layout-touch-header-height; + width: 2.5em; + + &:before { + font-size: 1.75rem; + } + } + } + + .popover & { + li { + display: block; + height: auto; + text-align: left; + + &.spacer { + display: none; + } + + &:last-child { + border: 0; + } + + &.separator { + line-height: 1.5rem !important; + font-size: .75rem !important; + padding: 0 .5rem; + color: @color-popover-separator; + background-color: @color-popover-separator-background; + + label { + margin: 0; // Unsets Bootstrap label margin, bug? + } + } + + a { + height: unset; + max-width: 100%; + width: 100%; + line-height: @listing-line-height; + display: block; + padding: 0 .5rem; + text-align: left; + + &:before { + line-height: inherit; + height: inherit !important; + margin-right: .5rem !important; + float: left !important; + width: 1.18em !important; + min-width: 1.18em; + } + + &:not(.disabled):hover { + color: @color-menu-hover; + background-color: @color-menu-hover-background; + } + + &[aria-haspopup] { + display: flex; + + &:after { + &:extend(.font-icon-class); + color: @color-black-shade-text; + font-size: .9em; + margin: 0 0 0 .2em; + min-width: 1.18em; + content: @fa-var-chevron-right; + + html.layout-small & { + margin: 0 .2em; + } + } + + &.dropdown:after { + color: @color-list; + margin: 0 .6em !important; + } + + &:hover:after { + color: @color-menu-hover; + } + + & > span { + .overflow-ellipsis(); + flex: 1; + } + } + } + + span.inner { + font-size: 100%; + } + } + + .dropbutton { + display: flex; + + a:first-child { + .overflow-ellipsis(); + flex: 1; + } + + &:not(.disabled):hover { + background-color: @color-popover-mobile-dropbutton-background; + } + + a.dropdown { + width: 3.5rem; + padding: 0 .5em; + background-color: @color-popover-mobile-dropbutton-background; + + &:hover { + background-color: @color-menu-hover-background; + } + + // Note: :before icon is replaced with :after icon by a[aria-haspopup] above + + &:before, + span.inner { + display: none; + } + } + } + + &.no-icon a:before { + display: none; + } + } +} + +@media screen and (min-width: (@screen-width-small + 1px)) { + .content-frame-navigation { + display: none !important; + } + + .header a.button.icon { + &:not(.disabled):focus, + &:not(.disabled):hover { + background-color: @color-toolbar-button-background-hover; + outline: 0; + } + + &:before { + margin: 0; + } + } +} + +@media screen and (max-width: @screen-width-small) { + .menu.footer { + justify-content: space-around !important; + + & > * { + flex-grow: 1; + } + + .buttons { + display: flex; + justify-content: space-evenly; + } + + .listselectors > * { + flex-grow: 1; + } + } + + .menu.listing a { + color: @color-font; + } +} + +a.toolbar-button { + cursor: pointer; + + @media screen and (min-width: (@screen-width-large + 1px)) { + line-height: 1.5; + padding: .45rem; + + &:before { + float: none !important; + height: 1.75rem !important; + line-height: 1.5; + width: auto !important; + } + + span.inner { + display: inline !important; + font-weight: normal; + font-size: 90%; + } + } +} + +/*** Menu button icons ***/ + +.menu a { + &.mail:before { + content: @fa-var-envelope; + } + &.contacts:before { + content: @fa-var-users; + } + &.options:before { + content: @fa-var-sliders-h; + } + &.settings:before { + content: @fa-var-cog; + } + &.theme.light:before { + content: @fa-var-sun; + } + &.theme.dark:before { + content: @fa-var-moon; + } + &.help:before { + content: @fa-var-life-ring; + } + &.logout:before { + content: @fa-var-power-off; + } + &.about:before { + content: @fa-var-question; + } + &.refresh:before { + content: @fa-var-sync; + } + &.compose:before { + content: @fa-var-edit; + } + &.calendar:before { + content: @fa-var-calendar-alt; + } + &.tasklist:before { + content: @fa-var-tasks; + } + &.files:before { + content: @fa-var-folder; + } + &.notes:before { + content: @fa-var-sticky-note; + } + &.chat:before { + content: @fa-var-comments; + } + &.actions:before { + content: @fa-var-cog; + } + &.addressbook:before { + content: @fa-var-user; + } + &.archive:before { + content: @fa-var-archive; + } + &.assigngroup:before { + content: @fa-var-user-plus; + } + &.attach:before, + &.vcard:before { + content: @fa-var-paperclip; + } + &.next:before { + content: @fa-var-arrow-right; + } + &.prev:before, + &.back:before { + content: @fa-var-arrow-left; + } + &.check:before { + content: "\00a0"; // just a space + } + &.check.selected:before { + content: @fa-var-check; + } + &.closewin:before { + content: @fa-var-window-close; + } + &.collapse:before { + content: @fa-var-angle-down; + } + &.copy:before { + content: @fa-var-copy; + } + &.create:before { + content: @fa-var-plus-square; + } + &.delete:before { + content: @fa-var-trash-alt; + } + &.download:before, + &.download.eml:before, + &.download.maildir:before, + &.download.mbox:before { + content: @fa-var-download; + } + &.dropdown:before { + content: @fa-var-caret-down; + } + &.edit:before { + content: @fa-var-pencil-alt; + } + &.encrypt:before, + &.enigma:before { + content: @fa-var-lock; + } + &.encrypt.sign:before { + content: @fa-var-lock; // TODO + } + &.expand:before { + content: @fa-var-angle-right; + } + &.expand.all:before { + content: @fa-var-angle-double-down; + } + &.expand.none:before { + content: @fa-var-angle-double-up; + } + &.export:before, + &.export.all:before, + &.export.selection:before { + content: @fa-var-download; + } + &.expunge:before { + content: @fa-var-compress-arrows-alt; + } + &.extwin:before { + content: @fa-var-external-link-square-alt; + } + &.filterlink:before { + content: @fa-var-filter; + } + &.firstpage:before { + content: @fa-var-angle-double-left; + } + &.nextpage:before { + content: @fa-var-angle-right; + } + &.prevpage:before { + content: @fa-var-angle-left; + } + &.lastpage:before { + content: @fa-var-angle-double-right; + } + &.flag:before, + &.select.flagged:before { + .font-icon-solid(@fa-var-flag); + } + &.unflag:before { + .font-icon-regular(@fa-var-flag); + } + &.undo:before { + content: @fa-var-redo; + } + &.folders:before { + content: @fa-var-folder; + } + &.forward:before, + &.forward.attachment:before, + &.forward.bounce:before, + &.forward.inline:before { + content: @fa-var-share; + } + &.import:before, + &.upload:before { + content: @fa-var-upload; + } + &.insertresponse:before { + content: @fa-var-comment; + } + &.junk:before { + content: @fa-var-fire-alt; + } + &.notjunk:before { + content: @fa-var-inbox; + } + &.markmessage:before { + content: @fa-var-tag; + } + &.more:before { + content: @fa-var-ellipsis-h; + } + &.move:before { + content: @fa-var-folder-open; + } + &.print:before { + content: @fa-var-print; + } + &.properties:before { + content: @fa-var-file; + } + &.purge:before { + content: @fa-var-eraser; + } + &.qrcode:before { + content: @fa-var-qrcode; + } + &.read:before { + .font-icon-regular(@fa-var-envelope-open); + } + &.unread:before, + &.expand.unread:before, + &.select.unread:before { + .font-icon-solid(@fa-var-envelope); + } + &.recipient:before { + .font-icon-regular(@fa-var-envelope); + } + &.refresh:before { + content: @fa-var-sync; + } + &.remove:before { + content: @fa-var-eraser; + } + &.removegroup:before { + content: @fa-var-user-times; + } + &.rename:before { + content: @fa-var-pencil-alt; + } + &.reply:before { + content: @fa-var-reply; + } + &.reply-all:before, + &.reply.all:before, + &.reply.list:before { + content: @fa-var-reply-all; + } + &.responses:before { + content: @fa-var-comment; + } + &.rotate:before { + content: @fa-var-redo-alt; + } + &.save:before { + .font-icon-regular(@fa-var-save); + } + &.search:before { + content: @fa-var-search; + } + &.search.delete:before { + content: @fa-var-trash-alt; + } + &.select:before { + content: @fa-var-mouse-pointer; + } + &.select.all:before { + content: @fa-var-asterisk; + } + &.select.invert:before { + content: @fa-var-check-square; + } + &.select.none:before { + .font-icon-solid(@fa-var-times); + } + &.select.page:before { + .font-icon-solid(@fa-var-bars); + } + &.selection:before { + .font-icon-regular(@fa-var-check-square) !important; + } + &.send:before { + content: @fa-var-paper-plane; + } + &.showurl:before { + content: @fa-var-link; + } + &.signature:before { + content: @fa-var-signature; + } + &.source:before { + content: @fa-var-file-code; + } + &.spellcheck:before { + content: @fa-var-spell-check; + } + &.status:before { + .font-icon-regular(@fa-var-lightbulb); + } + &.submit:before { + content: @fa-var-check; + } + &.info:before { + content: @fa-var-info-circle; + } + &.threads:before { + content: @fa-var-comments; + } + &.zoomin:before { + content: @fa-var-search-plus; + } + &.zoomout:before { + content: @fa-var-search-minus; + } +} + + +/*** Searchbar and searchoptions widgets ***/ + +.searchbar { + height: @layout-searchbar-height; + min-height: @layout-searchbar-height; // because of Flexbox + line-height: @layout-searchbar-height; + background-color: @color-searchbar-background; + border-bottom: 1px solid @color-list-border; + display: flex; + align-items: center; + overflow: hidden; + position: relative; + + form { + flex: 1; + display: flex; + + &:before { + &:extend(.font-icon-class); + content: @fa-var-search; + height: @layout-searchbar-height; + color: @color-list-pagenav; + margin: 0 0 0 .75rem; + } + } + + input { + width: 100%; + border: 0; + background: transparent; + padding: .5rem; + line-height: normal; // fixes placeholder misalignment in IE11 + outline: 0; // removes focus outline in Chrome + + &::-ms-clear { + display: none; // for IE + } + } + + a { + color: @color-toolbar-button; + + &:before { + &:extend(.font-icon-class); + width: 2rem; + height: @layout-searchbar-height; + margin: 0; + } + + &.options:before { + content: @fa-var-angle-down; + } + + &.reset:before { + content: @fa-var-times; + font-size: 1rem; + } + + &.unread:before { + .font-icon-solid(@fa-var-envelope); + } + + &.reset, + &.search { + display: none; + } + + &.selected { + color: @color-success; + } + } + + span.inner { + display: none; + } + + &.active { + a.reset { + display: inline; + } + } + + &.open a.options:before { + content: @fa-var-angle-up; + } +} + +.searchoptions { + button.search { + width: 100%; + } + + ul.proplist { + & + div { + margin-top: 1rem; + } + } + + .input-group { + &:not(:last-child) { + margin-bottom: .5rem; + } + + .input-group-prepend { + width: 30%; + } + + label { + width: 100%; + } + } + + .formbuttons { + // this is needed because we hide .formbuttons on small devices + // we don't want it for search options form + display: block !important; + } +} + + +/*** Taskmenu ***/ + +#taskmenu { + a { + display: block; + float: none; + } + + @media screen and (max-width: @screen-width-xs) { + z-index: 30001; // because autocompletion popup uses z-index:30000 + overflow-x: hidden; + + a { + max-width: unset; + padding: 0 .5em; + margin-top: 1px; + text-align: left; + line-height: @layout-touch-menu-record-height; + height: @layout-touch-menu-record-height; + border-bottom: 1px solid @color-list-border !important; + color: @color-list; + font-size: 1.2rem; + + &:before { + float: left !important; + width: 1.2em !important; + margin-right: .5rem !important; + } + } + + span.inner { + font-size: 100%; + } + } + + @media screen and (min-width: (@screen-width-xs + 1px)) { + a { + color: @color-taskmenu-button; + padding: .45rem 0; + min-width: unset; + + &.selected { + color: @color-taskmenu-button-selected; + background: @color-taskmenu-button-selected-background; + + &:hover { + color: @color-taskmenu-button-selected-hover; + background: @color-taskmenu-button-background-hover; + } + } + + &:hover { + color: @color-taskmenu-button-hover; + background: @color-taskmenu-button-background-hover; + } + } + + .special-buttons { + position: absolute; + bottom: 0; + left: 0; + background-color: @color-taskmenu-background; + } + + .action-buttons { + a { + color: @color-taskmenu-button-action; + background: @color-taskmenu-button-action-background; + + &:hover { + color: @color-taskmenu-button-action-hover; + background: @color-taskmenu-button-action-background-hover; + } + } + } + + a.logout { + color: @color-taskmenu-button-logout !important; + + &:hover { + color: @color-taskmenu-button-logout-hover !important; + } + } + } + + @media screen and (min-width: (@screen-width-xs + 1px)) and (max-width: @screen-width-medium) { + a { + width: @layout-menu-width-sm; + height: @layout-menu-width-sm; + font-size: 1.2rem; + padding: 0; + + &:before { + line-height: @layout-menu-width-sm; + } + } + + span.inner { + display: none; + } + } + + @media screen and (min-width: (@screen-width-medium + 1px)) { + a { + width: @layout-menu-width; + font-size: 1rem; + + &:before { + float: none; // fixed overflowing text in Edge + } + + &:focus { + background-color: @color-taskmenu-button-selected-background; + } + } + + span.inner { + padding: 0 .1em; + } + } +} diff --git a/styles/widgets/messages.less b/styles/widgets/messages.less new file mode 100644 index 0000000..f81ac54 --- /dev/null +++ b/styles/widgets/messages.less @@ -0,0 +1,267 @@ +/** + * Roundcube Webmail styles for the Elastic skin + * + * Copyright (c) The Roundcube Dev Team + * + * The contents are subject to the Creative Commons Attribution-ShareAlike + * License. It is allowed to copy, distribute, transmit and to adapt the work + * by keeping credits to the original authors in the README.md file. + * See http://creativecommons.org/licenses/by-sa/3.0/ for details. + */ + +/*** UI Messages ***/ + +// .boxwarning/.boxerror/.boxinformation classes are converted to .ui.alert in bootstrap_init() + +.ui.alert { + margin: 0; + margin-bottom: .2rem; + opacity: .95; + width: 100%; + padding: .75em; + color: @color-message; + border: 1px solid @color-message-border; + background-color: @color-message-background; + display: flex; + align-items: center; + + @media screen and (max-width: @screen-width-xs) { + border: 0; + } + + span { + margin: auto 0; + } + + & > i.icon { + line-height: 1; + color: lighten(@color-black, 25%); + margin: auto 0; + } + + & > i.icon:before { + &:extend(.font-icon-class); + content: @fa-var-info-circle; + margin-right: .6rem; + } + + .btn { + margin-left: .5rem; + } + + &.loading { + color: @color-message-loading; + + & > i.icon:before { + content: @fa-var-circle-notch; + .animated-icon-class(); + width: 1em; + } + } + + &.alert-success > i.icon:before { + content: @fa-var-check-circle; + color: @color-message-success; + } + + &.alert-warning > i.icon:before { + content: @fa-var-exclamation-triangle; + color: @color-message-warning; + } + + &.alert-danger > i.icon:before { + content: @fa-var-exclamation-circle; + color: @color-message-error; + } + + &.vcardattachment > i.icon:before { + content: @fa-var-address-card; // vcard_attachments plugin + } + + &.enigmaattachment > i.icon:before { + content: @fa-var-key; // enigma plugin + } + + &.signed > i.icon:before, + &.encrypted > i.icon:before { + content: @fa-var-lock; // enigma plugin + } + + &.chat > i.icon:before { + content: @fa-var-comment; + } + + // #6797: Fix for long buttons issue + .boxbuttons { + white-space: nowrap; + + .btn { + .overflow-ellipsis(); + max-width: 220px; + } + + @media screen and (max-width: @screen-width-xs) { + display: flex; + flex-direction: column; + + .btn { + max-width: 160px; + + &:not(:first-child) { + margin-top: .25rem; + } + } + } + } + + // This works with following structure: [button]. + // here is a one-line text, and button can be anything but . + &.aligned-buttons { + display: flex; + + span { + flex: 1; + } + } + + a:not(.btn) { + color: @color-message-link; + font-weight: @color-message-link-font-weight; + } + + h3 { + font-weight: bold; + font-size: 1.2rem; + } + + p { + margin: 1rem 0; + } + + &.boxerror, + &.boxconfirmation, + &.boxinformation, + &.boxwarning { + padding: .5em; + border-radius: 0; + + i.icon { + font-size: 1.5em !important; + } + } + + &.boxerror { + background-color: @color-message-error-box-background; + & when not(@color-message-error-box = @color-message) { color: @color-message-error-box; } + } + + &.boxinformation { + background-color: @color-message-information-box-background; + & when not(@color-message-information-box = @color-message) { color: @color-message-information-box; } + } + + &.boxconfirmation { + background-color: @color-message-success-box-background; + & when not(@color-message-error-box = @color-message) { color: @color-message-error-box; } + } + + &.boxwarning { + background-color: @color-message-warning-box-background; + & when not(@color-message-warning-box = @color-message) { color: @color-message-warning-box; } + } + + & + table { + margin-top: 1em; + } +} + +#messagestack { + position: absolute; + bottom: .5em; + right: .7em; + z-index: 105; // needs to be above .ui-widget-overlay + width: 320px; + height: auto; + max-height: 85%; + + @media screen and (max-width: @screen-width-xs) { + left: 0; + right: 0; + bottom: 0; + width: auto; + } + + div { + background-color: @color-message; + color: @color-message-text; + + @media screen and (max-width: @screen-width-xs) { + margin: 0; + border-radius: 0; + min-height: 4.2rem; + } + + &.voice { + position: absolute; + top: -1000px; + } + + i.icon { + font-size: 1.5em !important; + } + + & > i.icon:before { + color: @color-message-text; + } + + &:last-child { + margin-bottom: 0; + } + } + + .loading { + background-color: @color-message-loading; + & when not(@color-message-loading-text = @color-message-text) { color: @color-message-loading-text; } + & > i.icon:before { + & when not(@color-message-loading-text = @color-message-text) { color: @color-message-loading-text; } + } + } + + .alert-info.information { + background-color: @color-message-information; + & when not(@color-message-information-text = @color-message-text) { color: @color-message-information-text; } + & > i.icon:before { + & when not(@color-message-information-text = @color-message-text) { color: @color-message-information-text; } + } + } + + .alert-success { + background-color: @color-message-success; + & when not(@color-message-success-text = @color-message-text) { color: @color-message-success-text; } + & > i.icon:before { + & when not(@color-message-success-text = @color-message-text) { color: @color-message-success-text; } + } + } + + .alert-warning { + background-color: @color-message-warning; + & when not(@color-message-warning-text = @color-message-text) { color: @color-message-warning-text; } + & > i.icon:before { + & when not(@color-message-warning-text = @color-message-text) { color: @color-message-warning-text; } + } + } + + .alert-danger { + background-color: @color-message-error; + & when not(@color-message-error-text = @color-message-text) { color: @color-message-error-text; } + & > i.icon:before { + & when not(@color-message-error-text = @color-message-text) { color: @color-message-error-text; } + } + } + + a { + color: inherit !important; + text-decoration: underline; + cursor: pointer; + } +} diff --git a/templates/about.html b/templates/about.html new file mode 100644 index 0000000..8cf514e --- /dev/null +++ b/templates/about.html @@ -0,0 +1,18 @@ + + +

+ +
+ +

Roundcube Webmail

+ +

+
+

+ +

+ +
+
+ + diff --git a/templates/addressbook.html b/templates/addressbook.html new file mode 100644 index 0000000..3845f42 --- /dev/null +++ b/templates/addressbook.html @@ -0,0 +1,157 @@ + + + +

+ + +
+ + +
+
+ + + + + +
+ + +
+

+ +
+ +
+ + +
+

+ +

+
+ +
+
+ + +
+

+ +
+ +
+

+ +
+ +
+

+ +
+ +
+

+ +
+ +
+

+ +
+ + diff --git a/templates/bounce.html b/templates/bounce.html new file mode 100644 index 0000000..f9fbf02 --- /dev/null +++ b/templates/bounce.html @@ -0,0 +1,74 @@ + + +

+ +
+ + +
+

+
+
+ +
+
+ + + " tabindex="1"> +
+
+
+
+ +
+
+ + + " tabindex="1"> + +
+
+
+ + +
+ +
+ +
+ +
+
+ + +
+ +
+

+ +
+ + diff --git a/templates/compose.html b/templates/compose.html new file mode 100644 index 0000000..0f7cad8 --- /dev/null +++ b/templates/compose.html @@ -0,0 +1,286 @@ + + + + + + + + + +

+ + + + +
+

+
+ + +
+ + +
+
+ + + +
+

+
+
+ +
+
+ + + " tabindex="1"> + +
+
+
+
+ +
+ +
+
+ + + + +
+ +
+ +
+
+
+
+ +
+ + + +
+ +
+ +
+ +
+
+
+
+ + + +
+ +
+

+ +
+ +
+

+ +
+ +
+

+ +
+ +
+ +
+ +
+
+ +
+ + +
+ +
+
+ + diff --git a/templates/contact.html b/templates/contact.html new file mode 100644 index 0000000..3df09b8 --- /dev/null +++ b/templates/contact.html @@ -0,0 +1,23 @@ + + +

+ +
+
+
+ +
+ +
+
+ +
+
+ +
+ +
+ + diff --git a/templates/contactedit.html b/templates/contactedit.html new file mode 100644 index 0000000..3842208 --- /dev/null +++ b/templates/contactedit.html @@ -0,0 +1,29 @@ + + +

+ + +
+
+ + + + + +
+ +
+
+ +
+ + +
+ +
+ + + + diff --git a/templates/contactimport.html b/templates/contactimport.html new file mode 100644 index 0000000..b7f30ee --- /dev/null +++ b/templates/contactimport.html @@ -0,0 +1,9 @@ + + +

:

+ +
+ +
+ + diff --git a/templates/contactprint.html b/templates/contactprint.html new file mode 100644 index 0000000..ffa16b5 --- /dev/null +++ b/templates/contactprint.html @@ -0,0 +1,19 @@ + + +