├── .gitignore ├── CHANGELOG.md ├── MANIFEST.in ├── README.md ├── babel.cfg ├── extras ├── customization.png ├── discorded_ss.png └── themeify.md ├── octoprint_themeify ├── __init__.py ├── static │ ├── css │ │ └── includes.css │ ├── dist │ │ ├── themeify.min.css │ │ └── themeify.min.js │ ├── img │ │ ├── ic_sd_card_white_18dp_1x.png │ │ └── ic_sd_card_white_18px.svg │ ├── js │ │ └── themeify.js │ └── less │ │ ├── base.less │ │ ├── cyborg │ │ ├── cyborg.less │ │ ├── mixins.less │ │ └── variables.less │ │ ├── discoranged │ │ ├── discoranged.less │ │ └── variables.less │ │ ├── discorded │ │ ├── discorded.less │ │ └── variables.less │ │ ├── dyl │ │ ├── components │ │ │ ├── buttons.less │ │ │ ├── dropdown.less │ │ │ ├── forms.less │ │ │ └── modal.less │ │ ├── dyl.less │ │ ├── files.less │ │ ├── footer.less │ │ ├── mixins.less │ │ ├── navbar.less │ │ ├── navtabs.less │ │ ├── sidebar.less │ │ ├── tabs │ │ │ ├── control.less │ │ │ └── temp.less │ │ └── variables.less │ │ ├── material-ui-light │ │ └── material_ui_light.less │ │ └── nighttime │ │ └── nighttime.less └── templates │ └── themeify_settings.jinja2 ├── package.json ├── requirements.txt ├── setup.py ├── webpack.config.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.swp 3 | .idea 4 | *.iml 5 | build 6 | *.egg* 7 | .DS_Store 8 | *.zip 9 | node_modules 10 | /package-lock.json 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [1.2.2](https://github.com/Birkbjo/OctoPrint-Themeify/compare/v1.2.1...v1.2.2) (2020-04-02) 6 | 7 | ### 1.2.1 (2020-04-01) 8 | 9 | 10 | ### Bug Fixes 11 | 12 | * remove quotes in selectors to prevent crashes ([f3c1bca](https://github.com/Birkbjo/OctoPrint-Themeify/commit/f3c1bca7cb316dadd7a8009574573e282221632f)), closes [#45](https://github.com/Birkbjo/OctoPrint-Themeify/issues/45) 13 | * subscribe to icon-change ([ed7483f](https://github.com/Birkbjo/OctoPrint-Themeify/commit/ed7483fa02204cb9d8a94e06f5d06e3407a15fda)) 14 | * **cyborg-theme:** fix float layout. Fixes [#56](https://github.com/Birkbjo/OctoPrint-Themeify/issues/56) ([2675c36](https://github.com/Birkbjo/OctoPrint-Themeify/commit/2675c36d604dabef14d7f529c5504542c279f341)) 15 | * octoprint 1.4 compatability ([fa7e3d1](https://github.com/Birkbjo/OctoPrint-Themeify/commit/fa7e3d1b38055228fd0156ff0df79de64cb7f0b9)) 16 | * **logger:** python 3 compat ([74f2fc1](https://github.com/Birkbjo/OctoPrint-Themeify/commit/74f2fc1c91fad74f186a34e299f62b127e649940)) 17 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md 2 | recursive-include octoprint_themeify/templates * 3 | recursive-include octoprint_themeify/translations * 4 | recursive-include octoprint_themeify/static * 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OctoPrint-Themeify 2 | 3 | A small [OctoPrint](https://github.com/foosel/OctoPrint) plugin to change the looks of OctoPrint! 4 | Currently features a beautiful Dark Theme inspired by Discord's color [palette](https://discordapp.com/branding), along with a handful of others thanks to the awesome contributors. 5 | 6 | Also features customization of individual elements. With the advanced-customization scheme you can modify the appearance to your heart's desire directly from the settings-dialog! 7 | 8 | 9 | 10 | 11 | ![](extras/discorded_ss.png) 12 | ![](extras/customization.png) 13 | ## Setup 14 | 15 | Install via the bundled [Plugin Manager](https://github.com/foosel/OctoPrint/wiki/Plugin:-Plugin-Manager) by searching for "Themify", or 16 | manually enter this URL: 17 | 18 | https://github.com/birkbjo/OctoPrint-Themeify/archive/master.zip 19 | 20 | 21 | If you don't see the styled header bar, go into Settings -> Appeareance and set Color to "default" and uncheck "Transparent Color". 22 | 23 | ## Contribute 24 | 25 | Contributions are always welcome, especially new themes! 26 | 27 | The Javascript and Less are compiled and bundled with webpack. 28 | The reason for this is to be able to use new JS features and have one place to build both the less and JS. 29 | 30 | ### Getting started 31 | 32 | Get NodeJS: https://nodejs.org/en/ 33 | 34 | Clone the repo: 35 | ```bash 36 | git clone https://github.com/Birkbjo/OctoPrint-Themeify.git 37 | cd OctoPrint-Themeify 38 | ``` 39 | 40 | Use npm install or [install yarn](https://yarnpkg.com/lang/en/docs/install/#windows-tab) 41 | 42 | ```bash 43 | yarn install && yarn build 44 | ``` 45 | 46 | Install the plugin into your octoprint instance: 47 | ``` 48 | octoprint dev plugin:install 49 | ``` 50 | Start hacking! 51 | 52 | If you edit the javascript, I advise to use 53 | ```bash 54 | yarn watch 55 | ``` 56 | so that you do not need to build for every change. 57 | 58 | If you have setup `stylesheet: less` in your `config.yaml` you can edit the less-files and reload the page without re-building for each change. 59 | 60 | #### Build 61 | 62 | Build javascript and css: 63 | ```bash 64 | yarn build 65 | ``` 66 | -------------------------------------------------------------------------------- /babel.cfg: -------------------------------------------------------------------------------- 1 | [python: */**.py] 2 | [jinja2: */**.jinja2] 3 | extensions=jinja2.ext.autoescape, jinja2.ext.with_ 4 | 5 | [javascript: */**.js] 6 | extract_messages = gettext, ngettext 7 | -------------------------------------------------------------------------------- /extras/customization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Birkbjo/OctoPrint-Themeify/a07164c232cdeded5087d54840a2d37655df330d/extras/customization.png -------------------------------------------------------------------------------- /extras/discorded_ss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Birkbjo/OctoPrint-Themeify/a07164c232cdeded5087d54840a2d37655df330d/extras/discorded_ss.png -------------------------------------------------------------------------------- /extras/themeify.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: plugin 3 | 4 | id: themeify 5 | title: Themeify 6 | description: Beautiful themes for octoprint 7 | author: Birk Johansson 8 | license: AGPLv3 9 | 10 | date: 2017-11-11 11 | 12 | homepage: https://github.com/birkbjo/OctoPrint-Themeify 13 | source: https://github.com/birkbjo/OctoPrint-Themeify 14 | archive: https://github.com/birkbjo/OctoPrint-Themeify/archive/master.zip 15 | 16 | tags: 17 | - theme 18 | - dark 19 | - style 20 | - styling 21 | 22 | screenshots: 23 | - url: /assets/img/plugins/themeify/discorded_ss.png 24 | alt: Discorded theme 25 | caption: Discorded theme 26 | 27 | featuredimage: /assets/img/plugins/themeify/discorded_ss.png 28 | 29 | compatibility: 30 | 31 | octoprint: 32 | - 1.3.5 33 | 34 | os: 35 | - linux 36 | - windows 37 | - macos 38 | - freebsd 39 | 40 | --- 41 | 42 | A small [OctoPrint](https://github.com/foosel/OctoPrint) plugin to change the looks of OctoPrint! 43 | Currently supports a beautiful Dark Theme inspired by Discord's color [palette](https://discordapp.com/branding). More configuration and themes are planned. 44 | 45 | -------------------------------------------------------------------------------- /octoprint_themeify/__init__.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from __future__ import absolute_import 3 | import octoprint.plugin 4 | import time 5 | 6 | 7 | class ThemeifyPlugin(octoprint.plugin.StartupPlugin, 8 | octoprint.plugin.AssetPlugin, 9 | octoprint.plugin.SettingsPlugin, 10 | octoprint.plugin.TemplatePlugin): 11 | 12 | def on_after_startup(self): 13 | self._logger.info("Themeify initialized.") 14 | 15 | def get_assets(self): 16 | return dict( 17 | less=["less/base.less"], 18 | css=["dist/themeify.min.css", "css/includes.css"], 19 | js=["dist/themeify.min.js"] 20 | ) 21 | 22 | def get_settings_defaults(self): 23 | return dict( 24 | enabled=True, 25 | enableCustomization=False, 26 | theme='discorded', 27 | color=[dict( 28 | selector='.navbar-inner', 29 | rule="background", 30 | value="#2f3136", 31 | enabled=False, 32 | deletable=False)], 33 | customRules=[ 34 | dict( 35 | selector='.navbar-inner', 36 | rule="background-color", 37 | value="#2f3136", 38 | enabled=False), 39 | dict( 40 | selector='.accordion', 41 | rule="background-color", 42 | value="#2f3136", 43 | enabled=False) 44 | ], 45 | tabs=dict( 46 | enableIcons=False, 47 | icons=[ 48 | dict( 49 | domId="#temp_link", 50 | enabled=True, 51 | faIcon="fa fa-line-chart" 52 | ), 53 | dict( 54 | domId="#control_link", 55 | enabled=True, 56 | faIcon="fa fa-gamepad", 57 | ), 58 | dict( 59 | domId="#gcode_link", 60 | enabled=True, 61 | faIcon="fa fa-object-ungroup" 62 | ), 63 | dict( 64 | domId="#term_link", 65 | enabled=True, 66 | faIcon="fa fa-terminal" 67 | )], 68 | ) 69 | ) 70 | 71 | # def on_settings_save(self, data): 72 | # self._logger.log(data) 73 | # octoprint.plugin.SettingsPlugin.on_settings_save(self, data) 74 | 75 | def get_template_configs(self): 76 | return [ 77 | dict(type="settings", custom_bindings=True) 78 | ] 79 | 80 | def get_update_information(self): 81 | # Define the configuration for your plugin to use with the Software Update 82 | # Plugin here. See https://github.com/foosel/OctoPrint/wiki/Plugin:-Software-Update 83 | # for details. 84 | return dict( 85 | themeify=dict( 86 | displayName="Themeify", 87 | displayVersion=self._plugin_version, 88 | 89 | # version check: github repository 90 | type="github_release", 91 | user="birkbjo", 92 | repo="OctoPrint-Themeify", 93 | current=self._plugin_version, 94 | 95 | # update method: pip 96 | pip="https://github.com/birkbjo/OctoPrint-Themeify/archive/{target_version}.zip" 97 | ) 98 | ) 99 | 100 | 101 | __plugin_name__ = "Themeify" 102 | __plugin_pythoncompat__ = ">=2.7,<4" 103 | 104 | def __plugin_load__(): 105 | global __plugin_implementation__ 106 | __plugin_implementation__ = ThemeifyPlugin() 107 | 108 | global __plugin_hooks__ 109 | __plugin_hooks__ = { 110 | "octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information 111 | } 112 | -------------------------------------------------------------------------------- /octoprint_themeify/static/css/includes.css: -------------------------------------------------------------------------------- 1 | #settings_plugin_themeify div.disabled { 2 | opacity: 0.4; 3 | pointer-events: none; 4 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/dist/themeify.min.js: -------------------------------------------------------------------------------- 1 | !function(e){function t(o){if(n[o])return n[o].exports;var s=n[o]={i:o,l:!1,exports:{}};return e[o].call(s.exports,s,s.exports,t),s.l=!0,s.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){n(1),e.exports=n(2)},function(e,t){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}$(function(){function e(e){ko.extenders.stripQuotes=function(e,t){var n=ko.pureComputed({read:e,write:function(t){var n=t.replace(/['"]+/g,"");e(n)}}).extend({notify:"always"});return n(e()),n};var t=this;t.classId="themeify",t.settings=e[0],t.ownSettings={},t.customRules=[],t.customizedElements=[],t.builtInElements=[],t._ownSettingsPrev={},t.configSubscriptions={enabled:"",theme:""},t.tabIcons={},t.oldTabContent={};var o=function(e){return t._ownSettingsPrev[e]};t.onStartupComplete=function(){var e=$("html").attr("id");e&&"touch"==e&&$("html").removeClass(t.classId),t.updateColors(),t._updateCustomRules()},t.setupIcons=function(){t.tabIcons.tabs().filter(function(e){return e.domId()&&e.enabled()}).map(function(e,n){var o=e.domId,s=(e.enabled,e.faIcon),i=$("",{class:s()}),u=$("".concat(o()," a"));u&&"tabs"===u.closest("ul").attr("id")?(t.oldTabContent[o()]=$("".concat(o()," a")).html(),u.html(i)):console.warn("Themeify: Failed to add icon! ".concat(o()," is not a child of the tab-list!"))})},t.restoreTabs=function(){t.tabIcons.tabs().filter(function(e){return e.domId()}).map(function(e,n){var o=e.domId,s=(e.enabled,e.faIcon,t.oldTabContent[o()]);s&&$("".concat(o()," a")).html(s)})},t.enableBeforeLoaded=function(){var e=localStorage.getItem("theme");e&&$("html").addClass(t.classId).addClass(e)},t.enable=function(){if(t.ownSettings.enabled()&&"touch"!==$("html").attr("id")){var e=t.ownSettings.theme();localStorage.setItem("theme",e),$("html").addClass(t.classId).addClass(t.ownSettings.theme())}},t.addNewCustomRule=function(){var e={selector:ko.observable("").extend({stripQuotes:!0}),rule:ko.observable("").extend({stripQuotes:!0}),value:ko.observable(""),enabled:ko.observable(!0)};t._subscribeToDictValues(e,"customRules"),t.ownSettings.customRules.push(e)},t.addNewIcon=function(){var e={domId:ko.observable("").extend({stripQuotes:!0}),enabled:ko.observable(!0),faIcon:ko.observable("")};t._subscribeToDictValues(e,"tabs",t.onIconChange),t.tabIcons.tabs.push(e)},t.onBeforeBinding=function(){t.settings=t.settings.settings,t.ownSettings=t.settings.plugins.themeify,t.customRules=t.ownSettings.customRules.extend({rateLimit:50}),t.onRuleToggle=t.onRuleToggle,t.tabIcons={enabled:t.ownSettings.tabs.enableIcons,tabs:t.ownSettings.tabs.icons},t.tabIcons.enabled()&&t.setupIcons(),t.enable(),t._copyOwnSettings()},t.updateColors=function(){t._removeBuiltInStyles(),t.ownSettings.enableCustomization()&&t.ownSettings.color().filter(function(e){return!!e.enabled()}).map(function(e,n){t._applyRule(e,!0)})},t._updateCustomRules=function(){t._removeCustomStyles(),t.updateColors(),t.ownSettings.enableCustomization()&&t.ownSettings.customRules().filter(function(e){return!!e.enabled()}).map(function(e){t._applyRule(e)})},t._applyRule=function(e){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],o=$(e.selector()),s=o.css(e.rule());n?t.builtInElements.push({elem:o,rule:e.rule(),old:s}):t.customizedElements.push({elem:o,rule:e.rule(),old:s}),$(e.selector()).css(e.rule(),e.value())},t.clone=function(e){if("function"==typeof e)return e();if(null===e||"object"!==n(e)||"isActiveClone"in e)return e;if(e instanceof Date)var o=new e.constructor;else var o=e.constructor();for(var s in e)Object.prototype.hasOwnProperty.call(e,s)&&(e.isActiveClone=null,o[s]=t.clone(e[s]),delete e.isActiveClone);return o},t._copyOwnSettings=function(){Object.keys(t.ownSettings).forEach(function(e,n){t._ownSettingsPrev[e]=t.clone(t.ownSettings[e])})},t.onChange=function(e,n){t.updateColors(),t._copyOwnSettings()},t.onColorChange=function(e,n){t.updateColors(),t._copyOwnSettings()},t.onCustomRuleChange=function(e){t.updateColors(),e.rule()&&e.selector()&&e.value()&&t._updateCustomRules()},t.onThemeChange=function(e){var n=o("theme");(function(e){return $("html").hasClass(e)})(e)||(localStorage.setItem("theme",e),$("html").addClass(e).removeClass(n)),t._copyOwnSettings()},t.onEnabledChange=function(e){if(e&&"touch"!==$("html").attr("id")){var n=t.ownSettings.theme();$("html").addClass(t.classId).addClass(n),localStorage.setItem("theme",n)}else $("html").removeClass(t.classId),localStorage.setItem("theme",!1);t._copyOwnSettings()},t.onEnableCustomizationChange=function(e){e?(t.updateColors(),t._updateCustomRules()):(t._removeBuiltInStyles(),t._removeCustomStyles()),t._copyOwnSettings()},t.onIconsEnableChange=function(e){e?t.setupIcons():t.restoreTabs()},t.onIconChange=function(e,n,o){t.tabIcons.enabled()&&("enabled"!==o||n||t.restoreTabs(),t.setupIcons())},t._removeCustomStyles=function(){t.customizedElements.map(function(e){return e.elem.css(e.rule,"")})},t._removeBuiltInStyles=function(){t.builtInElements.map(function(e){return e.elem.css(e.rule,"")})},t._removeCustomStylesByRule=function(e){$(e.selector()).css(e.rule(),"")},t.onRuleToggle=function(e){e.enabled(!e.enabled())},t.ruleIsDeleteable=function(e){return!e.deletable||"function"!=typeof e.deletable||e.deletable()},t.onCustomRuleDelete=function(e){t.ruleIsDeleteable(e)&&(t.customRules.remove(e),t._updateCustomRules())},t.onIconDelete=function(e){t.restoreTabs(),t.tabIcons.tabs.remove(e),t.setupIcons()},t._subscribeToDictValues=function(e,n,o){var s=o?o.bind(this,e):t.onCustomRuleChange.bind(this,e);Object.keys(e).map(function(o){t.configSubscriptions[n].push(e[o].subscribe(function(e){return s(e,o)}))})},t.onSettingsShown=function(){var e=this;Object.keys(t.ownSettings).map(function(n,o){if("customRules"==n)t.configSubscriptions[n]=[],t.customRules().map(function(e,o){t._subscribeToDictValues(e,n)});else if("color"==n){t.configSubscriptions[n]=[];var s=t.onColorChange;t.ownSettings.color().map(function(e,o){t._subscribeToDictValues(e,n,s)})}else if("tabs"==n){var i=t.configSubscriptions[n]=[],u=t.tabIcons,l=u.enabled,a=u.tabs;i.push(l.subscribe(t.onIconsEnableChange)),a().map(function(e,o){t._subscribeToDictValues(e,n,t.onIconChange)})}else{var c=t.configOnChangeMap[n]?t.configOnChangeMap[n]:t.onChange.bind(e,n);t.configSubscriptions[n]=t.ownSettings[n].subscribe(c)}})},t.onSettingsHidden=function(){Object.keys(t.configSubscriptions).map(function(e,n){Array.isArray(t.configSubscriptions[e])?t.configSubscriptions[e].forEach(function(e){e.dispose()}):t.configSubscriptions[e].dispose()})},t.enableBeforeLoaded(),t.configOnChangeMap={enabled:t.onEnabledChange,theme:t.onThemeChange,enableCustomization:t.onEnableCustomizationChange}}OCTOPRINT_VIEWMODELS.push([e,["settingsViewModel"],["#settings_plugin_themeify"]])})},function(e,t){}]); -------------------------------------------------------------------------------- /octoprint_themeify/static/img/ic_sd_card_white_18dp_1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Birkbjo/OctoPrint-Themeify/a07164c232cdeded5087d54840a2d37655df330d/octoprint_themeify/static/img/ic_sd_card_white_18dp_1x.png -------------------------------------------------------------------------------- /octoprint_themeify/static/img/ic_sd_card_white_18px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /octoprint_themeify/static/js/themeify.js: -------------------------------------------------------------------------------- 1 | /* 2 | * View model for OctoPrint-Themeify 3 | * 4 | * Author: Birk Johansson 5 | * License: MIT 6 | */ 7 | 8 | $(function() { 9 | 10 | function ThemeifyViewModel(parameters) { 11 | ko.extenders.stripQuotes = function(target, opts) { 12 | const result = ko.pureComputed({ 13 | read: target, 14 | write: function(newVal) { 15 | const stripped = newVal.replace(/['"]+/g, '') 16 | target(stripped) 17 | } 18 | }).extend({ notify: 'always' }); 19 | result(target()) 20 | return result; 21 | } 22 | 23 | var self = this; 24 | self.classId = 'themeify'; 25 | self.settings = parameters[0]; 26 | 27 | self.ownSettings = {}; 28 | self.customRules = []; 29 | //These hold the customized and built-in changed/overriden elements, respectively 30 | self.customizedElements = []; 31 | self.builtInElements = []; 32 | 33 | self._ownSettingsPrev = {}; 34 | //holds subscriptions, so that they can be removed later 35 | self.configSubscriptions = { 36 | enabled: '', 37 | theme: '', 38 | }; 39 | self.tabIcons = {}; 40 | self.oldTabContent = {}; 41 | var oldVal = function(key) { 42 | return self._ownSettingsPrev[key]; 43 | }; 44 | 45 | self.onStartupComplete = function() { 46 | var htmlId = $('html').attr('id'); 47 | //Remove styling if touch is enabled 48 | if (htmlId && htmlId == 'touch') { 49 | $('html').removeClass(self.classId); 50 | } 51 | 52 | self.updateColors(); 53 | self._updateCustomRules(); 54 | }; 55 | 56 | self.setupIcons = function() { 57 | self.tabIcons 58 | .tabs() 59 | .filter(tab => tab.domId() && tab.enabled()) 60 | .map((tab, i) => { 61 | const { domId, enabled, faIcon } = tab; 62 | const icon = $(``, { class: faIcon() }); 63 | const elem$ = $(`${domId()} a`); 64 | if (elem$ && elem$.closest('ul').attr('id') === 'tabs') { 65 | self.oldTabContent[domId()] = $(`${domId()} a`).html(); 66 | elem$.html(icon); 67 | } else { 68 | console.warn( 69 | `Themeify: Failed to add icon! ${domId()} is not a child of the tab-list!` 70 | ); 71 | } 72 | }); 73 | }; 74 | 75 | self.restoreTabs = function() { 76 | self.tabIcons 77 | .tabs() 78 | .filter(tab => tab.domId()) 79 | .map((tab, i) => { 80 | const { domId, enabled, faIcon } = tab; 81 | const oldContent = self.oldTabContent[domId()]; 82 | if (oldContent) { 83 | $(`${domId()} a`).html(oldContent); 84 | } 85 | }); 86 | }; 87 | 88 | self.enableBeforeLoaded = function() { 89 | const localTheme = localStorage.getItem('theme'); 90 | if (localTheme) { 91 | $('html') 92 | .addClass(self.classId) 93 | .addClass(localTheme); 94 | } 95 | }; 96 | 97 | self.enable = function() { 98 | if ( 99 | self.ownSettings.enabled() && 100 | $('html').attr('id') !== 'touch' 101 | ) { 102 | const theme = self.ownSettings.theme(); 103 | localStorage.setItem('theme', theme); 104 | $('html') 105 | .addClass(self.classId) 106 | .addClass(self.ownSettings.theme()); 107 | } 108 | }; 109 | 110 | self.addNewCustomRule = function() { 111 | var ruleObj = { 112 | selector: ko.observable('').extend({ stripQuotes: true}), 113 | rule: ko.observable('').extend({ stripQuotes: true}), 114 | value: ko.observable(''), 115 | enabled: ko.observable(true), 116 | }; 117 | self._subscribeToDictValues(ruleObj, 'customRules'); 118 | self.ownSettings.customRules.push(ruleObj); 119 | }; 120 | 121 | self.addNewIcon = function() { 122 | var icon = { 123 | domId: ko.observable('').extend({ stripQuotes: true}), 124 | enabled: ko.observable(true), 125 | faIcon: ko.observable(''), 126 | }; 127 | self._subscribeToDictValues(icon, 'tabs', self.onIconChange); 128 | self.tabIcons.tabs.push(icon); 129 | }; 130 | 131 | self.onBeforeBinding = function() { 132 | self.settings = self.settings.settings; 133 | self.ownSettings = self.settings.plugins.themeify; 134 | self.customRules = self.ownSettings.customRules.extend({ 135 | rateLimit: 50, 136 | }); 137 | self.onRuleToggle = self.onRuleToggle; 138 | self.tabIcons = { 139 | enabled: self.ownSettings.tabs.enableIcons, 140 | tabs: self.ownSettings.tabs.icons, 141 | }; 142 | 143 | if (self.tabIcons.enabled()) { 144 | self.setupIcons(); 145 | } 146 | 147 | self.enable(); 148 | 149 | self._copyOwnSettings(); 150 | }; 151 | 152 | self.updateColors = function() { 153 | self._removeBuiltInStyles(); 154 | if (self.ownSettings.enableCustomization()) { 155 | self.ownSettings 156 | .color() 157 | .filter(rule => !!rule.enabled()) 158 | .map((rule, i) => { 159 | self._applyRule(rule, true); 160 | }); 161 | } 162 | }; 163 | 164 | self._updateCustomRules = function() { 165 | self._removeCustomStyles(); 166 | self.updateColors(); 167 | if (self.ownSettings.enableCustomization()) { 168 | self.ownSettings 169 | .customRules() 170 | .filter(rule => !!rule.enabled()) 171 | .map(rule => { 172 | self._applyRule(rule); 173 | }); 174 | } 175 | }; 176 | 177 | self._applyRule = function(rule, builtIn = false) { 178 | var elem = $(rule.selector()); 179 | var old = elem.css(rule.rule()); 180 | if (builtIn) { 181 | self.builtInElements.push({ 182 | elem: elem, 183 | rule: rule.rule(), 184 | old, 185 | }); 186 | } else { 187 | self.customizedElements.push({ 188 | elem: elem, 189 | rule: rule.rule(), 190 | old, 191 | }); 192 | } 193 | $(rule.selector()).css(rule.rule(), rule.value()); 194 | }; 195 | 196 | self.clone = function(obj) { 197 | //get observable value 198 | if (typeof obj == 'function') { 199 | return obj(); 200 | } 201 | 202 | if ( 203 | obj === null || 204 | typeof obj !== 'object' || 205 | 'isActiveClone' in obj 206 | ) 207 | return obj; 208 | 209 | if (obj instanceof Date) var temp = new obj.constructor(); 210 | else var temp = obj.constructor(); 211 | 212 | for (var key in obj) { 213 | if (Object.prototype.hasOwnProperty.call(obj, key)) { 214 | obj['isActiveClone'] = null; 215 | temp[key] = self.clone(obj[key]); 216 | delete obj['isActiveClone']; 217 | } 218 | } 219 | 220 | return temp; 221 | }; 222 | 223 | self._copyOwnSettings = function() { 224 | Object.keys(self.ownSettings).forEach(function(key, i) { 225 | self._ownSettingsPrev[key] = self.clone(self.ownSettings[key]); 226 | }); 227 | }; 228 | 229 | self.onChange = function(settingKey, newVal) { 230 | self.updateColors(); 231 | self._copyOwnSettings(); 232 | }; 233 | 234 | self.onColorChange = function(elem, color) { 235 | self.updateColors(); 236 | self._copyOwnSettings(); 237 | }; 238 | 239 | self.onCustomRuleChange = function(rule) { 240 | self.updateColors(); 241 | if (rule.rule() && rule.selector() && rule.value()) { 242 | self._updateCustomRules(); 243 | } 244 | }; 245 | 246 | self.onThemeChange = function(newVal) { 247 | var prev = oldVal('theme'); 248 | var hasClass = clazz => { 249 | return $('html').hasClass(clazz); 250 | }; 251 | if (!hasClass(newVal)) { 252 | localStorage.setItem('theme', newVal); 253 | $('html') 254 | .addClass(newVal) 255 | .removeClass(prev); 256 | } 257 | 258 | self._copyOwnSettings(); 259 | }; 260 | 261 | self.onEnabledChange = function(newVal) { 262 | if (newVal && $('html').attr('id') !== 'touch') { 263 | const theme = self.ownSettings.theme(); 264 | $('html') 265 | .addClass(self.classId) 266 | .addClass(theme); 267 | localStorage.setItem('theme', theme); 268 | } else { 269 | $('html').removeClass(self.classId); 270 | localStorage.setItem('theme', false); 271 | } 272 | 273 | self._copyOwnSettings(); 274 | }; 275 | 276 | self.onEnableCustomizationChange = function(newVal) { 277 | if (newVal) { 278 | self.updateColors(); 279 | self._updateCustomRules(); 280 | } else { 281 | self._removeBuiltInStyles(); 282 | self._removeCustomStyles(); 283 | } 284 | self._copyOwnSettings(); 285 | }; 286 | 287 | self.onIconsEnableChange = function(newVal) { 288 | if (newVal) { 289 | self.setupIcons(); 290 | } else { 291 | self.restoreTabs(); 292 | } 293 | }; 294 | 295 | self.onIconChange = function(icon, value, propKey) { 296 | if (!self.tabIcons.enabled()) return; 297 | 298 | if (propKey === 'enabled' && !value) { 299 | self.restoreTabs(); 300 | } 301 | self.setupIcons(); 302 | }; 303 | 304 | self._removeCustomStyles = function() { 305 | self.customizedElements.map(elem => elem.elem.css(elem.rule, '')); 306 | }; 307 | 308 | self._removeBuiltInStyles = function() { 309 | self.builtInElements.map(elem => elem.elem.css(elem.rule, '')); 310 | }; 311 | 312 | self._removeCustomStylesByRule = function(rule) { 313 | $(rule.selector()).css(rule.rule(), ''); 314 | }; 315 | 316 | self.onRuleToggle = function(rule) { 317 | rule.enabled(!rule.enabled()); 318 | //onCustomColorChange will pickup this change and update accordingly 319 | }; 320 | 321 | self.ruleIsDeleteable = function(rule) { 322 | //deleteable if not exists 323 | if (!rule.deletable || typeof rule.deletable !== 'function') { 324 | return true; 325 | } 326 | return rule.deletable(); 327 | }; 328 | 329 | self.onCustomRuleDelete = function(rule) { 330 | if (self.ruleIsDeleteable(rule)) { 331 | self.customRules.remove(rule); 332 | self._updateCustomRules(); 333 | } 334 | }; 335 | 336 | self.onIconDelete = function(icon) { 337 | self.restoreTabs(); 338 | self.tabIcons.tabs.remove(icon); 339 | self.setupIcons(); 340 | }; 341 | 342 | self._subscribeToDictValues = function(dict, key, subscribeFunc) { 343 | var subFunc = subscribeFunc 344 | ? subscribeFunc.bind(this, dict) 345 | : self.onCustomRuleChange.bind(this, dict); 346 | Object.keys(dict).map(dictAttr => { 347 | self.configSubscriptions[key].push( 348 | dict[dictAttr].subscribe(val => subFunc(val, dictAttr)) 349 | ); 350 | }); 351 | }; 352 | self.onSettingsShown = function() { 353 | //subscribe to changes 354 | Object.keys(self.ownSettings).map((key, i) => { 355 | if (key == 'customRules') { 356 | self.configSubscriptions[key] = []; 357 | self.customRules().map((rule, i) => { 358 | //subscribe to the attributes (selector, rule, value, enabled etc) 359 | self._subscribeToDictValues(rule, key); 360 | }); 361 | } else if (key == 'color') { 362 | self.configSubscriptions[key] = []; 363 | var subFunc = self.onColorChange; 364 | //Loop rules 365 | self.ownSettings.color().map((rule, i) => { 366 | //subscribe to the attributes (selector, rule, value, enabled etc) 367 | self._subscribeToDictValues(rule, key, subFunc); 368 | }); 369 | } else if (key == 'tabs') { 370 | const sub = (self.configSubscriptions[key] = []); 371 | const { enabled, tabs } = self.tabIcons; 372 | sub.push(enabled.subscribe(self.onIconsEnableChange)); 373 | tabs().map((tab, i) => { 374 | self._subscribeToDictValues( 375 | tab, 376 | key, 377 | self.onIconChange 378 | ); 379 | }); 380 | } else { 381 | //Use the map for simple subscriptions 382 | var onChangeFunc = self.configOnChangeMap[key] 383 | ? self.configOnChangeMap[key] 384 | : self.onChange.bind(this, key); 385 | self.configSubscriptions[key] = self.ownSettings[ 386 | key 387 | ].subscribe(onChangeFunc); 388 | } 389 | }); 390 | }; 391 | 392 | self.onSettingsHidden = function() { 393 | //Cleanup subscriptions 394 | Object.keys(self.configSubscriptions).map((key, i) => { 395 | if (Array.isArray(self.configSubscriptions[key])) { 396 | self.configSubscriptions[key].forEach(elem => { 397 | elem.dispose(); 398 | }); 399 | } else { 400 | self.configSubscriptions[key].dispose(); 401 | } 402 | }); 403 | }; 404 | 405 | //optimize "flicker" before theme is loaded 406 | self.enableBeforeLoaded(); 407 | 408 | self.configOnChangeMap = { 409 | enabled: self.onEnabledChange, 410 | theme: self.onThemeChange, 411 | enableCustomization: self.onEnableCustomizationChange, 412 | }; 413 | } 414 | 415 | OCTOPRINT_VIEWMODELS.push([ 416 | ThemeifyViewModel, 417 | ['settingsViewModel'], 418 | ['#settings_plugin_themeify'], 419 | ]); 420 | }); 421 | -------------------------------------------------------------------------------- /octoprint_themeify/static/less/base.less: -------------------------------------------------------------------------------- 1 | @import "discorded/discorded.less"; 2 | @import "material-ui-light/material_ui_light.less"; 3 | @import "cyborg/cyborg.less"; 4 | @import "discoranged/discoranged.less"; 5 | @import "dyl/dyl.less"; 6 | @import "nighttime/nighttime.less"; 7 | 8 | .themeify { 9 | &.discorded { 10 | .discorded(); 11 | } 12 | &.material_ui_light { 13 | .material_ui_light(); 14 | } 15 | &.cyborg { 16 | .cyborg(); 17 | } 18 | &.discoranged { 19 | .discoranged(); 20 | } 21 | &.dyl { 22 | .dyl(); 23 | } 24 | &.nighttime { 25 | .nighttime(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /octoprint_themeify/static/less/cyborg/cyborg.less: -------------------------------------------------------------------------------- 1 | @import "mixins.less"; 2 | @import "variables.less"; 3 | 4 | .cyborg() { 5 | 6 | body { 7 | min-height: 100%; 8 | color: @gray; 9 | #gradient > .vertical (@bodyBackground, #252A30); 10 | } 11 | 12 | a { 13 | color: @linkColor; 14 | &:hover { 15 | color: @linkColorHover; 16 | } 17 | } 18 | span .caret { 19 | color: red !important; 20 | } 21 | 22 | .modal { 23 | color: @gray; 24 | #gradient > .radial(lighten(@bodyBackground, 10%), @bodyBackground); 25 | & h1, h2, h3, h4, h5, h6 { 26 | color: @almostNotWhite; 27 | } 28 | } 29 | .modal-footer { 30 | color: @gray; 31 | background-color: @dropdownBackground; 32 | } 33 | 34 | .modal-header { 35 | color: @gray; 36 | background-color: @dropdownBackground; 37 | } 38 | 39 | .hero-unit { 40 | font-size: 18px; 41 | font-weight: 200; 42 | color: inherit; 43 | background-color: @dropdownBackground; 44 | } 45 | 46 | .hero-unit h1 { 47 | font-size: 60px; 48 | letter-spacing: -1px; 49 | color: inherit; 50 | } 51 | 52 | .close, 53 | .close:hover { 54 | color: @red; 55 | background-color: transparent; 56 | text-shadow: 0 1px 0 #555; 57 | opacity: 1; 58 | } 59 | 60 | .nav-tabs { 61 | & >.active > a { 62 | color: #ffffff; 63 | background-image: linear-gradient(to bottom,#08c,#0077b3); 64 | &:hover { 65 | color: @white; 66 | background-image: none; 67 | background-color: #33b5e5; 68 | } 69 | } 70 | >li>a:hover { 71 | color: @white; 72 | background-image: none; 73 | background-color: #33b5e5; 74 | } 75 | } 76 | 77 | legend { 78 | color: @grayLight; 79 | } 80 | 81 | .nav-list { 82 | .nav-header { 83 | text-shadow: none; 84 | } 85 | &>.active>a { 86 | color: #fff; 87 | text-shadow: none; 88 | background-image: linear-gradient(to bottom,#08c,#0077b3); 89 | &:hover{ 90 | background-image:none; 91 | background-color: #08c; 92 | } 93 | } 94 | &>li>a { 95 | text-shadow: none; 96 | &:hover{ 97 | text-decoration: none; 98 | background-image:none; 99 | background-color: #08c; 100 | } 101 | } 102 | } 103 | 104 | .help-block, 105 | .help-inline { 106 | color: darken(@gray, 10%); 107 | } 108 | 109 | select[multiple] { 110 | background-color: inherit; 111 | color: inherit; 112 | } 113 | 114 | textarea, input[type="text"], 115 | input[type="password"], 116 | input[type="datetime"], 117 | input[type="datetime-local"], 118 | input[type="date"], 119 | input[type="month"], 120 | input[type="time"], 121 | input[type="week"], 122 | input[type="number"], 123 | input[type="email"], 124 | input[type="url"], 125 | input[type="search"], 126 | input[type="tel"], 127 | input[type="color"], 128 | .uneditable-input { 129 | border: solid #ccc; 130 | border-right-width: 0.7px; 131 | border-top-width: 0.8px; 132 | border-bottom-width: 0.8px; 133 | border-left-width: 0.7px; 134 | } 135 | 136 | .input-append .add-on, 137 | .input-prepend .add-on { 138 | color: @grayLight; 139 | .buttonBackground(darken(@gray, 5%), darken(@gray, 15%)); 140 | } 141 | 142 | .octoprint-container .tab-content h1 { 143 | color: @tabContentHeading 144 | } 145 | 146 | .table-striped tbody > tr:nth-child(odd) > td, 147 | .table-striped tbody > tr:nth-child(odd) > th { 148 | background-color: rgba(100, 100, 100, 0.1); 149 | } 150 | 151 | .table-hover tbody tr:hover td, 152 | .table-hover tbody tr:hover th, 153 | #files .gcode_files .entry:hover { 154 | background-color: rgba(100, 100, 100, 0.3); 155 | } 156 | 157 | .accordion-group { 158 | border: 1px solid @accordianGroup; 159 | } 160 | 161 | .octoprint-container .accordion-heading [class^="fa-"], 162 | .octoprint-container .accordion-heading [class*=" fa-"], 163 | .octoprint-container .accordion-heading .accordion-heading-button a { 164 | color: @almostNotWhite; 165 | } 166 | 167 | .dropdown-menu{ 168 | color: @white; 169 | #gradient > .radial(lighten(@bodyBackground, 10%), @bodyBackground); 170 | [class^="fa-"], 171 | [class*=" fa-"] { 172 | color: @white; 173 | } 174 | & li>a { 175 | color: @white; 176 | } 177 | & li>a:hover { 178 | color: @white !important; 179 | background-color: @blue; 180 | background-image: linear-gradient(to bottom,#08c,#0077b3); 181 | [class^="fa-"], 182 | [class*=" fa-"] { 183 | color: @white; 184 | } 185 | } 186 | } 187 | 188 | .nav .dropdown-toggle:hover .caret, 189 | .nav .dropdown-toggle:focus .caret { 190 | border-top-color: @white; 191 | border-bottom-color: @white; 192 | } 193 | 194 | .navbar-fixed-top .navbar-inner, 195 | .navbar-static-top .navbar-inner { 196 | border-width: 0 0 0px; 197 | } 198 | 199 | .icon-sd-black-14 { 200 | background-image: url(../../img/ic_sd_card_white_18dp_1x.png); 201 | background-image: url(../../img/ic_sd_card_white_18px.svg); 202 | background-position: 0 0px; 203 | margin-top: 1px; 204 | width: 15px; 205 | height: 17px; 206 | filter: hue-rotate(unit(hue(@almostNotWhite),deg)) saturate(saturation(@almostNotWhite)) brightness(lightness(@almostNotWhite)); 207 | transform: rotateY(180deg); 208 | } 209 | 210 | .progress { 211 | color: #eee; 212 | background-color: #444; 213 | background-image: linear-gradient(to bottom, #555, #333); 214 | -webkit-border-radius: 4px; 215 | -moz-border-radius: 4px; 216 | border-radius: 4px; 217 | } 218 | 219 | .btn { 220 | .buttonBackground(darken(@gray, 20%), darken(@gray, 30%)); 221 | color: @white; 222 | text-shadow: none; 223 | 224 | &:hover { 225 | text-shadow: none; 226 | color: darken(@white, 15%); 227 | } 228 | } 229 | 230 | .btn-primary, { 231 | .buttonBackground(@blueDark, darken(@blueDark, 10%)); 232 | text-shadow: none; 233 | } 234 | 235 | .btn-warning { 236 | .buttonBackground(lighten(@orange, 10%), @orange); 237 | text-shadow: none; 238 | } 239 | 240 | .btn-danger { 241 | .buttonBackground(lighten(@red, 10%), @red); 242 | text-shadow: none; 243 | } 244 | 245 | .btn-success { 246 | .buttonBackground(lighten(@green, 10%), @green); 247 | text-shadow: none; 248 | } 249 | 250 | .btn-info { 251 | .buttonBackground(darken(@gray, 40%), darken(@gray, 50%)); 252 | text-shadow: none; 253 | } 254 | 255 | .btn-inverse { 256 | .buttonBackground(lighten(@purple, 5%), @purple); 257 | text-shadow: none; 258 | } 259 | 260 | .btn .caret { 261 | border-top: 4px solid black; 262 | opacity: 0.3; 263 | } 264 | 265 | .btn-group > .dropdown-menu > li > a:hover { 266 | border-bottom: 0; 267 | } 268 | 269 | .btn.disabled, .btn[disabled] { 270 | color: darken(@almostNotWhite, 5); 271 | opacity: 0.65; 272 | background-color: #5c5c5c; 273 | border: 1px solid #5c5c5c; 274 | background-image: none; 275 | &:hover { 276 | color: darken(@almostNotWhite,5); 277 | cursor: not-allowed; 278 | } 279 | } 280 | 281 | .btn-group>.btn.active { 282 | z-index: 3; 283 | .buttonBackground(darken(@gray, 30%), darken(@gray, 40%)); 284 | } 285 | 286 | #job_cancel, #job_cancel:hover, #job_cancel:focus, #job_cancel:active { 287 | color: @almostNotWhite; 288 | background-color: #bd362f; 289 | background-image: linear-gradient(to bottom,#ee5f5b,#bd362f); 290 | background-repeat: repeat-x; 291 | border: 1px solid #bd362f; 292 | } 293 | 294 | #job_cancel.btn.disabled, #job_cancel.btn[disabled], #job_cancel.btn:hover[disabled] { 295 | color: @almostNotWhite; 296 | opacity: 0.65; 297 | background-color: #5c5c5c; 298 | border: 1px solid #5c5c5c; 299 | background-image: none; 300 | &:hover { 301 | color: darken(@almostNotWhite,5); 302 | cursor: not-allowed; 303 | } 304 | } 305 | 306 | .pagination ul>li>a, .pagination ul>li>span, 307 | .pagination-mini ul>li:last-child>a, 308 | .pagination-small ul>li:last-child>a, 309 | .pagination-mini ul>li:last-child>span, 310 | .pagination-small ul>li:last-child>span, 311 | .pagination-mini ul>li:first-child>a, 312 | .pagination-small ul>li:first-child>a, 313 | .pagination-mini ul>li:first-child>span, 314 | .pagination-small ul>li:first-child>span { 315 | background-color: @paginationBackground; 316 | color: @paginationActiveBackground; 317 | &:hover { 318 | color: @grayDark; 319 | background-color: @blue; 320 | } 321 | 322 | } 323 | .pagination ul>.active>a, .pagination ul>.active>span, 324 | .pagination ul>.active:first-child>a, 325 | .pagination ul>.active:first-child>span, 326 | .pagination-small ul>.active:first-child>a, 327 | .pagination-small ul>.active:first-child>span, 328 | .pagination-mini ul>.active:first-child>a, 329 | .pagination-mini ul>.active:first-child>span, 330 | .pagination ul>.active:last-child>a, 331 | .pagination ul>.active:last-child>span, 332 | .pagination-small ul>.active:last-child>a, 333 | .pagination-small ul>.active:last-child>span, 334 | .pagination-mini ul>.active:last-child>a, 335 | .pagination-mini ul>.active:last-child>span, { 336 | color: @grayDark; 337 | background-color: @blue; 338 | } 339 | 340 | #settings_dialog_content > .active canvas, 341 | #usersettings_access .controls > div > canvas { 342 | padding: 10px; 343 | background-color: white; 344 | } 345 | 346 | #settings_dialog { 347 | 348 | h1, h2, h3, h4, h5, h6 { 349 | color: @gray; 350 | } 351 | 352 | .btn-danger > [class^="icon-"], 353 | .btn-danger > [class*=" icon-"], 354 | .btn-danger > [class^="fa-"], 355 | .btn-danger > [class*=" fa-"] { 356 | color: @white; 357 | } 358 | 359 | [class^="icon-"], 360 | [class*=" icon-"], 361 | [class^="fa-"], 362 | [class*=" fa-"] { 363 | color: @almostNotWhite; 364 | &.disabled { 365 | cursor: not-allowed; 366 | 367 | } 368 | } 369 | 370 | [class*=" fa-exclamation-triangle"], 371 | [class^="icon-star"], 372 | [class*=" icon-star"], 373 | [class^="icon-key"], 374 | [class*=" icon-key"], 375 | [class^="fa-star"], 376 | [class*=" fa-star"], 377 | [class^="fa-key"], 378 | [class*=" fa-key"], { 379 | color: #ffbe00; 380 | } 381 | 382 | [class^="icon-download"], 383 | [class*=" icon-download"], 384 | [class^="fa-download"], 385 | [class*=" fa-download"] { 386 | color: lighten(@green, 10%); 387 | } 388 | 389 | [class*=" icon-trash"], 390 | [class*=" fa-trash"], 391 | [class^="icon-trash"], 392 | [class^="fa-trash"] { 393 | color: @red; 394 | } 395 | } 396 | 397 | .timelapse_files_action, 398 | .timelapse_unrendered_action { 399 | [class*=" fa-trash"], 400 | [class^="fa-trash"] { 401 | color: @red; 402 | } 403 | } 404 | 405 | .timelapse_files_action { 406 | [class^="fa-download"], 407 | [class*=" fa-download"] { 408 | color: lighten(@green, 10%); 409 | } 410 | } 411 | 412 | .timelapse_unrendered_action { 413 | [class*=" fa-video-camera"], 414 | [class^="fa-video-camera"] { 415 | color: @blue; 416 | } 417 | } 418 | 419 | #term .terminal #terminal-output, #term .terminal #terminal-output-lowfi { 420 | #gradient > .radial(lighten(@bodyBackground, 5%), @bodyBackground); 421 | color: @almostNotWhite; 422 | } 423 | .flot-text { 424 | color: @almostNotWhite !important; 425 | } 426 | 427 | // Fix for float, https://github.com/Birkbjo/OctoPrint-Themeify/issues/56 428 | .form-horizontal .control-label { 429 | padding-top: 4px; 430 | } 431 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/cyborg/mixins.less: -------------------------------------------------------------------------------- 1 | // 2 | // Mixins 3 | // -------------------------------------------------- 4 | 5 | 6 | // UTILITY MIXINS 7 | // -------------------------------------------------- 8 | 9 | // Clearfix 10 | // -------- 11 | // For clearing floats like a boss h5bp.com/q 12 | .clearfix { 13 | *zoom: 1; 14 | &:before, 15 | &:after { 16 | display: table; 17 | content: ""; 18 | // Fixes Opera/contenteditable bug: 19 | // http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952 20 | line-height: 0; 21 | } 22 | &:after { 23 | clear: both; 24 | } 25 | } 26 | 27 | // Webkit-style focus 28 | // ------------------ 29 | .tab-focus() { 30 | // Default 31 | outline: thin dotted #333; 32 | // Webkit 33 | outline: 5px auto -webkit-focus-ring-color; 34 | outline-offset: -2px; 35 | } 36 | 37 | // Center-align a block level element 38 | // ---------------------------------- 39 | .center-block() { 40 | display: block; 41 | margin-left: auto; 42 | margin-right: auto; 43 | } 44 | 45 | // IE7 inline-block 46 | // ---------------- 47 | .ie7-inline-block() { 48 | *display: inline; /* IE7 inline-block hack */ 49 | *zoom: 1; 50 | } 51 | 52 | // IE7 likes to collapse whitespace on either side of the inline-block elements. 53 | // Ems because we're attempting to match the width of a space character. Left 54 | // version is for form buttons, which typically come after other elements, and 55 | // right version is for icons, which come before. Applying both is ok, but it will 56 | // mean that space between those elements will be .6em (~2 space characters) in IE7, 57 | // instead of the 1 space in other browsers. 58 | .ie7-restore-left-whitespace() { 59 | *margin-left: .3em; 60 | 61 | &:first-child { 62 | *margin-left: 0; 63 | } 64 | } 65 | 66 | .ie7-restore-right-whitespace() { 67 | *margin-right: .3em; 68 | } 69 | 70 | // Sizing shortcuts 71 | // ------------------------- 72 | .size(@height, @width) { 73 | width: @width; 74 | height: @height; 75 | } 76 | .square(@size) { 77 | .size(@size, @size); 78 | } 79 | 80 | // Placeholder text 81 | // ------------------------- 82 | .placeholder(@color: @placeholderText) { 83 | &:-moz-placeholder { 84 | color: @color; 85 | } 86 | &:-ms-input-placeholder { 87 | color: @color; 88 | } 89 | &::-webkit-input-placeholder { 90 | color: @color; 91 | } 92 | } 93 | 94 | // Text overflow 95 | // ------------------------- 96 | // Requires inline-block or block for proper styling 97 | .text-overflow() { 98 | overflow: hidden; 99 | text-overflow: ellipsis; 100 | white-space: nowrap; 101 | } 102 | 103 | // CSS image replacement 104 | // ------------------------- 105 | // Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757 106 | .hide-text { 107 | font: 0/0 a; 108 | color: transparent; 109 | text-shadow: none; 110 | background-color: transparent; 111 | border: 0; 112 | } 113 | 114 | 115 | // FONTS 116 | // -------------------------------------------------- 117 | 118 | #font { 119 | #family { 120 | .serif() { 121 | font-family: @serifFontFamily; 122 | } 123 | .sans-serif() { 124 | font-family: @sansFontFamily; 125 | } 126 | .monospace() { 127 | font-family: @monoFontFamily; 128 | } 129 | } 130 | .shorthand(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { 131 | font-size: @size; 132 | font-weight: @weight; 133 | line-height: @lineHeight; 134 | } 135 | .serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { 136 | #font > #family > .serif; 137 | #font > .shorthand(@size, @weight, @lineHeight); 138 | } 139 | .sans-serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { 140 | #font > #family > .sans-serif; 141 | #font > .shorthand(@size, @weight, @lineHeight); 142 | } 143 | .monospace(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) { 144 | #font > #family > .monospace; 145 | #font > .shorthand(@size, @weight, @lineHeight); 146 | } 147 | } 148 | 149 | 150 | // FORMS 151 | // -------------------------------------------------- 152 | 153 | // Block level inputs 154 | .input-block-level { 155 | display: block; 156 | width: 100%; 157 | min-height: @inputHeight; // Make inputs at least the height of their button counterpart (base line-height + padding + border) 158 | .box-sizing(border-box); // Makes inputs behave like true block-level elements 159 | } 160 | 161 | 162 | 163 | // Mixin for form field states 164 | .formFieldState(@textColor: #555, @borderColor: #ccc, @backgroundColor: #f5f5f5) { 165 | // Set the text color 166 | .control-label, 167 | .help-block, 168 | .help-inline { 169 | color: @textColor; 170 | } 171 | // Style inputs accordingly 172 | .checkbox, 173 | .radio, 174 | input, 175 | select, 176 | textarea { 177 | color: @textColor; 178 | } 179 | input, 180 | select, 181 | textarea { 182 | border-color: @borderColor; 183 | .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work 184 | &:focus { 185 | border-color: darken(@borderColor, 10%); 186 | @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@borderColor, 20%); 187 | .box-shadow(@shadow); 188 | } 189 | } 190 | // Give a small background color for input-prepend/-append 191 | .input-prepend .add-on, 192 | .input-append .add-on { 193 | color: @textColor; 194 | background-color: @backgroundColor; 195 | border-color: @textColor; 196 | } 197 | } 198 | 199 | 200 | 201 | // CSS3 PROPERTIES 202 | // -------------------------------------------------- 203 | 204 | // Border Radius 205 | .border-radius(@radius) { 206 | -webkit-border-radius: @radius; 207 | -moz-border-radius: @radius; 208 | border-radius: @radius; 209 | } 210 | 211 | // Single Corner Border Radius 212 | .border-top-left-radius(@radius) { 213 | -webkit-border-top-left-radius: @radius; 214 | -moz-border-radius-topleft: @radius; 215 | border-top-left-radius: @radius; 216 | } 217 | .border-top-right-radius(@radius) { 218 | -webkit-border-top-right-radius: @radius; 219 | -moz-border-radius-topright: @radius; 220 | border-top-right-radius: @radius; 221 | } 222 | .border-bottom-right-radius(@radius) { 223 | -webkit-border-bottom-right-radius: @radius; 224 | -moz-border-radius-bottomright: @radius; 225 | border-bottom-right-radius: @radius; 226 | } 227 | .border-bottom-left-radius(@radius) { 228 | -webkit-border-bottom-left-radius: @radius; 229 | -moz-border-radius-bottomleft: @radius; 230 | border-bottom-left-radius: @radius; 231 | } 232 | 233 | // Single Side Border Radius 234 | .border-top-radius(@radius) { 235 | .border-top-right-radius(@radius); 236 | .border-top-left-radius(@radius); 237 | } 238 | .border-right-radius(@radius) { 239 | .border-top-right-radius(@radius); 240 | .border-bottom-right-radius(@radius); 241 | } 242 | .border-bottom-radius(@radius) { 243 | .border-bottom-right-radius(@radius); 244 | .border-bottom-left-radius(@radius); 245 | } 246 | .border-left-radius(@radius) { 247 | .border-top-left-radius(@radius); 248 | .border-bottom-left-radius(@radius); 249 | } 250 | 251 | // Drop shadows 252 | .box-shadow(@shadow) { 253 | -webkit-box-shadow: @shadow; 254 | -moz-box-shadow: @shadow; 255 | box-shadow: @shadow; 256 | } 257 | 258 | // Transitions 259 | .transition(@transition) { 260 | -webkit-transition: @transition; 261 | -moz-transition: @transition; 262 | -o-transition: @transition; 263 | transition: @transition; 264 | } 265 | .transition-delay(@transition-delay) { 266 | -webkit-transition-delay: @transition-delay; 267 | -moz-transition-delay: @transition-delay; 268 | -o-transition-delay: @transition-delay; 269 | transition-delay: @transition-delay; 270 | } 271 | .transition-duration(@transition-duration) { 272 | -webkit-transition-duration: @transition-duration; 273 | -moz-transition-duration: @transition-duration; 274 | -o-transition-duration: @transition-duration; 275 | transition-duration: @transition-duration; 276 | } 277 | 278 | // Transformations 279 | .rotate(@degrees) { 280 | -webkit-transform: rotate(@degrees); 281 | -moz-transform: rotate(@degrees); 282 | -ms-transform: rotate(@degrees); 283 | -o-transform: rotate(@degrees); 284 | transform: rotate(@degrees); 285 | } 286 | .scale(@ratio) { 287 | -webkit-transform: scale(@ratio); 288 | -moz-transform: scale(@ratio); 289 | -ms-transform: scale(@ratio); 290 | -o-transform: scale(@ratio); 291 | transform: scale(@ratio); 292 | } 293 | .translate(@x, @y) { 294 | -webkit-transform: translate(@x, @y); 295 | -moz-transform: translate(@x, @y); 296 | -ms-transform: translate(@x, @y); 297 | -o-transform: translate(@x, @y); 298 | transform: translate(@x, @y); 299 | } 300 | .skew(@x, @y) { 301 | -webkit-transform: skew(@x, @y); 302 | -moz-transform: skew(@x, @y); 303 | -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twitter/bootstrap/issues/4885 304 | -o-transform: skew(@x, @y); 305 | transform: skew(@x, @y); 306 | -webkit-backface-visibility: hidden; // See https://github.com/twitter/bootstrap/issues/5319 307 | } 308 | .translate3d(@x, @y, @z) { 309 | -webkit-transform: translate3d(@x, @y, @z); 310 | -moz-transform: translate3d(@x, @y, @z); 311 | -o-transform: translate3d(@x, @y, @z); 312 | transform: translate3d(@x, @y, @z); 313 | } 314 | 315 | // Backface visibility 316 | // Prevent browsers from flickering when using CSS 3D transforms. 317 | // Default value is `visible`, but can be changed to `hidden 318 | // See git pull https://github.com/dannykeane/bootstrap.git backface-visibility for examples 319 | .backface-visibility(@visibility){ 320 | -webkit-backface-visibility: @visibility; 321 | -moz-backface-visibility: @visibility; 322 | backface-visibility: @visibility; 323 | } 324 | 325 | // Background clipping 326 | // Heads up: FF 3.6 and under need "padding" instead of "padding-box" 327 | .background-clip(@clip) { 328 | -webkit-background-clip: @clip; 329 | -moz-background-clip: @clip; 330 | background-clip: @clip; 331 | } 332 | 333 | // Background sizing 334 | .background-size(@size) { 335 | -webkit-background-size: @size; 336 | -moz-background-size: @size; 337 | -o-background-size: @size; 338 | background-size: @size; 339 | } 340 | 341 | 342 | // Box sizing 343 | .box-sizing(@boxmodel) { 344 | -webkit-box-sizing: @boxmodel; 345 | -moz-box-sizing: @boxmodel; 346 | box-sizing: @boxmodel; 347 | } 348 | 349 | // User select 350 | // For selecting text on the page 351 | .user-select(@select) { 352 | -webkit-user-select: @select; 353 | -moz-user-select: @select; 354 | -ms-user-select: @select; 355 | -o-user-select: @select; 356 | user-select: @select; 357 | } 358 | 359 | // Resize anything 360 | .resizable(@direction) { 361 | resize: @direction; // Options: horizontal, vertical, both 362 | overflow: auto; // Safari fix 363 | } 364 | 365 | // CSS3 Content Columns 366 | .content-columns(@columnCount, @columnGap: @gridGutterWidth) { 367 | -webkit-column-count: @columnCount; 368 | -moz-column-count: @columnCount; 369 | column-count: @columnCount; 370 | -webkit-column-gap: @columnGap; 371 | -moz-column-gap: @columnGap; 372 | column-gap: @columnGap; 373 | } 374 | 375 | // Optional hyphenation 376 | .hyphens(@mode: auto) { 377 | word-wrap: break-word; 378 | -webkit-hyphens: @mode; 379 | -moz-hyphens: @mode; 380 | -ms-hyphens: @mode; 381 | -o-hyphens: @mode; 382 | hyphens: @mode; 383 | } 384 | 385 | // Opacity 386 | .opacity(@opacity) { 387 | opacity: @opacity / 100; 388 | filter: ~"alpha(opacity=@{opacity})"; 389 | } 390 | 391 | 392 | 393 | // BACKGROUNDS 394 | // -------------------------------------------------- 395 | 396 | // Add an alphatransparency value to any background or border color (via Elyse Holladay) 397 | #translucent { 398 | .background(@color: @white, @alpha: 1) { 399 | background-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha); 400 | } 401 | .border(@color: @white, @alpha: 1) { 402 | border-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha); 403 | .background-clip(padding-box); 404 | } 405 | } 406 | 407 | // Gradient Bar Colors for buttons and alerts 408 | .gradientBar(@primaryColor, @secondaryColor, @textColor: #fff, @textShadow: 0 -1px 0 rgba(0,0,0,.25)) { 409 | color: @textColor; 410 | text-shadow: @textShadow; 411 | #gradient > .vertical(@primaryColor, @secondaryColor); 412 | border-color: @secondaryColor @secondaryColor darken(@secondaryColor, 15%); 413 | border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) fadein(rgba(0,0,0,.1), 15%); 414 | } 415 | 416 | // Gradients 417 | #gradient { 418 | .horizontal(@startColor: #555, @endColor: #333) { 419 | background-color: @endColor; 420 | background-image: -moz-linear-gradient(left, @startColor, @endColor); // FF 3.6+ 421 | background-image: -webkit-gradient(linear, 0 0, 100% 0, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+ 422 | background-image: -webkit-linear-gradient(left, @startColor, @endColor); // Safari 5.1+, Chrome 10+ 423 | background-image: -o-linear-gradient(left, @startColor, @endColor); // Opera 11.10 424 | background-image: linear-gradient(to right, @startColor, @endColor); // Standard, IE10 425 | background-repeat: repeat-x; 426 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@startColor),argb(@endColor))); // IE9 and down 427 | } 428 | .vertical(@startColor: #555, @endColor: #333) { 429 | background-color: mix(@startColor, @endColor, 60%); 430 | background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+ 431 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+ 432 | background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+ 433 | background-image: -o-linear-gradient(top, @startColor, @endColor); // Opera 11.10 434 | background-image: linear-gradient(to bottom, @startColor, @endColor); // Standard, IE10 435 | background-repeat: repeat-x; 436 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down 437 | } 438 | .directional(@startColor: #555, @endColor: #333, @deg: 45deg) { 439 | background-color: @endColor; 440 | background-repeat: repeat-x; 441 | background-image: -moz-linear-gradient(@deg, @startColor, @endColor); // FF 3.6+ 442 | background-image: -webkit-linear-gradient(@deg, @startColor, @endColor); // Safari 5.1+, Chrome 10+ 443 | background-image: -o-linear-gradient(@deg, @startColor, @endColor); // Opera 11.10 444 | background-image: linear-gradient(@deg, @startColor, @endColor); // Standard, IE10 445 | } 446 | .horizontal-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) { 447 | background-color: mix(@midColor, @endColor, 80%); 448 | background-image: -webkit-gradient(left, linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor)); 449 | background-image: -webkit-linear-gradient(left, @startColor, @midColor @colorStop, @endColor); 450 | background-image: -moz-linear-gradient(left, @startColor, @midColor @colorStop, @endColor); 451 | background-image: -o-linear-gradient(left, @startColor, @midColor @colorStop, @endColor); 452 | background-image: linear-gradient(to right, @startColor, @midColor @colorStop, @endColor); 453 | background-repeat: no-repeat; 454 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down, gets no color-stop at all for proper fallback 455 | } 456 | 457 | .vertical-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) { 458 | background-color: mix(@midColor, @endColor, 80%); 459 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor)); 460 | background-image: -webkit-linear-gradient(@startColor, @midColor @colorStop, @endColor); 461 | background-image: -moz-linear-gradient(top, @startColor, @midColor @colorStop, @endColor); 462 | background-image: -o-linear-gradient(@startColor, @midColor @colorStop, @endColor); 463 | background-image: linear-gradient(@startColor, @midColor @colorStop, @endColor); 464 | background-repeat: no-repeat; 465 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down, gets no color-stop at all for proper fallback 466 | } 467 | .radial(@innerColor: #555, @outerColor: #333) { 468 | background-color: @outerColor; 469 | background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(@innerColor), to(@outerColor)); 470 | background-image: -webkit-radial-gradient(circle, @innerColor, @outerColor); 471 | background-image: -moz-radial-gradient(circle, @innerColor, @outerColor); 472 | background-image: -o-radial-gradient(circle, @innerColor, @outerColor); 473 | background-repeat: no-repeat; 474 | } 475 | .striped(@color: #555, @angle: 45deg) { 476 | background-color: @color; 477 | background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent)); 478 | background-image: -webkit-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); 479 | background-image: -moz-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); 480 | background-image: -o-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); 481 | background-image: linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); 482 | } 483 | } 484 | // Reset filters for IE 485 | .reset-filter() { 486 | filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)")); 487 | } 488 | 489 | 490 | 491 | // COMPONENT MIXINS 492 | // -------------------------------------------------- 493 | 494 | // Horizontal dividers 495 | // ------------------------- 496 | // Dividers (basically an hr) within dropdowns and nav lists 497 | .nav-divider(@top: #e5e5e5, @bottom: @white) { 498 | // IE7 needs a set width since we gave a height. Restricting just 499 | // to IE7 to keep the 1px left/right space in other browsers. 500 | // It is unclear where IE is getting the extra space that we need 501 | // to negative-margin away, but so it goes. 502 | *width: 100%; 503 | height: 1px; 504 | margin: ((@baseLineHeight / 2) - 1) 1px; // 8px 1px 505 | *margin: -5px 0 5px; 506 | overflow: hidden; 507 | background-color: @top; 508 | border-bottom: 1px solid @bottom; 509 | } 510 | 511 | // Button backgrounds 512 | // ------------------ 513 | .buttonBackground(@startColor, @endColor, @textColor: #fff, @textShadow: 0 -1px 0 rgba(0,0,0,.25)) { 514 | // gradientBar will set the background to a pleasing blend of these, to support IE<=9 515 | .gradientBar(@startColor, @endColor, @textColor, @textShadow); 516 | *background-color: @endColor; /* Darken IE7 buttons by default so they stand out more given they won't have borders */ 517 | .reset-filter(); 518 | 519 | // in these cases the gradient won't cover the background, so we override 520 | &:hover, &:focus, &:active, &.active, &.disabled, &[disabled] { 521 | color: @textColor; 522 | background-color: @endColor; 523 | *background-color: darken(@endColor, 5%); 524 | } 525 | 526 | // IE 7 + 8 can't handle box-shadow to show active, so we darken a bit ourselves 527 | &:active, 528 | &.active { 529 | background-color: darken(@endColor, 10%) e("\9"); 530 | } 531 | } 532 | 533 | // Navbar vertical align 534 | // ------------------------- 535 | // Vertically center elements in the navbar. 536 | // Example: an element has a height of 30px, so write out `.navbarVerticalAlign(30px);` to calculate the appropriate top margin. 537 | .navbarVerticalAlign(@elementHeight) { 538 | margin-top: (@navbarHeight - @elementHeight) / 2; 539 | } 540 | 541 | 542 | 543 | // Grid System 544 | // ----------- 545 | 546 | // Centered container element 547 | .container-fixed() { 548 | margin-right: auto; 549 | margin-left: auto; 550 | .clearfix(); 551 | } 552 | 553 | // Table columns 554 | .tableColumns(@columnSpan: 1) { 555 | float: none; // undo default grid column styles 556 | width: ((@gridColumnWidth) * @columnSpan) + (@gridGutterWidth * (@columnSpan - 1)) - 16; // 16 is total padding on left and right of table cells 557 | margin-left: 0; // undo default grid column styles 558 | } 559 | 560 | // Make a Grid 561 | // Use .makeRow and .makeColumn to assign semantic layouts grid system behavior 562 | .makeRow() { 563 | margin-left: @gridGutterWidth * -1; 564 | .clearfix(); 565 | } 566 | .makeColumn(@columns: 1, @offset: 0) { 567 | float: left; 568 | margin-left: (@gridColumnWidth * @offset) + (@gridGutterWidth * (@offset - 1)) + (@gridGutterWidth * 2); 569 | width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1)); 570 | } 571 | 572 | // The Grid 573 | #grid { 574 | 575 | .core (@gridColumnWidth, @gridGutterWidth) { 576 | 577 | .spanX (@index) when (@index > 0) { 578 | .span@{index} { .span(@index); } 579 | .spanX(@index - 1); 580 | } 581 | .spanX (0) {} 582 | 583 | .offsetX (@index) when (@index > 0) { 584 | .offset@{index} { .offset(@index); } 585 | .offsetX(@index - 1); 586 | } 587 | .offsetX (0) {} 588 | 589 | .offset (@columns) { 590 | margin-left: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns + 1)); 591 | } 592 | 593 | .span (@columns) { 594 | width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1)); 595 | } 596 | 597 | .row { 598 | margin-left: @gridGutterWidth * -1; 599 | .clearfix(); 600 | } 601 | 602 | [class*="span"] { 603 | float: left; 604 | min-height: 1px; // prevent collapsing columns 605 | margin-left: @gridGutterWidth; 606 | } 607 | 608 | // Set the container width, and override it for fixed navbars in media queries 609 | .container, 610 | .navbar-static-top .container, 611 | .navbar-fixed-top .container, 612 | .navbar-fixed-bottom .container { .span(@gridColumns); } 613 | 614 | // generate .spanX and .offsetX 615 | .spanX (@gridColumns); 616 | .offsetX (@gridColumns); 617 | 618 | } 619 | 620 | .fluid (@fluidGridColumnWidth, @fluidGridGutterWidth) { 621 | 622 | .spanX (@index) when (@index > 0) { 623 | .span@{index} { .span(@index); } 624 | .spanX(@index - 1); 625 | } 626 | .spanX (0) {} 627 | 628 | .offsetX (@index) when (@index > 0) { 629 | .offset@{index} { .offset(@index); } 630 | .offset@{index}:first-child { .offsetFirstChild(@index); } 631 | .offsetX(@index - 1); 632 | } 633 | .offsetX (0) {} 634 | 635 | .offset (@columns) { 636 | margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth*2); 637 | *margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + (@fluidGridGutterWidth*2) - (.5 / @gridRowWidth * 100 * 1%); 638 | } 639 | 640 | .offsetFirstChild (@columns) { 641 | margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) + (@fluidGridGutterWidth); 642 | *margin-left: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%) + @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%); 643 | } 644 | 645 | .span (@columns) { 646 | width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)); 647 | *width: (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1)) - (.5 / @gridRowWidth * 100 * 1%); 648 | } 649 | 650 | .row-fluid { 651 | width: 100%; 652 | .clearfix(); 653 | [class*="span"] { 654 | .input-block-level(); 655 | float: left; 656 | margin-left: @fluidGridGutterWidth; 657 | *margin-left: @fluidGridGutterWidth - (.5 / @gridRowWidth * 100 * 1%); 658 | } 659 | [class*="span"]:first-child { 660 | margin-left: 0; 661 | } 662 | 663 | // Space grid-sized controls properly if multiple per line 664 | .controls-row [class*="span"] + [class*="span"] { 665 | margin-left: @fluidGridGutterWidth; 666 | } 667 | 668 | // generate .spanX and .offsetX 669 | .spanX (@gridColumns); 670 | .offsetX (@gridColumns); 671 | } 672 | 673 | } 674 | 675 | .input(@gridColumnWidth, @gridGutterWidth) { 676 | 677 | .spanX (@index) when (@index > 0) { 678 | input.span@{index}, textarea.span@{index}, .uneditable-input.span@{index} { .span(@index); } 679 | .spanX(@index - 1); 680 | } 681 | .spanX (0) {} 682 | 683 | .span(@columns) { 684 | width: ((@gridColumnWidth) * @columns) + (@gridGutterWidth * (@columns - 1)) - 14; 685 | } 686 | 687 | input, 688 | textarea, 689 | .uneditable-input { 690 | margin-left: 0; // override margin-left from core grid system 691 | } 692 | 693 | // Space grid-sized controls properly if multiple per line 694 | .controls-row [class*="span"] + [class*="span"] { 695 | margin-left: @gridGutterWidth; 696 | } 697 | 698 | // generate .spanX 699 | .spanX (@gridColumns); 700 | 701 | } 702 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/cyborg/variables.less: -------------------------------------------------------------------------------- 1 | // Cyborg 2.3.2 2 | // Variables 3 | // -------------------------------------------------- 4 | 5 | 6 | // Global values 7 | // -------------------------------------------------- 8 | 9 | //OctoPrint specific 10 | //--------------------------------------------------- 11 | @tabContentHeading: #adafae; 12 | @accordianGroup: #e5e5e5; 13 | @almostNotWhite: #ccc; 14 | @reallyRed: #f00; 15 | @fileMenuText: #333; 16 | 17 | // Grays 18 | // ------------------------- 19 | @black: #000; 20 | @grayDarker: #020202; 21 | @grayDark: #222; 22 | @gray: #999; 23 | @grayLight: #ADAFAE; 24 | @grayLighter: #eee; 25 | @white: #fff; 26 | 27 | 28 | // Accent colors 29 | // ------------------------- 30 | @blue: #33B5E5; 31 | @blueDark: #0099CC; 32 | @green: #669900; 33 | @red: #CC0000; 34 | @yellow: #ECBB13; 35 | @orange: #FF8800; 36 | @pink: #FF4444; 37 | @purple: #9933CC; 38 | 39 | 40 | // Scaffolding 41 | // ------------------------- 42 | @bodyBackground: #060606; 43 | @textColor: @gray; 44 | 45 | 46 | // Links 47 | // ------------------------- 48 | @linkColor: @blue; 49 | @linkColorHover: @white; 50 | 51 | 52 | // Typography 53 | // ------------------------- 54 | @sansFontFamily: 'Droid Sans', sans-serif; 55 | @serifFontFamily: Georgia, "Times New Roman", Times, serif; 56 | @monoFontFamily: Menlo, Monaco, Consolas, "Courier New", monospace; 57 | 58 | @baseFontSize: 14px; 59 | @baseFontFamily: @sansFontFamily; 60 | @baseLineHeight: 20px; 61 | @altFontFamily: @serifFontFamily; 62 | 63 | @headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily 64 | @headingsFontWeight: normal; // instead of browser default, bold 65 | @headingsColor: @white; // empty to use BS default, @textColor 66 | 67 | 68 | // Component sizing 69 | // ------------------------- 70 | // Based on 14px font-size and 20px line-height 71 | 72 | @fontSizeLarge: @baseFontSize * 1.25; // ~18px 73 | @fontSizeSmall: @baseFontSize * 0.85; // ~12px 74 | @fontSizeMini: @baseFontSize * 0.75; // ~11px 75 | 76 | @paddingLarge: 11px 19px; // 44px 77 | @paddingSmall: 2px 10px; // 26px 78 | @paddingMini: 0px 6px; // 22px 79 | 80 | @baseBorderRadius: 4px; 81 | @borderRadiusLarge: 6px; 82 | @borderRadiusSmall: 3px; 83 | 84 | 85 | // Tables 86 | // ------------------------- 87 | @tableBackground: transparent; // overall background-color 88 | @tableBackgroundAccent: rgba(100, 100, 100, 0.1); // for striping 89 | @tableBackgroundHover: @grayDark; // for hover 90 | @tableBorder: @grayDark; // table and cell border 91 | 92 | // Buttons 93 | // ------------------------- 94 | @btnBackground: darken(@gray, 20%); 95 | @btnBackgroundHighlight: darken(@gray, 25%); 96 | @btnBorder: rgba(0, 0, 0, 0); 97 | 98 | @btnPrimaryBackground: @blueDark; 99 | @btnPrimaryBackgroundHighlight: darken(@blueDark, 10%); 100 | 101 | @btnInfoBackground: darken(@gray, 40%); 102 | @btnInfoBackgroundHighlight: darken(@gray, 50%); 103 | 104 | @btnSuccessBackground: lighten(@green, 10%); 105 | @btnSuccessBackgroundHighlight: @green; 106 | 107 | @btnWarningBackground: lighten(@orange, 15%); 108 | @btnWarningBackgroundHighlight: @orange; 109 | 110 | @btnDangerBackground: lighten(@red, 10%); 111 | @btnDangerBackgroundHighlight: @red; 112 | 113 | @btnInverseBackground: lighten(@purple, 5%); 114 | @btnInverseBackgroundHighlight: @purple; 115 | 116 | 117 | // Forms 118 | // ------------------------- 119 | @inputBackground: #ccc; 120 | @inputBorder: #bbb; 121 | @inputBorderRadius: @baseBorderRadius; 122 | @inputDisabledBackground: #555; 123 | @formActionsBackground: transparent; 124 | @inputHeight: @baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border 125 | 126 | 127 | // Dropdowns 128 | // ------------------------- 129 | @dropdownBackground: #131517; 130 | @dropdownBorder: rgba(0,0,0,.2); 131 | @dropdownDividerTop: transparent; 132 | @dropdownDividerBottom: #222; 133 | 134 | @dropdownLinkColor: @textColor; 135 | @dropdownLinkColorHover: @white; 136 | @dropdownLinkColorActive: @white; 137 | 138 | @dropdownLinkBackgroundActive: @linkColor; 139 | @dropdownLinkBackgroundHover: @linkColor; 140 | 141 | 142 | 143 | // COMPONENT VARIABLES 144 | // -------------------------------------------------- 145 | 146 | 147 | // Z-index master list 148 | // ------------------------- 149 | // Used for a bird's eye view of components dependent on the z-axis 150 | // Try to avoid customizing these :) 151 | @zindexDropdown: 1000; 152 | @zindexPopover: 1010; 153 | @zindexTooltip: 1020; 154 | @zindexFixedNavbar: 1030; 155 | @zindexModalBackdrop: 1040; 156 | @zindexModal: 1050; 157 | 158 | 159 | // Sprite icons path 160 | // ------------------------- 161 | @iconSpritePath: "../img/glyphicons-halflings.png"; 162 | @iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; 163 | 164 | 165 | // Input placeholder text color 166 | // ------------------------- 167 | @placeholderText: @grayLight; 168 | 169 | 170 | // Hr border color 171 | // ------------------------- 172 | @hrBorder: @grayDark; 173 | 174 | 175 | // Horizontal forms & lists 176 | // ------------------------- 177 | @horizontalComponentOffset: 180px; 178 | 179 | 180 | // Wells 181 | // ------------------------- 182 | @wellBackground: #131517; 183 | 184 | 185 | // Navbar 186 | // ------------------------- 187 | @navbarCollapseWidth: 979px; 188 | @navbarCollapseDesktopWidth: @navbarCollapseWidth + 1; 189 | 190 | @navbarHeight: 50px; 191 | @navbarBackgroundHighlight: @grayDarker; 192 | @navbarBackground: @grayDarker; 193 | @navbarBorder: darken(@navbarBackground, 12%); 194 | 195 | @navbarText: @grayLight; 196 | @navbarLinkColor: @grayLight; 197 | @navbarLinkColorHover: @white; 198 | @navbarLinkColorActive: @navbarLinkColorHover; 199 | @navbarLinkBackgroundHover: transparent; 200 | @navbarLinkBackgroundActive: @navbarBackground; 201 | 202 | @navbarBrandColor: @navbarLinkColor; 203 | 204 | // Inverted navbar 205 | @navbarInverseBackground: #252A30; 206 | @navbarInverseBackgroundHighlight: #252A30; 207 | @navbarInverseBorder: transparent; 208 | 209 | @navbarInverseText: @grayLight; 210 | @navbarInverseLinkColor: @grayLight; 211 | @navbarInverseLinkColorHover: @white; 212 | @navbarInverseLinkColorActive: @navbarInverseLinkColorHover; 213 | @navbarInverseLinkBackgroundHover: #242A31; 214 | @navbarInverseLinkBackgroundActive: @navbarInverseLinkBackgroundHover; 215 | 216 | @navbarInverseSearchBackground: lighten(@navbarInverseBackground, 25%); 217 | @navbarInverseSearchBackgroundFocus: @white; 218 | @navbarInverseSearchBorder: @navbarInverseBackground; 219 | @navbarInverseSearchPlaceholderColor: @white; 220 | 221 | @navbarInverseBrandColor: @navbarInverseLinkColor; 222 | 223 | 224 | // Pagination 225 | // ------------------------- 226 | @paginationBackground: @bodyBackground; 227 | @paginationBorder: transparent; 228 | @paginationActiveBackground: @blue; 229 | 230 | 231 | // Hero unit 232 | // ------------------------- 233 | @heroUnitBackground: #131517; 234 | @heroUnitHeadingColor: inherit; 235 | @heroUnitLeadColor: inherit; 236 | 237 | 238 | // Form states and alerts 239 | // ------------------------- 240 | @warningText: darken(#c09853, 10%); 241 | @warningBackground: @grayLighter; 242 | @warningBorder: transparent; 243 | 244 | @errorText: #b94a48; 245 | @errorBackground: @grayLighter; 246 | @errorBorder: darken(spin(@errorBackground, -10), 3%); 247 | 248 | @successText: #468847; 249 | @successBackground: @grayLighter; 250 | @successBorder: darken(spin(@successBackground, -10), 5%); 251 | 252 | @infoText: @blueDark; 253 | @infoBackground: @grayLighter; 254 | @infoBorder: darken(spin(@infoBackground, -10), 7%); 255 | 256 | 257 | // Tooltips and popovers 258 | // ------------------------- 259 | @tooltipColor: #fff; 260 | @tooltipBackground: @heroUnitBackground; 261 | @tooltipArrowWidth: 5px; 262 | @tooltipArrowColor: @tooltipBackground; 263 | 264 | @popoverBackground: @heroUnitBackground; 265 | @popoverArrowWidth: 10px; 266 | @popoverArrowColor: @popoverBackground; 267 | @popoverTitleBackground: @popoverBackground; 268 | 269 | // Special enhancement for popovers 270 | @popoverArrowOuterWidth: @popoverArrowWidth + 1; 271 | @popoverArrowOuterColor: rgba(0,0,0,.25); 272 | 273 | 274 | 275 | // GRID 276 | // -------------------------------------------------- 277 | 278 | 279 | // Default 940px grid 280 | // ------------------------- 281 | @gridColumns: 12; 282 | @gridColumnWidth: 60px; 283 | @gridGutterWidth: 20px; 284 | @gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); 285 | 286 | // 1200px min 287 | @gridColumnWidth1200: 70px; 288 | @gridGutterWidth1200: 30px; 289 | @gridRowWidth1200: (@gridColumns * @gridColumnWidth1200) + (@gridGutterWidth1200 * (@gridColumns - 1)); 290 | 291 | // 768px-979px 292 | @gridColumnWidth768: 42px; 293 | @gridGutterWidth768: 20px; 294 | @gridRowWidth768: (@gridColumns * @gridColumnWidth768) + (@gridGutterWidth768 * (@gridColumns - 1)); 295 | 296 | 297 | // Fluid grid 298 | // ------------------------- 299 | @fluidGridColumnWidth: percentage(@gridColumnWidth/@gridRowWidth); 300 | @fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth); 301 | 302 | // 1200px min 303 | @fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200); 304 | @fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200); 305 | 306 | // 768px-979px 307 | @fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768); 308 | @fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768); -------------------------------------------------------------------------------- /octoprint_themeify/static/less/discoranged/discoranged.less: -------------------------------------------------------------------------------- 1 | @import "variables.less"; 2 | 3 | @highlighter: lighten(@notquiteBlack,10); 4 | 5 | .discoranged() { 6 | body { 7 | background-color: @darkish; 8 | color: @notquiteWhite; 9 | font-weight: 400; 10 | } 11 | 12 | a { 13 | color: @greyple; 14 | } 15 | 16 | a:hover { 17 | color: lighten(@greyple, 20) 18 | } 19 | 20 | .octoprint-container .tab-content h1 { 21 | color: #FFFFFF; 22 | } 23 | 24 | .octoprint-container .tab-content { 25 | border: none @notquiteBlack; 26 | background-color: @notquiteBlack; 27 | -webkit-box-shadow: 1px 1px 2px 0 rgba(0,0,0,0.75); 28 | -moz-box-shadow: 1px 1px 2px 0 rgba(0,0,0,0.75); 29 | box-shadow: 1px 1px 2px 0 rgba(0,0,0,0.75); 30 | padding: 20px 15px; 31 | } 32 | 33 | .accordion-group { 34 | border: none; 35 | } 36 | 37 | .accordion { 38 | background-color: @notquiteBlack; 39 | -webkit-box-shadow: 1px 1px 2px 0 rgba(0,0,0,0.75); 40 | -moz-box-shadow: 1px 1px 2px 0 rgba(0,0,0,0.75); 41 | box-shadow: 1px 1px 2px 0 rgba(0,0,0,0.75); 42 | } 43 | 44 | .octoprint-container .accordion-heading a.accordion-toggle { 45 | color: @orange; 46 | &:hover, &:focus, &:active { 47 | color: darken(@orange, 8); 48 | text-decoration: none; 49 | } 50 | 51 | } 52 | 53 | .octoprint-container .accordion-heading .accordion-heading-button a { 54 | color: inherit; 55 | } 56 | 57 | .nav-tabs { 58 | border: 1px solid @darkish; 59 | } 60 | 61 | .nav-tabs>li>a { 62 | -webkit-border-radius: 0; 63 | border-radius: 0; 64 | } 65 | 66 | .nav-tabs>.active>a, .nav-tabs>.active>a:hover { 67 | background-color: @notquiteBlack; 68 | color: @orange; 69 | border: 1px solid @notquiteBlack; 70 | border-right: 1px solid #000; 71 | } 72 | .nav-pills>.active>a, .nav-pills>.active>a:hover { 73 | background-color: @orange; 74 | } 75 | 76 | .nav-tabs>li>a:hover { 77 | background-color: lighten(@notquiteBlack, 10); 78 | border: 1px solid @darkish; 79 | color: @orange; 80 | } 81 | 82 | h1, h2, h3, h4 { 83 | color: @orange 84 | } 85 | 86 | .btn { 87 | border-radius: 3px; 88 | background-image: none; 89 | border: none; 90 | box-shadow: none; 91 | background-color: @darkish; 92 | color: #fff; 93 | font-weight: 400; 94 | text-shadow: none; 95 | outline: none; 96 | &:hover { 97 | color: #fff; 98 | background-color: @highlighter; 99 | } 100 | &:focus { 101 | // border-color: rgba(255,255,255,0.7); 102 | background-color: @highlighter; 103 | // box-shadow: none; 104 | // outline-color: @notquiteWhite; 105 | // outline-width: 2px; 106 | color: #fff; 107 | } 108 | &:active { 109 | // box-shadow: none; 110 | background-color: lighten(@highlighter, 10) 111 | // outline: 0; 112 | } 113 | } 114 | .btn.active { 115 | background-color: lighten(@highlighter, 10); 116 | // border: 1px solid rgba(255,255,255,0.85); 117 | color: #fff; 118 | } 119 | .btn .btn-primary, .btn-primary[disabled] { 120 | background-color: @orange; 121 | } 122 | .btn-primary { 123 | background-color: @orange; 124 | border: none; 125 | &:hover { 126 | background-color: darken(@orange, 5); 127 | } 128 | &:active, &:focus { 129 | background-color: darken(@orange, 8); 130 | } 131 | &.disabled, &[disabled] { 132 | background-color: darken(@orange, 5); 133 | } 134 | } 135 | .btn-group.open .btn-primary.dropdown-toggle { 136 | box-shadow: none; 137 | background-color: darken(@orange, 10); 138 | } 139 | .btn-group.open .btn.dropdown-toggle { 140 | background: @darkish; 141 | &:active, &:focus { 142 | background: @darkish; 143 | color: #fff; 144 | } 145 | } 146 | .btn.disabled, .btn[disabled] { 147 | background-color: darken(@lighterish,5); 148 | color: darken(@notquiteWhite, 5); 149 | &:hover { 150 | color: darken(@notquiteWhite,5); 151 | } 152 | } 153 | .btn-danger { 154 | background-color: #f00; 155 | &:active, &:focus, &:hover { 156 | background-color: darken(#f00, 8); 157 | } 158 | } 159 | 160 | select, textarea, input[type="search"], input[type="text"], input[type="number"], .input-append .add-on, textarea, input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input { 161 | background-color: @lighterish; 162 | border:none; 163 | color: lighten(@notquiteWhite,5); 164 | text-shadow: none; 165 | padding-bottom: 6px; 166 | } 167 | 168 | textarea:focus, input[type="text"]:focus, input[type="password"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="date"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="week"]:focus, input[type="number"]:focus, input[type="email"]:focus, input[type="url"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="color"]:focus, .uneditable-input:focus { 169 | box-shadow: inset 0 1px 1px rgba(255,255,255,0.075), 0 0 8px rgba(255,255,255,0.5) 170 | } 171 | .input-append .add-on, .input-prepend .add-on { 172 | padding-bottom: 6px; 173 | } 174 | //upload archive field 175 | .input-prepend .add-on.add-on-limited { 176 | background-color: @lighterish; 177 | color: lighten(@notquiteWhite, 5); 178 | border: none; 179 | text-shadow: none; 180 | } 181 | 182 | .slider .slider-selection { 183 | background-image: none; 184 | background-color: @orange; 185 | border-color: darken(@orange, 5); 186 | &:hover, &:active { 187 | background-color: @orange; 188 | } 189 | } 190 | 191 | .slider .slider-handle { 192 | background-image: none; 193 | background-color: @orange; 194 | border: 1px solid darken(@orange, 5); 195 | &:hover, &:active { 196 | background-color: @orange; 197 | } 198 | } 199 | 200 | .slider .slider-track { 201 | background-image: none; 202 | border: none; 203 | background-color: @lighterish; 204 | } 205 | 206 | .octoprint-container .accordion-heading [class*=" icon-"] { 207 | color: @orange; 208 | &:hover { 209 | color: darken(@orange, 8); 210 | } 211 | &.disabled { 212 | color: darken(@lighterish,5); 213 | } 214 | } 215 | 216 | /* Settings dialog-table icons */ 217 | td, th { 218 | &[class^="settings_"] { 219 | a { 220 | color: @notquiteWhite; 221 | &:hover { 222 | color: #fff; 223 | } 224 | &.disabled { 225 | color: darken(@lighterish,5); 226 | } 227 | } 228 | } 229 | & i { 230 | color: @notquiteWhite; 231 | &:hover { 232 | color: #fff; 233 | } 234 | &.disabled { 235 | color: darken(@lighterish,5); 236 | } 237 | } 238 | } 239 | 240 | #settings_dialog_content .table td { 241 | background-color: @notquiteBlack; 242 | border-top: none; 243 | } 244 | 245 | .table tbody tr.info td { 246 | background-color: @orange; 247 | } 248 | 249 | .icon-sd-black-14 { 250 | background-image: url(../../img/ic_sd_card_white_18dp_1x.png); 251 | background-image: url(../../img/ic_sd_card_white_18px.svg); 252 | background-position: 0 0; 253 | margin-top: 1px; 254 | width: 15px; 255 | height: 17px; 256 | filter: hue-rotate(unit(hue(@notquiteWhite),deg)) saturate(saturation(@notquiteWhite)) brightness(lightness(@notquiteWhite)); 257 | transform: rotateY(180deg); 258 | } 259 | 260 | .progress .bar { 261 | background: @orange; 262 | } 263 | 264 | #navbar .navbar-inner { 265 | background-color: @notquiteBlack; 266 | border: none; 267 | background-image: none; 268 | 269 | .nav { 270 | >li.dropdown.open>.dropdown-toggle, >li.dropdown.active>.dropdown-toggle, >li.dropdown.open.active>.dropdown-toggle { 271 | background: darken(@notquiteBlack, 1); 272 | // border-bottom: 1px solid @notquiteBlack; 273 | color: @orange; 274 | } 275 | > li > a:hover { 276 | color: @orange; 277 | background: @highlighter; 278 | } 279 | > li > .dropdown-menu:before{ 280 | border-bottom-color: @orange; 281 | } 282 | > li > .dropdown-menu:after{ 283 | border-bottom-color: @notquiteBlack; 284 | } 285 | } 286 | & .brand, .nav > li > a { 287 | color: @orange; 288 | text-shadow: none; 289 | & .caret { 290 | border-top-color: @orange; 291 | border-bottom-color: @orange; 292 | } 293 | } 294 | } 295 | 296 | .dropdown-menu { 297 | background: @notquiteBlack; 298 | border: 1px solid @orange; 299 | 300 | li > a { 301 | color: @notquiteWhite; 302 | &:hover, &:focus { 303 | background: @highlighter; 304 | outline: none; 305 | } 306 | } 307 | } 308 | 309 | /*general table hover colour*/ 310 | #files .gcode_files .entry:hover, 311 | .table-hover tbody tr:hover td, 312 | .table-hover tbody tr:hover th { 313 | background-color: lighten(@notquiteBlack, 10); 314 | } 315 | 316 | .legend > table { 317 | color: @notquiteWhite !important; 318 | } 319 | 320 | .progress { 321 | background: @lighterish; 322 | } 323 | 324 | /* Now non-bordered :) */ 325 | .table-bordered, .table-striped { 326 | border: none @lighterish; 327 | & th,td { 328 | border-color: @lighterish; 329 | border-left:none; 330 | border-right: none; 331 | } 332 | } 333 | 334 | .table-striped tbody { 335 | > tr:nth-child(odd) > td, th { 336 | background-color: @darkish; 337 | } 338 | } 339 | 340 | //modal 341 | 342 | .modal { 343 | background-color: @darkish; 344 | } 345 | 346 | .modal-body { 347 | border: none; 348 | } 349 | 350 | .modal-footer, .modal-header { 351 | background-color: @notquiteBlack; 352 | border: none; 353 | -webkit-box-shadow: none; 354 | -moz-box-shadow: none; 355 | box-shadow: none; 356 | } 357 | //menu in modal etc 358 | .nav-list > li > a { 359 | text-shadow: none; 360 | &:hover { 361 | color: #fff; 362 | background: @highlighter; 363 | } 364 | } 365 | 366 | .nav-list { 367 | .nav-header { 368 | text-shadow: none; 369 | color: @orange; 370 | } 371 | >.active>a { 372 | background-color: @notquiteBlack; 373 | &:hover { 374 | background-color: @notquiteBlack; 375 | } 376 | } 377 | } 378 | 379 | 380 | .close { 381 | color: #fff; 382 | text-shadow: none; 383 | } 384 | 385 | .help-inline, .help-block { 386 | color: darken(@notquiteWhite, 15); 387 | } 388 | 389 | code { 390 | background-color: @lighterish; 391 | border: none; 392 | } 393 | 394 | .label, .badge { 395 | background-color: @lighterish; 396 | color: @notquiteWhite; 397 | text-shadow: none; 398 | } 399 | 400 | 401 | .scrollable::-webkit-scrollbar, 402 | .pre-scrollable::-webkit-scrollbar, 403 | body::-webkit-scrollbar, 404 | .scroll-wrapper::-webkit-scrollbar, 405 | #settings_plugin_pluginmanager_pluginlist::-webkit-scrollbar, 406 | #settings_plugin_softwareupdate_updatelist::-webkit-scrollbar { 407 | background-color: @darkish; 408 | border: none; 409 | } 410 | 411 | .scrollable::-webkit-scrollbar-thumb, 412 | .pre-scrollable::-webkit-scrollbar-thumb, 413 | body::-webkit-scrollbar-thumb, 414 | .scroll-wrapper::-webkit-scrollbar-thumb, 415 | #settings_plugin_pluginmanager_pluginlist::-webkit-scrollbar-thumb, 416 | #settings_plugin_softwareupdate_updatelist::-webkit-scrollbar-thumb { 417 | background-color: @notquiteBlack; 418 | border-radius: 25px; 419 | } 420 | 421 | .scrollable::-webkit-scrollbar-track, 422 | .pre-scrollable::-webkit-scrollbar-track, 423 | body::-webkit-scrollbar-track, 424 | .scroll-wrapper::-webkit-scrollbar-track, 425 | #settings_plugin_pluginmanager_pluginlist::-webkit-scrollbar-track, 426 | #settings_plugin_softwareupdate_updatelist::-webkit-scrollbar-track { 427 | -webkit-box-shadow: inset 0 0 6px fade(@notquiteBlack,50); 428 | } 429 | 430 | legend { 431 | color: inherit; 432 | } 433 | 434 | .hero-unit { 435 | background-color: @darkish; 436 | } 437 | 438 | .footer ul li a { 439 | color: #999; 440 | } 441 | 442 | .flot-text { 443 | color: @notquiteWhite !important; 444 | } 445 | 446 | #terminal-output { 447 | background-color: @lighterish; 448 | color: @notquiteWhite; 449 | } 450 | 451 | .pagination-mini ul>li > a { 452 | background-color: @darkish; 453 | color: @notquiteWhite; 454 | border: 1px solid rgba(255,255,255,0.3); 455 | &:hover { 456 | color: #fff; 457 | background: @highlighter; 458 | border: 1px solid rgba(255,255,255,0.7); 459 | } 460 | &:focus { 461 | outline: none; 462 | border: 1px solid rgba(255,255,255,0.8); 463 | } 464 | } 465 | 466 | .pagination ul>li>a:hover, .pagination ul>.active>a { 467 | background-color: @notquiteBlack; 468 | color: #fff; 469 | border: 1px solid rgba(255,255,255,0.85); 470 | } 471 | 472 | .nav .dropdown-toggle .caret { 473 | border-top-color: @notquiteWhite; 474 | border-bottom-color: @notquiteWhite; 475 | } 476 | 477 | input[disabled], select[disabled], textarea[disabled], input[readonly], select[readonly], textarea[readonly] { 478 | background-color: darken(@lighterish,5); 479 | color: darken(@notquiteWhite, 10); 480 | } 481 | 482 | .modal-backdrop, .modal-backdrop.fade.in { 483 | background: #000; 484 | } 485 | 486 | .alert { 487 | h1, h2, h3, h4, h5, h6 { 488 | color: inherit; 489 | } 490 | } 491 | } 492 | -------------------------------------------------------------------------------- /octoprint_themeify/static/less/discoranged/variables.less: -------------------------------------------------------------------------------- 1 | @octoLight: darken(#13c100, 15%); 2 | @octoDark: darken(#169300, 15%); 3 | @greyple: #99AAB5; 4 | @darkish: #36393f;//#2C2F33; 5 | @notquiteBlack: #2f3136;// #23272A; 6 | @orange: #FC8003; 7 | @lighterish: lighten(@darkish, 20); 8 | @notquiteWhite: #dadadc;//#darken(#fff, 20); -------------------------------------------------------------------------------- /octoprint_themeify/static/less/discorded/discorded.less: -------------------------------------------------------------------------------- 1 | @import "variables.less"; 2 | 3 | @highlighter: lighten(@notquiteBlack,10); 4 | 5 | .discorded() { 6 | body { 7 | background-color: @darkish; 8 | color: @notquiteWhite; 9 | font-weight: 400; 10 | } 11 | 12 | a { 13 | color: @greyple; 14 | } 15 | 16 | a:hover { 17 | color: lighten(@greyple, 20) 18 | } 19 | 20 | .octoprint-container .tab-content h1 { 21 | color: #FFFFFF; 22 | } 23 | 24 | .octoprint-container .tab-content { 25 | border: none; 26 | } 27 | 28 | .accordion-group { 29 | border: none; 30 | } 31 | 32 | .accordion { 33 | background-color: @notquiteBlack; 34 | -webkit-box-shadow: 1px 1px 2px 0px rgba(0,0,0,0.75); 35 | -moz-box-shadow: 1px 1px 2px 0px rgba(0,0,0,0.75); 36 | box-shadow: 1px 1px 2px 0px rgba(0,0,0,0.75); 37 | } 38 | 39 | .octoprint-container .accordion-heading .accordion-heading-button a { 40 | color: inherit; 41 | } 42 | 43 | .nav-tabs>li>a { 44 | -webkit-border-radius: 0; 45 | border-radius: 0; 46 | } 47 | 48 | .nav-tabs>.active>a, .nav-tabs>.active>a:hover { 49 | background-color: @notquiteBlack; 50 | color: #fff; 51 | border: none; 52 | } 53 | .nav-pills>.active>a, .nav-pills>.active>a:hover { 54 | background-color: @blurple; 55 | } 56 | 57 | .nav-tabs>li>a:hover { 58 | background-color: lighten(@notquiteBlack, 10); 59 | border: none; 60 | } 61 | 62 | h1, h2, h3, h4 { 63 | color: #FFFFFF 64 | } 65 | 66 | .btn { 67 | border-radius: 3px; 68 | border-top-left-radius: 3px; 69 | border-top-right-radius: 3px; 70 | border-bottom-right-radius: 3px; 71 | border-bottom-left-radius: 3px; 72 | background-image: none; 73 | border: 1px solid rgba(255,255,255,0.3); 74 | box-shadow: none; 75 | background-color: @darkish; 76 | color: #fff; 77 | font-weight: 400; 78 | text-shadow: none; 79 | &:hover { 80 | color: #fff; 81 | background-color: @highlighter; 82 | } 83 | &:focus { 84 | border-color: rgba(255,255,255,0.7); 85 | background-color: @highlighter; 86 | // box-shadow: none; 87 | outline-color: @notquiteWhite; 88 | outline-width: 2px; 89 | color: #fff; 90 | } 91 | &:active { 92 | // box-shadow: none; 93 | background-color: lighten(@highlighter, 10) 94 | // outline: 0; 95 | } 96 | } 97 | .btn.active { 98 | background-color: lighten(@highlighter, 10); 99 | border: 1px solid rgba(255,255,255,0.85); 100 | color: #fff; 101 | } 102 | .btn btn-primary, .btn-primary[disabled] { 103 | background-color: #7289DA; 104 | } 105 | .btn-primary { 106 | background-color: #7289DA; 107 | border: none; 108 | &:hover { 109 | background-color: darken(@blurple, 5); 110 | } 111 | &:active, &:focus { 112 | background-color: darken(@blurple, 8); 113 | } 114 | &.disabled, &[disabled] { 115 | background-color: darken(@blurple, 5); 116 | } 117 | } 118 | .btn-group.open .btn-primary.dropdown-toggle { 119 | box-shadow: none; 120 | background-color: darken(@blurple, 10); 121 | } 122 | .btn-group.open .btn.dropdown-toggle { 123 | background: @darkish; 124 | &:active, &:focus { 125 | background: @darkish; 126 | color: #fff; 127 | } 128 | } 129 | .btn.disabled, .btn[disabled] { 130 | background-color: darken(@lighterish,5); 131 | color: darken(@notquiteWhite, 5); 132 | &:hover { 133 | color: darken(@notquiteWhite,5); 134 | } 135 | } 136 | 137 | select, textarea, input[type="search"],input[type="text"], input[type="number"], .input-append .add-on, textarea, input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input { 138 | background-color: @lighterish; 139 | border:none; 140 | color: lighten(@notquiteWhite,5); 141 | text-shadow: none; 142 | padding-bottom: 6px; 143 | } 144 | 145 | textarea:focus, input[type="text"]:focus, input[type="password"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="date"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="week"]:focus, input[type="number"]:focus, input[type="email"]:focus, input[type="url"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="color"]:focus, .uneditable-input:focus { 146 | box-shadow: inset 0 1px 1px rgba(255,255,255,0.075), 0 0 8px rgba(255,255,255,0.5) 147 | } 148 | .input-append .add-on, .input-prepend .add-on { 149 | padding-bottom: 6px; 150 | } 151 | //upload archive field 152 | .input-prepend .add-on.add-on-limited { 153 | background-color: @lighterish; 154 | color: lighten(@notquiteWhite, 5); 155 | border: none; 156 | text-shadow: none; 157 | } 158 | 159 | .slider .slider-selection { 160 | background: @blurple; 161 | 162 | &:hover, &:active { 163 | background-color: darken(@blurple, 5); 164 | } 165 | } 166 | 167 | .octoprint-container .accordion-heading [class*=" icon-"] { 168 | color: @notquiteWhite; 169 | &:hover { 170 | color: #fff; 171 | } 172 | &.disabled { 173 | color: darken(@lighterish,5); 174 | } 175 | } 176 | 177 | /* Settings dialog-table icons */ 178 | td, th { 179 | &[class^="settings_"] { 180 | a { 181 | color: @notquiteWhite; 182 | &:hover { 183 | color: #fff; 184 | } 185 | &.disabled { 186 | color: darken(@lighterish,5); 187 | } 188 | } 189 | } 190 | & i { 191 | color: @notquiteWhite; 192 | &:hover { 193 | color: #fff; 194 | } 195 | &.disabled { 196 | color: darken(@lighterish,5); 197 | } 198 | } 199 | } 200 | 201 | .icon-sd-black-14 { 202 | background-image: url(../../img/ic_sd_card_white_18dp_1x.png); 203 | background-image: url(../../img/ic_sd_card_white_18px.svg); 204 | background-position: 0 0px; 205 | margin-top: 1px; 206 | width: 15px; 207 | height: 17px; 208 | filter: hue-rotate(unit(hue(@notquiteWhite),deg)) saturate(saturation(@notquiteWhite)) brightness(lightness(@notquiteWhite)); 209 | transform: rotateY(180deg); 210 | } 211 | 212 | .progress .bar { 213 | background: @blurple; 214 | } 215 | 216 | #navbar .navbar-inner { 217 | background-color: @notquiteBlack; 218 | border: none; 219 | background-image: none; 220 | 221 | .nav { 222 | >li.dropdown.open>.dropdown-toggle, >li.dropdown.active>.dropdown-toggle, >li.dropdown.open.active>.dropdown-toggle { 223 | background: darken(@notquiteBlack, 1); 224 | border-bottom: 1px solid @notquiteWhite; 225 | color: #fff; 226 | } 227 | > li > a:hover { 228 | color: #fff; 229 | background: @highlighter; 230 | } 231 | } 232 | 233 | & .brand, .nav > li > a { 234 | color: #fff; 235 | & .caret { 236 | border-top-color: #fff; 237 | border-bottom-color: #fff; 238 | } 239 | } 240 | } 241 | 242 | .dropdown-menu { 243 | background: @notquiteBlack; 244 | 245 | li > a { 246 | color: @notquiteWhite; 247 | &:hover, &:focus { 248 | background: @highlighter; 249 | outline: none; 250 | } 251 | } 252 | } 253 | 254 | /*general table hover colour*/ 255 | #files .gcode_files .entry:hover, 256 | .table-hover tbody tr:hover td, 257 | .table-hover tbody tr:hover th { 258 | background-color: lighten(@notquiteBlack, 10); 259 | } 260 | 261 | .legend > table { 262 | color: @notquiteWhite !important; 263 | } 264 | 265 | .progress { 266 | background: @lighterish; 267 | } 268 | 269 | /* Now non-bordered :) */ 270 | .table-bordered, .table-striped { 271 | border-color: @lighterish; 272 | border: none; 273 | & th,td { 274 | border-color: @lighterish; 275 | border-left:none; 276 | border-right: none; 277 | } 278 | } 279 | 280 | .table-striped tbody { 281 | > tr:nth-child(odd) > td, th { 282 | background-color: @darkish; 283 | } 284 | } 285 | 286 | //modal 287 | 288 | .modal { 289 | background-color: @darkish; 290 | } 291 | 292 | .modal-body { 293 | border: none; 294 | } 295 | 296 | .modal-footer, .modal-header { 297 | background-color: @notquiteBlack; 298 | border: none; 299 | -webkit-box-shadow: none; 300 | -moz-box-shadow: none; 301 | box-shadow: none; 302 | } 303 | //menu in modal etc 304 | .nav-list > li > a { 305 | text-shadow: none; 306 | &:hover { 307 | color: #fff; 308 | background: @highlighter; 309 | } 310 | } 311 | 312 | .nav-list { 313 | .nav-header { 314 | text-shadow: none; 315 | } 316 | >.active>a { 317 | background-color: @notquiteBlack; 318 | &:hover { 319 | background-color: @notquiteBlack; 320 | } 321 | } 322 | } 323 | 324 | 325 | .close { 326 | color: #fff; 327 | text-shadow: none; 328 | } 329 | 330 | .help-inline, .help-block { 331 | color: darken(@notquiteWhite, 15); 332 | } 333 | 334 | code { 335 | background-color: @lighterish; 336 | border: none; 337 | } 338 | 339 | .label, .badge { 340 | background-color: @lighterish; 341 | color: @notquiteWhite; 342 | text-shadow: none; 343 | } 344 | 345 | 346 | .scrollable::-webkit-scrollbar, .pre-scrollable::-webkit-scrollbar,body::-webkit-scrollbar { 347 | background-color: @darkish; 348 | } 349 | 350 | .scrollable::-webkit-scrollbar-thumb,.pre-scrollable::-webkit-scrollbar-thumb, body::-webkit-scrollbar-thumb{ 351 | background-color: darken(@darkish,5); 352 | border-radius: 25px; 353 | } 354 | 355 | .scrollable::-webkit-scrollbar-track,.pre-scrollable::-webkit-scrollbar-track, body::-webkit-scrollbar-track { 356 | -webkit-box-shadow: inset 0 0 6px fade(@notquiteBlack,50); 357 | } 358 | 359 | legend { 360 | color: inherit; 361 | } 362 | 363 | .hero-unit { 364 | background-color: @darkish; 365 | } 366 | 367 | .footer ul li a { 368 | color: #999; 369 | } 370 | 371 | .flot-text { 372 | color: @notquiteWhite !important; 373 | } 374 | 375 | #terminal-output { 376 | background-color: @lighterish; 377 | color: @notquiteWhite; 378 | } 379 | 380 | .pagination-mini ul>li > a { 381 | background-color: @darkish; 382 | color: @notquiteWhite; 383 | border: 1px solid rgba(255,255,255,0.3); 384 | &:hover { 385 | color: #fff; 386 | background: @highlighter; 387 | border: 1px solid rgba(255,255,255,0.7); 388 | } 389 | &:focus { 390 | outline: none; 391 | border: 1px solid rgba(255,255,255,0.8); 392 | } 393 | } 394 | 395 | .pagination ul>li>a:hover, .pagination ul>.active>a { 396 | background-color: @notquiteBlack; 397 | color: #fff; 398 | border: 1px solid rgba(255,255,255,0.85); 399 | } 400 | 401 | .nav .dropdown-toggle .caret { 402 | border-top-color: @notquiteWhite; 403 | border-bottom-color: @notquiteWhite; 404 | } 405 | 406 | input[disabled], select[disabled], textarea[disabled], input[readonly], select[readonly], textarea[readonly] { 407 | background-color: darken(@lighterish,5); 408 | color: darken(@notquiteWhite, 10); 409 | } 410 | 411 | .modal-backdrop, .modal-backdrop.fade.in { 412 | background: #000; 413 | } 414 | 415 | .alert { 416 | h1, h2, h3, h4, h5, h6 { 417 | color: inherit; 418 | } 419 | } 420 | } 421 | -------------------------------------------------------------------------------- /octoprint_themeify/static/less/discorded/variables.less: -------------------------------------------------------------------------------- 1 | @octoLight: darken(#13c100, 15%); 2 | @octoDark: darken(#169300, 15%); 3 | @greyple: #99AAB5; 4 | @darkish: #36393f;//#2C2F33; 5 | @notquiteBlack: #2f3136;// #23272A; 6 | @blurple: #7289DA; 7 | @lighterish: lighten(@darkish, 20); 8 | @notquiteWhite: #dadadc;//#darken(#fff, 20); -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/components/buttons.less: -------------------------------------------------------------------------------- 1 | .btn { 2 | margin: 0 0 0.25rem; 3 | padding: 0.25rem 0.5rem; 4 | height: auto; 5 | 6 | background-image: none; 7 | 8 | border: 0; 9 | border-radius: 0; 10 | 11 | .matShadow(1); 12 | 13 | background-color: @colorBackgroundDark; 14 | 15 | color: @colorPrimaryText; 16 | text-shadow: none; 17 | font-weight: 300; 18 | font-family: @fontBody; 19 | 20 | transition: all 0.1s ease-in-out; 21 | 22 | &:hover { 23 | background-color: darken(@colorBackgroundDark, 8%); 24 | 25 | .matShadow(2); 26 | } 27 | 28 | &.disabled, 29 | &[disabled] { 30 | box-shadow: none; 31 | } 32 | 33 | .fa { 34 | // margin-right: 0.25rem; 35 | 36 | color: darken(@colorBackgroundDark, 30%); 37 | } 38 | } 39 | 40 | .btn-primary { 41 | .btn; 42 | 43 | background-color: @colorSecondary; 44 | 45 | color: @colorSecondaryText; 46 | text-shadow: 0 1px 0 fade(@colorSecondaryLight, 50%); 47 | 48 | &:hover { 49 | background-color: lighten(@colorSecondary, 12%); 50 | } 51 | 52 | .fa { 53 | color: @colorSecondaryDark; 54 | } 55 | } 56 | 57 | .btn-danger { 58 | background-color: @colorError; 59 | 60 | color: #FFF; 61 | // text-shadow: 0 1px 0 fade(@colorSecondaryLight, 50%); 62 | 63 | &:hover { 64 | background-color: @colorErrorDark; 65 | } 66 | 67 | .fa { 68 | color: rgba(255,255,255, 0.7); 69 | } 70 | } 71 | 72 | 73 | .btn-group.open .btn-primary.dropdown-toggle { 74 | background-color: @colorSecondaryDark; 75 | 76 | .caret { 77 | border-top-color: @colorSecondaryLight; 78 | border-bottom-color: @colorSecondaryLight; 79 | } 80 | } 81 | 82 | 83 | .dropdown-menu li > a, 84 | .dropdown-menu li > a, 85 | .dropdown-submenu > a { 86 | color: @colorSecondaryText; 87 | 88 | &:hover { 89 | background: @colorSecondaryLight; 90 | color: @colorSecondaryDark; 91 | } 92 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/components/dropdown.less: -------------------------------------------------------------------------------- 1 | .dropdown-menu { 2 | padding: 0.25rem 0; 3 | 4 | border-radius: 0; 5 | border: 0; 6 | .matShadow(2); 7 | 8 | .divider { 9 | margin: 0.25rem 0; 10 | border-color: @colorSecondary; 11 | } 12 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/components/forms.less: -------------------------------------------------------------------------------- 1 | select, 2 | textarea, 3 | input[type="text"], 4 | input[type="password"], 5 | input[type="datetime"], 6 | input[type="datetime-local"], 7 | input[type="date"], 8 | input[type="month"], 9 | input[type="time"], 10 | input[type="week"], 11 | input[type="number"], 12 | input[type="email"], 13 | input[type="url"], 14 | input[type="search"], 15 | input[type="tel"], 16 | input[type="color"], 17 | .uneditable-input { 18 | height: auto; 19 | 20 | border: 0; 21 | box-shadow: none; 22 | border-radius: 0; 23 | 24 | font-family: @fontBody; 25 | background-color: #FFF; 26 | padding: 0.325rem; 27 | 28 | .matShadow(1); 29 | 30 | &[disabled] { 31 | background-color: @colorBackground; 32 | box-shadow: none; 33 | } 34 | } 35 | 36 | .input-prepend, 37 | .input-append, 38 | .input-prepend.input-append { 39 | display: inline-flex; 40 | margin-bottom: 0.25rem; 41 | transition: all 0.2s ease-in-out; 42 | .matShadow(1); 43 | 44 | &:hover { 45 | .matShadow(2); 46 | } 47 | 48 | select, 49 | textarea, 50 | input[type="text"], 51 | input[type="password"], 52 | input[type="datetime"], 53 | input[type="datetime-local"], 54 | input[type="date"], 55 | input[type="month"], 56 | input[type="time"], 57 | input[type="week"], 58 | input[type="number"], 59 | input[type="email"], 60 | input[type="url"], 61 | input[type="search"], 62 | input[type="tel"], 63 | input[type="color"], 64 | .uneditable-input { 65 | flex-grow: 1; 66 | box-shadow: none; 67 | } 68 | 69 | input[type="number"] { 70 | min-width: 50px; 71 | } 72 | 73 | .btn { 74 | display: flex; 75 | align-items: center; 76 | justify-content: center; 77 | 78 | margin: 0; 79 | padding: 0; 80 | width: 2rem; 81 | 82 | text-align: center; 83 | 84 | border-radius: 0; 85 | box-shadow: none; 86 | border: 0; 87 | 88 | .fa { 89 | margin: 0; 90 | } 91 | } 92 | 93 | .add-on { 94 | flex-grow: 1; 95 | padding: 0.25rem 0.5rem; 96 | height: auto; 97 | 98 | border: 0; 99 | font-size: 0.8rem; 100 | text-transform: uppercase; 101 | color: #666; 102 | background-color: @colorBackground; 103 | } 104 | 105 | .btn.add-on { 106 | padding-left: 0.5rem; 107 | padding-right: 0.5rem; 108 | } 109 | } 110 | 111 | .progress { 112 | display: flex; 113 | margin: 1rem 0; 114 | height: 2rem; 115 | 116 | background-color: red; 117 | 118 | border-radius: 0; 119 | box-shadow: none; 120 | 121 | .progress-text-back, 122 | .progress-text-front { 123 | display: flex; 124 | align-items: center; 125 | justify-content: center; 126 | height: 100%; 127 | 128 | font-size: 0.9rem; 129 | font-weight: 700; 130 | text-shadow: none; 131 | } 132 | 133 | .bar { 134 | background: @colorPrimary; 135 | } 136 | } 137 | 138 | .slider { 139 | border-radius: 0; 140 | border: 0; 141 | 142 | .slider-track { 143 | border: 0; 144 | border-radius: 0; 145 | box-shadow: none; 146 | 147 | transition: box-shadow 0.2s ease-in-out; 148 | 149 | &:hover { 150 | .matShadow(1); 151 | } 152 | } 153 | 154 | .slider-selection { 155 | background: @colorPrimary; 156 | border-radius: 0; 157 | } 158 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/components/modal.less: -------------------------------------------------------------------------------- 1 | .modal-backdrop { 2 | background: #222; 3 | } 4 | 5 | .modal { 6 | border-radius: 0; 7 | border: 0; 8 | 9 | .matShadow(2); 10 | 11 | .modal-header { 12 | background-color: @colorSecondary; 13 | border-bottom: 0; 14 | 15 | color: @colorSecondaryText; 16 | } 17 | 18 | .modal-body { 19 | padding: 0; 20 | 21 | > p { 22 | padding: 0 1rem; 23 | } 24 | 25 | .full-sized-box { 26 | padding: 0; 27 | 28 | .tab-content > .tab-pane, 29 | .pill-content > .pill-pane { 30 | padding: 1rem 1rem 1rem 0; 31 | } 32 | } 33 | 34 | a { 35 | color: @colorSecondary; 36 | } 37 | 38 | table th, 39 | table td { 40 | vertical-align: middle; 41 | } 42 | } 43 | 44 | .modal-footer { 45 | margin-bottom: 0; 46 | padding: 1rem; 47 | 48 | text-align: right; 49 | 50 | border-top: 0; 51 | border-radius: 0; 52 | box-shadow: none; 53 | background-color: @colorBackground; 54 | } 55 | 56 | table td.settings_users_actions, 57 | table th.settings_users_actions, 58 | table td.settings_printerProfiles_profiles_action, 59 | table th.settings_printerProfiles_profiles_action { 60 | width: auto; 61 | 62 | a { 63 | display: inline-block; 64 | padding: 0.25rem 0.625rem; 65 | 66 | font-size: 1.2rem; 67 | } 68 | } 69 | 70 | .tab-content { 71 | box-shadow: none; 72 | } 73 | } 74 | 75 | #settings_printerProfiles_editDialog, 76 | #usersettings_dialog { 77 | .tab-content { 78 | padding: 0 1rem; 79 | } 80 | } 81 | 82 | .nav-pills { 83 | background-color: @colorSecondaryLight; 84 | 85 | > li:not(.dropdown) { 86 | 87 | > a { 88 | margin: 0; 89 | padding: 0.5rem 1rem; 90 | 91 | border-radius: 0; 92 | 93 | color: @colorSecondaryText; 94 | font-size: 0.8rem; 95 | text-transform: uppercase; 96 | 97 | &:hover { 98 | color: @colorPrimaryText; 99 | } 100 | } 101 | 102 | &.active > a, 103 | &.active > a:hover { 104 | color: @colorPrimaryText; 105 | background-color: #FFF; 106 | } 107 | } 108 | } 109 | 110 | .nav-list { 111 | .nav-header { 112 | background-color: @colorBackground; 113 | } 114 | 115 | li > a { 116 | padding: 0.5rem 1rem; 117 | 118 | color: @colorSecondaryDark; 119 | 120 | &:hover { 121 | background-color: fade(@colorSecondaryLight, 50%); 122 | 123 | color: @colorSecondaryDark; 124 | } 125 | } 126 | 127 | > .active > a, 128 | > .active > a:hover { 129 | // padding: 0.5rem 1rem; 130 | 131 | color: @colorSecondaryText; 132 | text-shadow: none; 133 | 134 | background-color: @colorSecondaryLight; 135 | } 136 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/dyl.less: -------------------------------------------------------------------------------- 1 | @import "variables.less"; 2 | @import "mixins.less"; 3 | 4 | .dyl() { 5 | 6 | 7 | body { 8 | background-color: @colorBackground; 9 | 10 | color: @colorPrimaryText; 11 | font-family: @fontBody; 12 | font-size: 16px; 13 | 14 | overflow-x: hidden; 15 | 16 | box-sizing: border-box; 17 | 18 | * { 19 | box-sizing: inherit; 20 | } 21 | } 22 | 23 | a { 24 | color: @colorPrimary; 25 | 26 | transition: all 0.15s ease-in-out; 27 | } 28 | 29 | @import "navbar.less"; 30 | @import "navtabs.less"; 31 | 32 | @import "components/modal.less"; 33 | @import "components/buttons.less"; 34 | @import "components/forms.less"; 35 | @import "components/dropdown.less"; 36 | 37 | @import "sidebar.less"; 38 | @import "files.less"; 39 | @import "footer.less"; 40 | 41 | @import "tabs/temp.less"; 42 | @import "tabs/control.less"; 43 | 44 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/files.less: -------------------------------------------------------------------------------- 1 | #files .form-search { 2 | display: block; 3 | margin: 0 0 0.5rem !important; 4 | 5 | input { 6 | width: 100%; 7 | } 8 | } 9 | 10 | #files .gcode_files { 11 | // border: 1px solid blue; 12 | 13 | .entry { 14 | margin: 0 0 0.5rem; 15 | padding: 0 0 1.5rem; 16 | 17 | line-height: 1.4; 18 | 19 | background-color: lighten(@colorBackground, 1%); 20 | border: 0; 21 | 22 | &.folder { 23 | padding: 0; 24 | 25 | border-left: 0.5rem solid @colorBackgroundDark; 26 | } 27 | 28 | &.back { 29 | padding: 0 1rem; 30 | background-color: #FFF; 31 | 32 | &:hover { 33 | background-color: fade(@colorSecondary, 10%); 34 | // color: @colorSecondaryText; 35 | } 36 | } 37 | 38 | .title { 39 | margin: 0 0 0.125rem; 40 | padding: 0.25rem 0.5rem 0.125rem; 41 | 42 | background-color: @colorBackgroundDark; 43 | transition: background 0.1s ease-in-out; 44 | // border-bottom: 1px solid @colorBorder; 45 | 46 | &:hover { 47 | background-color: darken(@colorBackgroundDark, 5%); 48 | } 49 | } 50 | 51 | .internal, 52 | .uploaded, 53 | .size, 54 | .additionalInfo { 55 | padding: 0.125rem 0.5rem; 56 | } 57 | 58 | .additionalInfo { 59 | margin-left: 0.5rem; 60 | padding-left: 0.25rem; 61 | margin-bottom: 1rem; 62 | border-left: 0.25rem solid @colorBackgroundDark; 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/footer.less: -------------------------------------------------------------------------------- 1 | .octoprint-container > .footer { 2 | position: relative; 3 | 4 | display: flex; 5 | justify-content: space-between; 6 | padding: 1rem; 7 | 8 | background: @colorPrimaryDark; 9 | 10 | color: rgba(255,255,255, 0.8); 11 | 12 | &::before, 13 | &::after { 14 | position: absolute; 15 | top: 0; 16 | 17 | display: block; 18 | height: 100%; 19 | // width: calc(~"50vw - 477px"); 20 | width: 50vw; 21 | 22 | content: ""; 23 | background-color: @colorPrimaryDark; 24 | } 25 | 26 | &::before { 27 | left: 100%; 28 | } 29 | 30 | &::after { 31 | right: 100%; 32 | } 33 | 34 | #footer_version, 35 | #footer_links { 36 | float: none; 37 | margin: 0; 38 | } 39 | 40 | .muted, 41 | a { 42 | color: rgba(255,255,255, 0.8); 43 | 44 | &:hover { 45 | color: #FFF; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/mixins.less: -------------------------------------------------------------------------------- 1 | .matShadow(@level: 1){ 2 | & when (@level = 1) { 3 | box-shadow: 0 1px 2px rgba(0,0,0,0.1), 4 | 0 1px 1px rgba(0,0,0,0.2); 5 | } 6 | & when (@level = 2) { 7 | box-shadow: 0 2px 4px rgba(0,0,0,0.2), 8 | 0 3px 5px rgba(0,0,0,0.15); 9 | } 10 | & when (@level = 3) { 11 | box-shadow: 0 10px 20px rgba(0,0,0,0.19), 12 | 0 6px 6px rgba(0,0,0,0.23); 13 | } 14 | & when (@level = 4) { 15 | box-shadow: 0 14px 28px rgba(0,0,0,0.25), 16 | 0 10px 10px rgba(0,0,0,0.22); 17 | } 18 | & when (@level = 5) { 19 | box-shadow: 0 19px 38px rgba(0,0,0,0.30), 20 | 0 15px 12px rgba(0,0,0,0.22); 21 | } 22 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/navbar.less: -------------------------------------------------------------------------------- 1 | #navbar { 2 | position: sticky; 3 | z-index: 1001; 4 | top: 0; 5 | 6 | &.navbar-fixed-top .navbar-inner, 7 | &.navbar-static-top .navbar-inner { 8 | // .matShadow(1); 9 | box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); 10 | border-width: 0; 11 | } 12 | 13 | .navbar-inner { 14 | min-height: 0; 15 | 16 | background: @colorPrimary; 17 | 18 | // border: 1px solid red; 19 | 20 | .container { 21 | display: flex; 22 | justify-content: space-between; 23 | 24 | // border: 1px solid blue; 25 | 26 | &::before, 27 | &::after { 28 | display: none; 29 | } 30 | 31 | .nav-collapse { 32 | display: flex; 33 | } 34 | } 35 | 36 | .brand { 37 | margin-left: 0; 38 | padding: 0.6rem 1rem 0.4rem; 39 | color: @colorPrimaryText; 40 | text-shadow: none; 41 | 42 | &:hover { 43 | background: @colorPrimaryDark; 44 | } 45 | 46 | span { 47 | padding-left: 0; 48 | height: 24px; 49 | max-width: 250px; 50 | overflow: hidden; 51 | 52 | background: none !important; 53 | 54 | color: #FFF; 55 | font-size: 1.6rem; 56 | font-weight: 300; 57 | text-shadow: 0 1px 0 fade(@colorPrimaryDark, 50%); 58 | text-overflow: ellipsis; 59 | vertical-align: top; 60 | white-space: nowrap; 61 | line-height: 20px; 62 | } 63 | } 64 | 65 | ul.pull-right { 66 | display: flex; 67 | } 68 | 69 | ul.pull-right > li { 70 | display: flex; 71 | 72 | &.open { 73 | > a { 74 | background: @colorPrimaryDark; 75 | } 76 | 77 | &#navbar_login > a .caret { 78 | border-bottom-color: @colorPrimary; 79 | border-top-color: @colorPrimary; 80 | } 81 | } 82 | 83 | > a { 84 | padding: 0.6rem 1rem 0.4rem; 85 | 86 | color: #FFF; 87 | font-weight: 300; 88 | font-size: 1rem; 89 | text-shadow: 0 1px 0 fade(@colorPrimaryDark, 50%); 90 | 91 | &:hover { 92 | background: @colorPrimaryDark; 93 | } 94 | } 95 | } 96 | 97 | #navbar_login { 98 | .fa { 99 | margin-right: 0.25rem; 100 | } 101 | 102 | .caret { 103 | margin-top: 9px; 104 | transition: all 0.15s ease-in-out; 105 | 106 | border-bottom-color: @colorPrimaryDark; 107 | border-top-color: @colorPrimaryDark; 108 | } 109 | 110 | &:hover .caret { 111 | border-bottom-color: @colorPrimary; 112 | border-top-color: @colorPrimary; 113 | } 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/navtabs.less: -------------------------------------------------------------------------------- 1 | .nav-tabs { 2 | display: flex; 3 | 4 | // border-left: 1px solid @colorBorder; 5 | box-shadow: -1px 0 0 @colorBorder, 1px 0 0 @colorBorder; 6 | 7 | > li:not(.dropdown) { 8 | flex-grow: 1; 9 | flex-basis: 8rem; 10 | 11 | display: flex; 12 | 13 | border-top: 1px solid @colorBorder; 14 | border-bottom: 1px solid fade(@colorBorder, 50%); 15 | 16 | &:not(:last-of-type) { 17 | border-right: 1px solid @colorBorder; 18 | } 19 | 20 | > a { 21 | display: flex; 22 | justify-content: center; 23 | margin: 0; 24 | padding: 0.5rem 1rem; 25 | width: 100%; 26 | 27 | border-radius: 0; 28 | border: 0; 29 | 30 | background-color: darken(@colorBackground, 3%); 31 | color: #AAA; 32 | 33 | // color: @colorPrimaryDark; 34 | font-size: 0.8rem; 35 | font-weight: 700; 36 | text-align: center; 37 | text-transform: uppercase; 38 | } 39 | 40 | &.active { 41 | border-bottom: 1px solid #FFF; 42 | 43 | > a { 44 | color: #222; 45 | 46 | background-color: #FFF; 47 | } 48 | } 49 | } 50 | } 51 | 52 | .octoprint-container .tab-content { 53 | margin-bottom: 1.5rem; 54 | } 55 | .tab-content { 56 | 57 | background-color: #FFF; 58 | 59 | border-radius: 0; 60 | border: 0; 61 | 62 | .matShadow(1); 63 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/sidebar.less: -------------------------------------------------------------------------------- 1 | .accordion-group { 2 | border: 0; 3 | border-radius: 0; 4 | 5 | .matShadow(1); 6 | 7 | &:not(:last-of-type) { 8 | margin-bottom: 1rem; 9 | } 10 | 11 | .accordion-heading { 12 | display: flex; 13 | // align-items: center; 14 | border-radius: 0; 15 | 16 | background-color: @colorSecondaryLight; 17 | 18 | color: @colorSecondaryText; 19 | 20 | > a { 21 | display: flex; 22 | align-items: center; 23 | padding: 0.5rem 1rem; 24 | width: 100%; 25 | 26 | font-size: 0.8rem; 27 | font-weight: 700; 28 | text-transform: uppercase; 29 | color: @colorSecondaryText; 30 | 31 | .fa { 32 | display: flex; 33 | align-items: center; 34 | justify-content: center; 35 | margin-right: 0.5rem; 36 | padding-top: 2px; 37 | height: 1em; 38 | width: 1.4rem; 39 | 40 | transition: all 0.1s ease-in-out; 41 | color: @colorSecondaryDark; 42 | // text-align: center; 43 | font-size: 1.2rem; 44 | vertical-align: middle; 45 | } 46 | 47 | &:hover { 48 | text-decoration: none; 49 | } 50 | 51 | &.collapsed { 52 | padding: 0.125rem 1rem; 53 | 54 | .fa { 55 | font-size: 0.8rem; 56 | color: lighten(@colorSecondaryDark, 6%); 57 | } 58 | 59 | ~ div { 60 | display: none; 61 | } 62 | } 63 | } 64 | } 65 | 66 | .accordion-heading-button { 67 | display: flex; 68 | float: none; 69 | } 70 | 71 | .accordion-heading-button [class*=" icon-"], 72 | .accordion-heading-button [class^=icon-], 73 | .accordion-heading-button > a { 74 | display: flex; 75 | align-items: center; 76 | justify-content: center; 77 | padding: 0.5rem; 78 | 79 | font-size: 1rem; 80 | line-height: 1.2rem; 81 | text-align: center; 82 | color: #222; 83 | 84 | border-radius: 0; 85 | background-position: 50% 60%; 86 | box-shadow: none; 87 | 88 | .icon-sd-black-14 { 89 | padding-left: 0; 90 | } 91 | } 92 | 93 | .accordion-body { 94 | background-color: #FFF; 95 | } 96 | 97 | .accordion-inner { 98 | padding: 0.5rem 1rem 1rem; 99 | 100 | border-top: 0; 101 | } 102 | } 103 | 104 | .accordion-inner { 105 | font-size: 0.9rem; 106 | font-weight: 300; 107 | 108 | color: @colorPrimaryText; 109 | 110 | label { 111 | margin-bottom: 0; 112 | 113 | font-weight: 300; 114 | 115 | &:last-of-type { 116 | margin-bottom: 0.5rem; 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/tabs/control.less: -------------------------------------------------------------------------------- 1 | #control { 2 | // display: flex; 3 | 4 | &.active { 5 | display: flex; 6 | flex-wrap: wrap; 7 | } 8 | 9 | #webcam_container { 10 | flex-basis: 940px; 11 | margin: 0 1rem 2rem 0; 12 | } 13 | 14 | > .jog-panel { 15 | flex-grow: 1; 16 | 17 | float: none; 18 | 19 | h1 { 20 | display: block; 21 | margin: 0 0 1rem; 22 | padding: 0.5rem; 23 | 24 | border-bottom: 0; 25 | background-color: @colorBackground; 26 | 27 | font-weight: 700; 28 | font-size: 1rem; 29 | font-family: @fontTitle; 30 | line-height: 1.2; 31 | text-transform: uppercase; 32 | color: @colorPrimaryText; 33 | } 34 | } 35 | 36 | > .jog-panel:first-child { 37 | display: flex; 38 | flex-wrap: wrap; 39 | flex-basis: 20rem; 40 | } 41 | 42 | #control-jog-z, 43 | #control-jog-xy { 44 | float: none; 45 | margin-bottom: 2rem; 46 | 47 | button { 48 | padding: 1.5rem; 49 | } 50 | } 51 | 52 | .distance { 53 | // flex-basis: 10rem; 54 | margin-bottom: 0.25rem; 55 | width: 100%; 56 | flex-grow: 1; 57 | display: flex; 58 | 59 | .btn-group { 60 | display: flex; 61 | margin-right: 1rem; 62 | width: 100%; 63 | } 64 | 65 | button { 66 | display: flex; 67 | justify-content: center; 68 | padding: 0.5rem; 69 | 70 | text-align: center; 71 | font-weight: 400; 72 | 73 | &.active { 74 | background-color: @colorPrimary; 75 | 76 | color: #FFF; 77 | font-weight: 700; 78 | } 79 | } 80 | } 81 | 82 | #control-jog-feedrate { 83 | width: 100%; 84 | 85 | .slider { 86 | margin-bottom: 1rem; 87 | } 88 | 89 | .btn-block { 90 | width: 100% !important; 91 | } 92 | } 93 | 94 | .control-box { 95 | display: flex; 96 | } 97 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/tabs/temp.less: -------------------------------------------------------------------------------- 1 | #temp { 2 | 3 | .table.table-bordered { 4 | 5 | th { 6 | padding: 0.25rem 0.5rem; 7 | 8 | font-size: 0.8rem; 9 | text-transform: uppercase; 10 | 11 | background-color: @colorBackground; 12 | } 13 | } 14 | 15 | .form-inline { 16 | display: flex; 17 | justify-content: center; 18 | 19 | > div { 20 | 21 | &:not(:last-of-type) { 22 | margin-right: 1rem; 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /octoprint_themeify/static/less/dyl/variables.less: -------------------------------------------------------------------------------- 1 | // Dyl 1.0.1 2 | // Variables 3 | // -------------------------------------------------- 4 | @import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700'); 5 | 6 | @fontBody: "Source Sans Pro", sans-serif; 7 | @fontTitle: @fontBody; 8 | 9 | @colorPrimary: #4caf50; 10 | @colorPrimaryLight: #80e27e; 11 | @colorPrimaryDark: #087f23; 12 | @colorPrimaryText: #333; 13 | 14 | @colorSecondary: #ff9800; 15 | @colorSecondaryLight: #ffc947; 16 | @colorSecondaryDark: #c66900; 17 | @colorSecondaryText: darken(@colorSecondaryDark, 16%); 18 | 19 | @colorError: #c62828; 20 | @colorErrorLight: #ff5f52; 21 | @colorErrorDark: #8e0000; 22 | @colorErrorText: darken(@colorErrorDark, 10%); 23 | 24 | @colorBorder: #DDDDDD; 25 | 26 | @colorBackground: #F5F5F5; 27 | @colorBackgroundDark: #E7E7E7; 28 | -------------------------------------------------------------------------------- /octoprint_themeify/static/less/material-ui-light/material_ui_light.less: -------------------------------------------------------------------------------- 1 | .material_ui_light() { 2 | .btn { 3 | background: white; 4 | filter: brightness(1.0); 5 | border-radius: 3px; 6 | } 7 | .input-prepend, .input-append { 8 | .add-on:not(:last-child), .btn:not(:last-child) { 9 | border-top-right-radius: 0; 10 | border-bottom-right-radius: 0; 11 | } 12 | } 13 | .btn-group .btn:not(:last-of-type) { 14 | border-top-right-radius: 0; 15 | border-bottom-right-radius: 0; 16 | } 17 | .input-prepend, .input-append { 18 | .add-on:not(:first-child), .btn:not(:first-child) { 19 | border-top-left-radius: 0; 20 | border-bottom-left-radius: 0; 21 | } 22 | } 23 | .btn-group .btn:not(:first-of-type) { 24 | border-top-left-radius: 0; 25 | border-bottom-left-radius: 0; 26 | } 27 | .btn-group .btn:first-of-type:last-of-type { 28 | width: 100%; 29 | } 30 | .btn, .btn:focus, .btn:hover { 31 | transition: filter 0.2s ease, background-color 0.2s ease; 32 | } 33 | .btn.active, .btn.disabled, .btn:active, .btn:focus, .btn:hover, .btn[disabled] { 34 | filter: brightness(0.9); 35 | } 36 | .btn, .btn.active, .btn:active, .btn-group:not(.accordion-heading-button) { 37 | box-shadow: 0 4px 6px -4px rgba(0, 0, 0, 0.47); 38 | } 39 | .btn-group .btn { 40 | box-shadow: none; 41 | } 42 | .dropdown-backdrop { 43 | display: none; 44 | } 45 | .btn-group>.btn+.dropdown-backdrop+.dropdown-toggle, .btn-group>.btn+.dropdown-toggle { 46 | padding-right: 8px; 47 | padding-left: 8px; 48 | } 49 | .progress { 50 | background: rgba(0, 0, 0, 0.07); 51 | box-shadow: none; 52 | } 53 | .progress .bar { 54 | background: #2196F3; 55 | box-shadow: none; 56 | border: 0; 57 | } 58 | .btn, .input-append .add-on, .input-prepend .add-on, textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input, textarea:focus, input[type="text"]:focus, input[type="password"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="date"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="week"]:focus, input[type="number"]:focus, input[type="email"]:focus, input[type="url"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="color"]:focus, .uneditable-input:focus { 59 | text-shadow: none; 60 | border: 1px solid rgba(0, 0, 0, 0.31); 61 | } 62 | .btn-primary, .btn-primary.active, .btn-primary.disabled, .btn-primary:active, .btn-primary:focus, .btn-primary:hover, .btn-primary[disabled] { 63 | color: #fff; 64 | background-color: #2196F3; 65 | } 66 | .btn-danger, .btn-danger.active, .btn-danger.disabled, .btn-danger:active, .btn-danger:focus, .btn-danger:hover, .btn-danger[disabled] { 67 | background-color: #F44336; 68 | } 69 | .btn-warning, .btn-warning.active, .btn-warning.disabled, .btn-warning:active, .btn-warning:focus, .btn-warning:hover, .btn-warning[disabled] { 70 | background-color: #FF9800; 71 | } 72 | .dropdown-menu li>a:hover, .dropdown-menu li>a:focus, .dropdown-submenu:hover>a { 73 | background: #2196F3; 74 | } 75 | .dropdown-menu { 76 | box-shadow: 0 5px 15px -5px rgba(0, 0, 0, 0.35); 77 | border: 1px solid rgba(0, 0, 0, 0.13); 78 | border-radius: 3px; 79 | } 80 | .accordion-group { 81 | border: 1px solid #e9e9e9; 82 | border-radius: 4px; 83 | } 84 | .tab-content { 85 | border-radius: 0 0 4px 4px; 86 | } 87 | .accordion-group, .tab-content { 88 | box-shadow: 0px 2px 5px -2px rgba(0, 0, 0, 0.32); 89 | background: white; 90 | margin-bottom: 10px; 91 | } 92 | textarea:focus, input[type="text"]:focus, input[type="password"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="date"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="week"]:focus, input[type="number"]:focus, input[type="email"]:focus, input[type="url"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="color"]:focus, .uneditable-input:focus { 93 | background: white; 94 | box-shadow: none !important; 95 | border-color: #2196F3; 96 | } 97 | .slider .slider-track, 98 | #settings_dialog .tab-content { 99 | box-shadow: none; 100 | } 101 | .slider .slider-selection { 102 | background: #2196F3; 103 | border: none; 104 | box-shadow: none; 105 | } 106 | .nav>li>a { 107 | color: inherit; 108 | } 109 | .legendColorBox > div { 110 | border-radius: 50%; 111 | padding: 0 !important; 112 | border: 0 !important; 113 | } 114 | .legendColorBox > div > div { 115 | border-radius: 50%; 116 | width: 0px !important; 117 | height: 0px !important; 118 | padding: 0 !important; 119 | } 120 | #navbar .navbar-inner { 121 | background-image: none !important; 122 | box-shadow: 0 4px 6px -4px rgba(0, 0, 0, 0.47) !important; 123 | border: none !important; 124 | } 125 | #navbar .navbar-inner .nav>li>a:hover { 126 | background: rgba(128, 128, 128, 0.5) !important; 127 | } 128 | #navbar .navbar-inner .brand, #navbar .navbar-inner .nav>li>a { 129 | text-shadow: none !important; 130 | } 131 | .navbar .brand { 132 | text-shadow: none !important; 133 | } 134 | #navbar .navbar-inner .nav>li.dropdown.active>.dropdown-toggle, #navbar .navbar-inner .nav>li.dropdown.open.active>.dropdown-toggle, #navbar .navbar-inner .nav>li.dropdown.open>.dropdown-toggle { 135 | background: rgba(255,255,255, 0.3) !important; 136 | } 137 | .modal.fade { 138 | box-shadow: 0 30px 50px -30px rgba(0, 0, 0, 0.76) !important; 139 | border: 0 !important; 140 | } 141 | .nav-list, .nav-pills { 142 | >.active>a, >.active>a:hover { 143 | background-color: #2196F3; 144 | color: #ffffff; 145 | } 146 | } 147 | .modal-footer { 148 | border: 0; 149 | } 150 | textarea, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], .uneditable-input { 151 | box-shadow: none; 152 | } 153 | .modal-backdrop, .modal-backdrop.fade.in { 154 | background: black; 155 | } 156 | #temperature-graph { 157 | background-image: none !important; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /octoprint_themeify/static/less/nighttime/nighttime.less: -------------------------------------------------------------------------------- 1 | .nighttime() { 2 | body { 3 | background-color: #232629; 4 | color: #BAC0C6; 5 | font-weight: 400; 6 | line-height: 24px; 7 | 8 | @media (max-width: 767px) { 9 | padding: 0; 10 | } 11 | } 12 | 13 | ul.nav, .nav-pills { 14 | li { 15 | a { 16 | color: #fff; 17 | opacity: 0.7; 18 | text-shadow: none; 19 | text-decoration: none; 20 | background: none; 21 | 22 | .caret { 23 | border-top-color: #fff; 24 | } 25 | 26 | &:hover, &.on { 27 | opacity: 1; 28 | } 29 | &:hover { 30 | background: none rgba(0,0,0,0.1); 31 | } 32 | } 33 | &.open > a, &.active > a { 34 | opacity: 1; 35 | background: none rgba(0,0,0,0.1); 36 | } 37 | } 38 | } 39 | 40 | #navbar { 41 | &.navbar-fixed-top, &.navbar-fixed-bottom, &.navbar-static-top { 42 | margin: 0; 43 | } 44 | .navbar-inner { 45 | background: none #34383C; 46 | box-shadow: none; 47 | border: 0; 48 | color: #fff; 49 | 50 | a { 51 | padding: 16px 15px; 52 | text-shadow: none; 53 | color: #fff; 54 | text-decoration: none; 55 | background: none; 56 | 57 | &:hover { 58 | background: none rgba(0,0,0,0.1); 59 | } 60 | 61 | &.disabled { 62 | color: #232629; 63 | opacity: .5; 64 | cursor: not-allowed; 65 | } 66 | } 67 | 68 | ul.nav { 69 | font: inherit; 70 | 71 | li { 72 | font: inherit; 73 | a { 74 | font: inherit; 75 | 76 | &#psucontrol_indicator { 77 | &.off i { 78 | color: #fff; 79 | opacity: 0.5; 80 | text-shadow: none; 81 | } 82 | } 83 | 84 | .caret { 85 | border-top-color: #fff; 86 | } 87 | &:hover, &.on { 88 | opacity: 1; 89 | } 90 | &:hover { 91 | background: none rgba(0,0,0,0.1); 92 | } 93 | } 94 | &.open > a, &.active > a { 95 | opacity: 1; 96 | background: none rgba(0,0,0,0.1) !important; 97 | } 98 | } 99 | 100 | @media (max-width: 767px) { 101 | } 102 | } 103 | 104 | a.brand { 105 | padding: 16px 15px 12px; 106 | padding-left: 20px; 107 | } 108 | .btn-navbar { 109 | padding: 20px 15px; 110 | text-shadow: none; 111 | color: #fff; 112 | border: 0; 113 | margin: 0; 114 | background: none; 115 | opacity: 0.7; 116 | 117 | .icon-bar { 118 | box-shadow: none; 119 | color: inherit; 120 | } 121 | 122 | &:hover { 123 | opacity: 1; 124 | background: none rgba(0,0,0,0.1); 125 | } 126 | } 127 | 128 | 129 | &.transparent { 130 | background-color: transparent; 131 | 132 | ul.nav li { 133 | 134 | & > a { 135 | color: #fff; 136 | text-shadow: none; 137 | 138 | &:hover { 139 | background: none rgba(0,0,0,0.1); 140 | } 141 | } 142 | 143 | &.open > a, &.active > a { 144 | opacity: 1; 145 | background: none rgba(0,0,0,0.1); 146 | } 147 | } 148 | } 149 | &.red { 150 | background-color: #AA2A29; 151 | 152 | &#psucontrol_indicator { 153 | &.off i { 154 | color: rgba(0,0,0,0.5); 155 | text-shadow: none; 156 | } 157 | } 158 | } 159 | &.blue { 160 | background-color: #276ABB; 161 | 162 | &#psucontrol_indicator { 163 | &.off i { 164 | color: rgba(0,0,0,0.5); 165 | text-shadow: none; 166 | } 167 | } 168 | } 169 | &.green { 170 | background-color: #088E37; 171 | 172 | &#psucontrol_indicator { 173 | &.off i { 174 | color: rgba(0,0,0,0.5); 175 | text-shadow: none; 176 | } 177 | } 178 | } 179 | } 180 | 181 | #navbar_login { 182 | &.open { 183 | @media (max-width: 767px) { 184 | input[type="text"], input[type="password"] { 185 | width: 100%; 186 | } 187 | & > a { 188 | margin-bottom: 0; 189 | border-bottom-left-radius: 0; 190 | border-bottom-right-radius: 0; 191 | } 192 | #login_dropdown_loggedout { 193 | box-shadow: none; 194 | background-color: rgba(0,0,0,0.1); 195 | border-bottom-left-radius: 2px; 196 | border-bottom-right-radius: 2px; 197 | margin: 0; 198 | } 199 | } 200 | } 201 | } 202 | 203 | } 204 | 205 | ul.dropdown-menu { 206 | li { 207 | &>a { 208 | padding: 6px 20px; 209 | } 210 | &.divider { 211 | border: 0; 212 | background-color: #40454A; 213 | padding: 0; 214 | margin: 10px 0; 215 | } 216 | } 217 | } 218 | 219 | .octoprint-container { 220 | margin: 0 auto; 221 | padding: 20px; 222 | 223 | @media (max-width: 767px) { 224 | padding: 20px; 225 | } 226 | 227 | .tabbable { 228 | ul.nav-tabs { 229 | border-bottom: 1px solid #40454A; 230 | 231 | ul.dropdown-menu { 232 | margin-top: 0; 233 | } 234 | 235 | li { 236 | margin-right: 4px; 237 | a { 238 | border: 0; 239 | color: #fff; 240 | opacity: 0.7; 241 | margin: 0; 242 | text-decoration: none; 243 | 244 | .caret { 245 | border-top-color: #fff; 246 | } 247 | 248 | &:hover { 249 | background-color: #40454A; 250 | opacity: 1; 251 | } 252 | } 253 | 254 | &.active { 255 | a { 256 | background-color: #40454A; 257 | color: #fff; 258 | opacity: 1; 259 | } 260 | } 261 | } 262 | } 263 | .tab-content { 264 | border: 0; 265 | 266 | @media (max-width: 767px) { 267 | padding-top: 20px; 268 | 269 | #gcode { 270 | .layer-buttons { 271 | .btn { 272 | margin-bottom: 5px; 273 | 274 | &:last-child { 275 | margin-bottom: 0; 276 | } 277 | } 278 | } 279 | } 280 | } 281 | } 282 | } 283 | 284 | .accordion { 285 | 286 | background-color: #34383C; 287 | border-radius: 4px; 288 | overflow: hidden; 289 | 290 | .accordion-group { 291 | margin: 0; 292 | padding: 0; 293 | border: 0; 294 | 295 | .accordion-heading { 296 | background-color: #40454A; 297 | 298 | a.accordion-toggle { 299 | color: #fff; 300 | opacity: 0.7; 301 | text-decoration: none; 302 | 303 | [class*=" icon-"], [class^=icon-] { 304 | color: inherit; 305 | padding-right: 3px; 306 | } 307 | 308 | &:hover { 309 | opacity: 1; 310 | } 311 | } 312 | .accordion-heading-button { 313 | color: inherit; 314 | 315 | a { 316 | color: #fff; 317 | opacity: 0.7; 318 | 319 | [class^=icon-] { 320 | color: inherit; 321 | } 322 | &:hover { 323 | opacity: 1; 324 | } 325 | } 326 | } 327 | } 328 | .accordion-body { 329 | .accordion-inner { 330 | border: 0; 331 | padding: 20px; 332 | 333 | > span { 334 | opacity: 0.6; 335 | } 336 | 337 | strong { 338 | font-weight: normal; 339 | } 340 | } 341 | 342 | &#connection { 343 | } 344 | 345 | &#state { 346 | 347 | hr { 348 | border: 0; 349 | border-top: 1px solid #40454A; 350 | padding: 0; 351 | margin: 10px 0; 352 | } 353 | 354 | .print-control { 355 | 356 | @media (max-width: 979px) { 357 | display: block; 358 | 359 | button.btn { 360 | margin: 0; 361 | margin-bottom: 10px; 362 | width: 100%; 363 | 364 | &:last-child { 365 | margin-bottom: 0; 366 | } 367 | } 368 | } 369 | } 370 | } 371 | 372 | &#files { 373 | form.form-search input.search-query { 374 | width: 100%; 375 | } 376 | .slimScrollDiv { 377 | margin-top: 10px; 378 | 379 | .slimScrollRail { 380 | opacity: 0; 381 | } 382 | 383 | .gcode_files { 384 | padding-right: 12px; 385 | } 386 | .entry { 387 | padding: 15px 0; 388 | border: 0; 389 | border-top: 1px solid #40454A; 390 | 391 | .title { 392 | color: #fff; 393 | font-weight: normal; 394 | 395 | &.text-info, &.text-success, &.text-warning, &.text-error { 396 | &::before { 397 | display: block; 398 | float: left; 399 | content: ''; 400 | background-color: rgba(255,255,255,0.3); 401 | margin: 5px 10px 5px 0; 402 | height: 9px; 403 | width: 9px; 404 | border-radius: 5px; 405 | } 406 | } 407 | 408 | &.text-success::before { 409 | background-color: #00CE48; 410 | } 411 | &.text-warning::before { 412 | background-color: #D6B41A; 413 | } 414 | &.text-error::before { 415 | background-color: #AA2A29; 416 | } 417 | } 418 | 419 | 420 | &:nth-child(2) { 421 | border-top: 0; 422 | } 423 | 424 | &:hover { 425 | background: none; 426 | } 427 | } 428 | } 429 | 430 | .upload-buttons { 431 | .fileinput-button input { 432 | opacity: 0; 433 | } 434 | @media (max-width: 1200px) { 435 | display: block; 436 | 437 | .btn { 438 | margin: 0; 439 | margin-bottom: 10px; 440 | width: 100%; 441 | 442 | &:last-child { 443 | margin-bottom: 0; 444 | } 445 | } 446 | } 447 | } 448 | } 449 | } 450 | } 451 | } 452 | } 453 | 454 | h1 { 455 | color: #fff; 456 | border-bottom: 1px solid #40454A; 457 | } 458 | 459 | .help-block, .help-inline { 460 | color: rgba(255,255,255,0.7); 461 | } 462 | 463 | button.btn, .btn { 464 | border: 0; 465 | background: none #40454A; 466 | text-shadow: none; 467 | box-shadow: none; 468 | text-decoration: none; 469 | border-radius: 2px; 470 | color: #fff; 471 | opacity: 0.7; 472 | padding: 8px 16px; 473 | box-shadow: 0 0 0 1px rgba(0,0,0,0.1); 474 | 475 | .caret { 476 | border-top-color: #fff; 477 | } 478 | 479 | &.btn-mini { 480 | margin: 1px; 481 | padding: 2px 6px; 482 | } 483 | 484 | &:hover { 485 | opacity: 1; 486 | } 487 | 488 | &[disabled], &.disabled, .disabled & { 489 | background-color: #40454A; 490 | color: #232629; 491 | opacity: .5; 492 | cursor: not-allowed; 493 | pointer-events: none; 494 | 495 | .caret { 496 | border-top-color: #232629; 497 | border-bottom-color: #232629; 498 | } 499 | } 500 | 501 | &.btn-primary { 502 | background-color: #0073FF; 503 | } 504 | &.btn-danger { 505 | background-color: #AA2A29; 506 | } 507 | 508 | &#printer_connect { 509 | margin-top: 20px; 510 | } 511 | } 512 | 513 | .modal, .hero-unit { 514 | overflow: hidden; 515 | background-color: #34383C; 516 | border: 0; 517 | box-shadow: 0 0 0 1px rgba(0,0,0,0.1), 3px 0 30px 0 rgba(0,0,0,0.2); 518 | 519 | .modal-header { 520 | background-color: #40454A; 521 | border: 0; 522 | padding: 20px; 523 | 524 | .close { 525 | border: 0; 526 | background: none #40454A; 527 | text-shadow: none; 528 | box-shadow: none; 529 | text-decoration: none; 530 | border-radius: 2px; 531 | color: #fff; 532 | opacity: 0.7; 533 | padding: 4px 16px 12px 16px; 534 | margin: 0; 535 | 536 | &:hover { 537 | opacity: 1; 538 | } 539 | } 540 | } 541 | .modal-footer { 542 | background-color: #34383C; 543 | box-shadow: none; 544 | border: 0; 545 | padding: 20px; 546 | } 547 | .modal-body { 548 | padding: 20px; 549 | } 550 | } 551 | 552 | .modal-backdrop, #offline_overlay_background, #reloadui_overlay_background { 553 | background-color: #232629; 554 | } 555 | 556 | h1 { 557 | 558 | } 559 | h2 { 560 | 561 | } 562 | h3 { 563 | font-size: 18px; 564 | color: #fff; 565 | font-weight: normal; 566 | } 567 | h4,legend { 568 | font-size: 14px; 569 | color: #fff; 570 | font-weight: bold; 571 | border: 0; 572 | } 573 | 574 | .dropdown-menu { 575 | overflow: hidden; 576 | background-color: #34383C; 577 | border: 0; 578 | box-shadow: 0 0 0 1px rgba(0,0,0,0.1), 3px 0 30px 0 rgba(0,0,0,0.2); 579 | } 580 | 581 | ul.nav-list { 582 | text-decoration: none; 583 | 584 | li { 585 | text-shadow: none; 586 | margin-bottom: 2px; 587 | 588 | &.nav-header { 589 | padding-left: 0; 590 | } 591 | 592 | a { 593 | text-shadow: none; 594 | border-radius: 2px; 595 | border: 0; 596 | color: #fff; 597 | opacity: 0.7; 598 | margin: 0; 599 | text-decoration: none; 600 | 601 | &:hover, &:active, &:focus { 602 | background-color: #40454A; 603 | opacity: 1; 604 | } 605 | } 606 | 607 | &.active { 608 | a { 609 | background-color: #40454A; 610 | color: #fff; 611 | opacity: 1; 612 | } 613 | } 614 | } 615 | } 616 | 617 | .input-append, .input-prepend { 618 | .add-on, .btn, .btn-group, .input-mini, input { 619 | border-radius: 0; 620 | margin: 1px 0; 621 | margin-left: 1px; 622 | height: auto; 623 | 624 | &:first-child { 625 | border-top-left-radius: 2px; 626 | border-bottom-left-radius: 2px; 627 | margin-left: 0; 628 | } 629 | 630 | &:last-child { 631 | border-top-right-radius: 2px; 632 | border-bottom-right-radius: 2px; 633 | } 634 | } 635 | .add-on { 636 | margin-left: 0; 637 | padding: 8px; 638 | background-color: #40454A; 639 | border: 0; 640 | text-shadow: none; 641 | opacity: 0.7; 642 | } 643 | } 644 | 645 | .btn-group { 646 | button.btn, .btn, .input-mini { 647 | border-radius: 0; 648 | margin: 1px 0; 649 | margin-left: 1px; 650 | height: auto; 651 | 652 | &:first-of-type { 653 | border-top-left-radius: 2px; 654 | border-bottom-left-radius: 2px; 655 | margin-left: 0; 656 | } 657 | &:last-of-type { 658 | border-top-right-radius: 2px; 659 | border-bottom-right-radius: 2px; 660 | } 661 | } 662 | } 663 | 664 | .input-block-level { 665 | &.input-append, &.input-prepend { 666 | .add-on, .btn, .btn-group, .input-mini, input { 667 | margin: 0; 668 | } 669 | } 670 | } 671 | input, textarea, select, .input-mini { 672 | background-color: #fff; 673 | border: 0; 674 | box-shadow: none; 675 | border-radius: 2px; 676 | text-decoration: none; 677 | box-sizing: border-box; 678 | padding: 9px 10px; 679 | line-height: 18px; 680 | height: auto; 681 | 682 | &[type="color"] { 683 | padding: 13px 10px; 684 | } 685 | 686 | &[disabled], &[readonly], &.uneditable-input { 687 | background-color: #40454A; 688 | color: #fff; 689 | opacity: 0.7; 690 | pointer-events:none; 691 | } 692 | } 693 | .disabled { 694 | input, textarea, select, .input-mini { 695 | background-color: #40454A; 696 | color: #fff; 697 | opacity: 0.7; 698 | pointer-events:none; 699 | } 700 | } 701 | select { 702 | -webkit-appearance: none; 703 | -moz-appearance: none; 704 | appearance: none; 705 | } 706 | pre { 707 | background-color: #40454A; 708 | color: #fff; 709 | border: 0; 710 | } 711 | .progress { 712 | background: none rgba(0,0,0,0.1); 713 | margin: 15px 0; 714 | box-shadow: none; 715 | 716 | .bar { 717 | background: none #00CE48; 718 | box-shadow: none; 719 | text-shadow: none; 720 | } 721 | } 722 | 723 | table { 724 | thead { 725 | } 726 | tbody { 727 | tr { 728 | td, th { 729 | border: 0; 730 | padding: 15px 5px; 731 | 732 | &[class$="_action"], &[class$="_actions"] { 733 | color: #40454A; 734 | 735 | a { 736 | color: #fff; 737 | opacity: 0.7; 738 | text-decoration: none; 739 | 740 | &:hover { 741 | opacity: 1; 742 | } 743 | &.disabled { 744 | color: #232629; 745 | opacity: .5; 746 | cursor: not-allowed; 747 | } 748 | } 749 | } 750 | 751 | } 752 | } 753 | } 754 | &.table-bordered { 755 | border: 0; 756 | 757 | tbody tr { 758 | th, td { 759 | border: 0; 760 | } 761 | } 762 | } 763 | 764 | &.table-hover { 765 | tbody tr { 766 | th, td { 767 | background-color: transparent; 768 | 769 | &:hover { 770 | background-color: transparent; 771 | } 772 | } 773 | } 774 | } 775 | 776 | &.table-striped { 777 | tbody tr:nth-child(even) { 778 | th, td { 779 | background-color: rgba(0,0,0,0.1); 780 | } 781 | } 782 | tbody tr:nth-child(odd) { 783 | th, td { 784 | background-color: transparent; 785 | } 786 | } 787 | } 788 | } 789 | a { 790 | color: #fff; 791 | opacity: 0.7; 792 | text-decoration: underline; 793 | 794 | &:hover, &:active, &:focus { 795 | text-decoration: none; 796 | opacity: 1; 797 | } 798 | } 799 | code { 800 | border: 1px solid #40454A; 801 | color: #fff; 802 | background: none; 803 | } 804 | .label, .badge { 805 | border: 0; 806 | text-shadow: none; 807 | background-color: #40454A; 808 | } 809 | 810 | .form-horizontal .controls { 811 | margin-bottom: 2px; 812 | } 813 | 814 | #temperature-graph { 815 | background-image: none !important; 816 | 817 | .legend { 818 | table { 819 | top: 16px; 820 | left: 41px !important; 821 | bottom: auto !important; 822 | tbody tr td { 823 | padding: 4px 0; 824 | 825 | &.legendColorBox { 826 | & > div { 827 | border: 0 !important; 828 | padding: 0 !important; 829 | border-radius: 2px; 830 | overflow: hidden; 831 | } 832 | } 833 | &.legendLabel { 834 | padding-left: 10px; 835 | padding-right: 10px; 836 | } 837 | } 838 | } 839 | } 840 | } 841 | 842 | .pagination { 843 | 844 | ul { 845 | 846 | box-shadow: none; 847 | 848 | li { 849 | a { 850 | border: 0; 851 | background: none #40454A; 852 | text-shadow: none; 853 | box-shadow: none; 854 | text-decoration: none; 855 | border-radius: 0; 856 | color: #fff; 857 | opacity: 0.7; 858 | padding: 8px 16px; 859 | margin-left: 1px; 860 | 861 | &:hover { 862 | opacity: 1; 863 | } 864 | } 865 | 866 | &.active a { 867 | opacity: 1; 868 | } 869 | 870 | &.disabled a { 871 | pointer-events: none; 872 | opacity: 0.7; 873 | } 874 | 875 | :first-child a { 876 | border-top-left-radius: 2px; 877 | border-bottom-left-radius: 2px; 878 | margin-left: 0; 879 | } 880 | 881 | :last-child a { 882 | border-top-right-radius: 2px; 883 | border-bottom-right-radius: 2px; 884 | } 885 | } 886 | } 887 | 888 | &.pagination-mini { 889 | ul li a { 890 | //padding: 2px 6px; 891 | } 892 | } 893 | } 894 | 895 | .ui-pnotify { 896 | h4 { 897 | color: inherit; 898 | } 899 | .alert { 900 | &.alert-success { 901 | 902 | } 903 | } 904 | .ui-pnotify-shadow { 905 | 906 | } 907 | } 908 | button#squishSettingsTabButton { 909 | width: 100%; 910 | margin-bottom: 20px; 911 | } 912 | #squishSettingsMenuList { 913 | margin-bottom: 20px; 914 | } 915 | 916 | #gcode .progress, #gcode .slider-horizontal { 917 | max-width: none; 918 | } 919 | #control { 920 | .box { 921 | height: auto; 922 | width: auto; 923 | padding-left: 12px; 924 | padding-right: 12px; 925 | } 926 | .control-box { 927 | height: auto; 928 | } 929 | } 930 | 931 | #gcode_canvas { 932 | width: 100%; 933 | height: 100%; 934 | } 935 | .icon-sd-black-14, #settings_api canvas { 936 | -webkit-filter: invert(100%); 937 | filter: invert(100%); 938 | } 939 | #settings_plugin_pluginmanager_workingdialog_output { 940 | .call { 941 | color: #fff; 942 | } 943 | 944 | .stdout { 945 | color: #fff; 946 | } 947 | } 948 | } 949 | -------------------------------------------------------------------------------- /octoprint_themeify/templates/themeify_settings.jinja2: -------------------------------------------------------------------------------- 1 |
2 |

General

3 |
4 |
5 | 6 |
7 | 10 |
11 |
12 | 15 |
16 |
17 | 20 |
21 | 22 |
23 |
24 | 25 |
26 | 34 |
35 |
36 | 37 |
38 | 39 |
40 |

Customization

41 |
42 |
43 | 44 |
45 | 46 | 47 | 48 |
49 |
50 |
51 |
52 |
53 |
54 | 55 | 56 | Advanced options 57 | 58 |
59 | 152 |
153 | 154 | 155 |
-------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Themeify", 3 | "version": "1.2.2", 4 | "description": "A plugin to change the looks of OctoPrint", 5 | "license": "AGPL-3.0", 6 | "scripts": { 7 | "build": "webpack -p", 8 | "clean": "rm -r octoprint_themeify/static/dist", 9 | "clean-css": "rm octoprint_themeify/static/dist/themeify.min.css", 10 | "watch": "webpack --watch" 11 | }, 12 | "devDependencies": { 13 | "@babel/core": "^7.0.0-beta.34", 14 | "@babel/preset-env": "^7.0.0-beta.34", 15 | "babel-loader": "8.0.0-beta.0", 16 | "css-loader": "^0.28.7", 17 | "extract-text-webpack-plugin": "^3.0.2", 18 | "less": "^2.7.3", 19 | "less-loader": "^4.0.5", 20 | "style-loader": "^0.19.0", 21 | "webpack": "^3.10.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ### 2 | # This file is only here to make sure that something like 3 | # 4 | # pip install -e . 5 | # 6 | # works as expected. Requirements can be found in setup.py. 7 | ### 8 | 9 | . 10 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | plugin_identifier = "themeify" 4 | 5 | plugin_package = "octoprint_themeify" 6 | 7 | plugin_name = "Themeify" 8 | 9 | plugin_version = "1.2.2" 10 | 11 | plugin_description = """Beautiful themes for octoprint""" 12 | 13 | plugin_author = "Birk Johansson" 14 | 15 | plugin_author_email = "birkbjo@gmail.com" 16 | 17 | plugin_url = "https://github.com/birkbjo/OctoPrint-Themeify" 18 | 19 | plugin_license = "AGPLv3" 20 | 21 | plugin_requires = [] 22 | 23 | 24 | plugin_additional_data = [] 25 | plugin_additional_packages = [] 26 | plugin_ignored_packages = [] 27 | additional_setup_parameters = {} 28 | 29 | from setuptools import setup 30 | 31 | try: 32 | import octoprint_setuptools 33 | except: 34 | print("Could not import OctoPrint's setuptools, are you sure you are running that under " 35 | "the same python installation that OctoPrint is installed under?") 36 | import sys 37 | sys.exit(-1) 38 | 39 | setup_parameters = octoprint_setuptools.create_plugin_setup_parameters( 40 | identifier=plugin_identifier, 41 | package=plugin_package, 42 | name=plugin_name, 43 | version=plugin_version, 44 | description=plugin_description, 45 | author=plugin_author, 46 | mail=plugin_author_email, 47 | url=plugin_url, 48 | license=plugin_license, 49 | requires=plugin_requires, 50 | additional_packages=plugin_additional_packages, 51 | ignored_packages=plugin_ignored_packages, 52 | additional_data=plugin_additional_data 53 | ) 54 | 55 | if len(additional_setup_parameters): 56 | from octoprint.util import dict_merge 57 | setup_parameters = dict_merge(setup_parameters, additional_setup_parameters) 58 | 59 | setup(**setup_parameters) 60 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const webpack = require("webpack"); 3 | const ExtractTextPlugin = require("extract-text-webpack-plugin"); 4 | const isProd = process.argv.indexOf("-p") > -1; 5 | const staticPath = path.resolve(__dirname, "octoprint_themeify/static"); 6 | module.exports = { 7 | entry: [ 8 | path.join(staticPath, "js", "themeify.js"), 9 | path.join(staticPath, "less", "base.less") 10 | ], 11 | output: { 12 | filename: "themeify.min.js", 13 | path: path.join(staticPath, "dist") 14 | }, 15 | devtool: isProd ? 'false' : 'inline-source-map', 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.js$/, 20 | exclude: /(node_modules|bower_components)/, 21 | use: { 22 | loader: "babel-loader", 23 | options: { 24 | presets: ["@babel/preset-env"] 25 | } 26 | } 27 | }, 28 | { 29 | test: /\.less$/, 30 | use: ExtractTextPlugin.extract({ 31 | use: [ 32 | { 33 | loader: "css-loader", 34 | options: { url: false, minimize: true } 35 | }, 36 | { 37 | loader: "less-loader" 38 | } 39 | ], 40 | fallback: "style-loader" 41 | }) 42 | } 43 | ] 44 | }, 45 | plugins: [ 46 | new webpack.optimize.UglifyJsPlugin({ 47 | minimize: isProd, 48 | comments: false 49 | }), 50 | new ExtractTextPlugin({ 51 | filename: "../dist/themeify.min.css", 52 | disable: false, 53 | allChunks: true 54 | }) 55 | ] 56 | }; 57 | --------------------------------------------------------------------------------