├── assets ├── scss │ └── addr │ │ ├── spectre │ │ ├── _formswitcher.scss │ │ ├── utilities │ │ │ ├── _shapes.scss │ │ │ ├── _cursors.scss │ │ │ ├── _display.scss │ │ │ ├── _loading.scss │ │ │ ├── _position.scss │ │ │ ├── _colors.scss │ │ │ ├── _text.scss │ │ │ └── _divider.scss │ │ ├── mixins │ │ │ ├── _avatar.scss │ │ │ ├── _text.scss │ │ │ ├── _clearfix.scss │ │ │ ├── _toast.scss │ │ │ ├── _shadow.scss │ │ │ ├── _label.scss │ │ │ ├── _color.scss │ │ │ ├── _button.scss │ │ │ └── _position.scss │ │ ├── _icons.scss │ │ ├── _utilities.scss │ │ ├── _mixins.scss │ │ ├── spectre-icons.scss │ │ ├── _animations.scss │ │ ├── _hero.scss │ │ ├── _empty.scss │ │ ├── _panels.scss │ │ ├── spectre-exp.scss │ │ ├── _navbar.scss │ │ ├── _breadcrumbs.scss │ │ ├── _codes.scss │ │ ├── _navs.scss │ │ ├── _chips.scss │ │ ├── _tiles.scss │ │ ├── _accordions.scss │ │ ├── _asian.scss │ │ ├── _dropdowns.scss │ │ ├── _labels.scss │ │ ├── _filters.scss │ │ ├── _viewer-360.scss │ │ ├── _base.scss │ │ ├── _cards.scss │ │ ├── _toasts.scss │ │ ├── _autocomplete.scss │ │ ├── icons │ │ │ ├── _icons-core.scss │ │ │ ├── _icons-navigation.scss │ │ │ ├── _icons-object.scss │ │ │ └── _icons-action.scss │ │ ├── _tables.scss │ │ ├── _progress.scss │ │ ├── _pagination.scss │ │ ├── _timelines.scss │ │ ├── _meters.scss │ │ ├── _badges.scss │ │ ├── spectre.scss │ │ ├── _tabs.scss │ │ ├── _popovers.scss │ │ ├── _menus.scss │ │ ├── _media.scss │ │ ├── _bars.scss │ │ ├── _steps.scss │ │ ├── _avatars.scss │ │ ├── _modals.scss │ │ ├── _tooltips.scss │ │ ├── _off-canvas.scss │ │ ├── _typography.scss │ │ ├── _sliders.scss │ │ ├── _comparison-sliders.scss │ │ ├── _carousels.scss │ │ ├── _parallax.scss │ │ ├── _buttons.scss │ │ ├── _variables.scss │ │ ├── _calendars.scss │ │ ├── _layout.scss │ │ └── _normalize.scss │ │ ├── _boxes.scss │ │ ├── _loading.scss │ │ ├── _openlayers.scss │ │ ├── _animation.scss │ │ ├── _orderlayer.scss │ │ ├── _tools.scss │ │ ├── _call.scss │ │ ├── _modals.scss │ │ ├── _smartbox.scss │ │ ├── _dashboardtable.scss │ │ ├── _menubar.scss │ │ ├── _login.scss │ │ ├── _progressbar.scss │ │ ├── _infocards.scss │ │ ├── core.scss │ │ ├── _realledger.scss │ │ └── _form.scss └── scss.bat ├── release ├── media │ ├── gong.mp3 │ ├── gong.ogg │ ├── complete.mp3 │ └── complete.ogg ├── index.html └── js │ ├── remote.js │ └── progressbar.js ├── src ├── tools │ ├── timerbar.cljs │ └── time.cljs └── addfocus │ ├── default.cljs │ ├── helpers.cljs │ ├── subs.cljs │ ├── masterview.cljs │ └── events.cljs ├── .gitignore ├── package.json ├── shadow-cljs.edn └── readme.md /assets/scss/addr/spectre/_formswitcher.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/scss.bat: -------------------------------------------------------------------------------- 1 | sass --watch scss/addr/addr.scss ../release/css/app.css -------------------------------------------------------------------------------- /release/media/gong.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metehan/adhd-focus/HEAD/release/media/gong.mp3 -------------------------------------------------------------------------------- /release/media/gong.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metehan/adhd-focus/HEAD/release/media/gong.ogg -------------------------------------------------------------------------------- /release/media/complete.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metehan/adhd-focus/HEAD/release/media/complete.mp3 -------------------------------------------------------------------------------- /release/media/complete.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metehan/adhd-focus/HEAD/release/media/complete.ogg -------------------------------------------------------------------------------- /assets/scss/addr/spectre/utilities/_shapes.scss: -------------------------------------------------------------------------------- 1 | // Shapes 2 | .s-rounded { 3 | border-radius: $border-radius; 4 | } 5 | 6 | .s-circle { 7 | border-radius: 50%; 8 | } -------------------------------------------------------------------------------- /assets/scss/addr/spectre/mixins/_avatar.scss: -------------------------------------------------------------------------------- 1 | // Avatar mixin 2 | @mixin avatar-base($size: $unit-8) { 3 | font-size: $size / 2; 4 | height: $size; 5 | width: $size; 6 | } 7 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/mixins/_text.scss: -------------------------------------------------------------------------------- 1 | // Text Ellipsis 2 | @mixin text-ellipsis() { 3 | overflow: hidden; 4 | text-overflow: ellipsis; 5 | white-space: nowrap; 6 | } 7 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_icons.scss: -------------------------------------------------------------------------------- 1 | // CSS Icons 2 | @import "icons/icons-core"; 3 | @import "icons/icons-navigation"; 4 | @import "icons/icons-action"; 5 | @import "icons/icons-object"; -------------------------------------------------------------------------------- /assets/scss/addr/spectre/mixins/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // Clearfix mixin 2 | @mixin clearfix() { 3 | &::after { 4 | clear: both; 5 | content: ""; 6 | display: table; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/mixins/_toast.scss: -------------------------------------------------------------------------------- 1 | // Toast variant mixin 2 | @mixin toast-variant($color: $dark-color) { 3 | background: rgba($color, .95); 4 | border-color: $color; 5 | } 6 | -------------------------------------------------------------------------------- /src/tools/timerbar.cljs: -------------------------------------------------------------------------------- 1 | (ns tools.timerbar) 2 | 3 | (defn update-bar [percent] 4 | (let [grower (.getElementsByClassName js/document "growing-bar")] 5 | (for [x (js->clj grower)] 6 | (set! (.-width (.-style x)) (str percent "%"))))) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .cpcache 2 | .nrepl-port 3 | .idea 4 | .vscode 5 | 6 | node_modules 7 | package-lock.json 8 | 9 | pom.xml 10 | pom.xml.asc 11 | *.iml 12 | *.jar 13 | *.log 14 | .shadow-cljs 15 | .idea 16 | .lein-* 17 | .nrepl-* 18 | .DS_Store 19 | .hgignore 20 | .hg/ -------------------------------------------------------------------------------- /assets/scss/addr/_boxes.scss: -------------------------------------------------------------------------------- 1 | .boxed { 2 | background-color: white; 3 | border-radius: $unit-1; 4 | margin: $unit-2 ; 5 | padding: $unit-2; 6 | border: $visible-light solid $unit-o; 7 | 8 | &.nb { 9 | border: none; 10 | padding: 0; 11 | } 12 | } -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_utilities.scss: -------------------------------------------------------------------------------- 1 | @import "utilities/colors"; 2 | @import "utilities/cursors"; 3 | @import "utilities/display"; 4 | @import "utilities/divider"; 5 | @import "utilities/loading"; 6 | @import "utilities/position"; 7 | @import "utilities/shapes"; 8 | @import "utilities/text"; 9 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | @import "mixins/avatar"; 3 | @import "mixins/button"; 4 | @import "mixins/clearfix"; 5 | @import "mixins/color"; 6 | @import "mixins/label"; 7 | @import "mixins/position"; 8 | @import "mixins/shadow"; 9 | @import "mixins/text"; 10 | @import "mixins/toast"; -------------------------------------------------------------------------------- /assets/scss/addr/spectre/mixins/_shadow.scss: -------------------------------------------------------------------------------- 1 | // Component focus shadow 2 | @mixin control-shadow($color: $primary-color) { 3 | box-shadow: 0 0 0 .1rem rgba($color, .2); 4 | } 5 | 6 | // Shadow mixin 7 | @mixin shadow-variant($offset) { 8 | box-shadow: 0 $offset ($offset + .05rem) * 2 rgba($dark-color, .3); 9 | } 10 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/mixins/_label.scss: -------------------------------------------------------------------------------- 1 | // Label base style 2 | @mixin label-base() { 3 | border-radius: $border-radius; 4 | line-height: 1.25; 5 | padding: .1rem .2rem; 6 | } 7 | 8 | @mixin label-variant($color: $light-color, $bg-color: $primary-color) { 9 | background: $bg-color; 10 | color: $color; 11 | } 12 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/spectre-icons.scss: -------------------------------------------------------------------------------- 1 | // Variables and mixins 2 | @import "variables"; 3 | @import "mixins"; 4 | 5 | /*! Spectre.css Icons v#{$version} | MIT License | github.com/picturepan2/spectre */ 6 | // Icons 7 | @import "icons/icons-core"; 8 | @import "icons/icons-navigation"; 9 | @import "icons/icons-action"; 10 | @import "icons/icons-object"; 11 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/utilities/_cursors.scss: -------------------------------------------------------------------------------- 1 | // Cursors 2 | .c-hand { 3 | cursor: pointer; 4 | } 5 | 6 | .c-move { 7 | cursor: move; 8 | } 9 | 10 | .c-zoom-in { 11 | cursor: zoom-in; 12 | } 13 | 14 | .c-zoom-out { 15 | cursor: zoom-out; 16 | } 17 | 18 | .c-not-allowed { 19 | cursor: not-allowed; 20 | } 21 | 22 | .c-auto { 23 | cursor: auto; 24 | } -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_animations.scss: -------------------------------------------------------------------------------- 1 | // Animations 2 | @keyframes loading { 3 | 0% { 4 | transform: rotate(0deg); 5 | } 6 | 100% { 7 | transform: rotate(360deg); 8 | } 9 | } 10 | 11 | @keyframes slide-down { 12 | 0% { 13 | opacity: 0; 14 | transform: translateY(-$unit-8); 15 | } 16 | 100% { 17 | opacity: 1; 18 | transform: translateY(0); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "addfocus", 3 | "version": "0.0.1", 4 | "private": true, 5 | "devDependencies": { 6 | "shadow-cljs": "2.8.51" 7 | }, 8 | "dependencies": { 9 | "apexcharts": "^3.15.5", 10 | "create-react-class": "^15.6.3", 11 | "react": "^16.9.0", 12 | "react-dom": "^16.9.0", 13 | "react-flip-move": "^3.0.4", 14 | "react-highlight.js": "^1.0.7" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_hero.scss: -------------------------------------------------------------------------------- 1 | // Hero 2 | .hero { 3 | display: flex; 4 | flex-direction: column; 5 | justify-content: space-between; 6 | padding-bottom: 4rem; 7 | padding-top: 4rem; 8 | 9 | &.hero-sm { 10 | padding-bottom: 2rem; 11 | padding-top: 2rem; 12 | } 13 | 14 | &.hero-lg { 15 | padding-bottom: 8rem; 16 | padding-top: 8rem; 17 | } 18 | 19 | .hero-body { 20 | padding: $layout-spacing; 21 | } 22 | } -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_empty.scss: -------------------------------------------------------------------------------- 1 | // Empty states (or Blank slates) 2 | .empty { 3 | background: $bg-color; 4 | border-radius: $border-radius; 5 | color: $gray-color-dark; 6 | text-align: center; 7 | padding: $unit-16 $unit-8; 8 | 9 | .empty-icon { 10 | margin-bottom: $layout-spacing-lg; 11 | } 12 | 13 | .empty-title, 14 | .empty-subtitle { 15 | margin: $layout-spacing auto; 16 | } 17 | 18 | .empty-action { 19 | margin-top: $layout-spacing-lg; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_panels.scss: -------------------------------------------------------------------------------- 1 | // Panels 2 | .panel { 3 | border: $border-width solid $border-color; 4 | border-radius: $border-radius; 5 | display: flex; 6 | flex-direction: column; 7 | 8 | .panel-header, 9 | .panel-footer { 10 | flex: 0 0 auto; 11 | padding: $layout-spacing-lg; 12 | } 13 | 14 | .panel-nav { 15 | flex: 0 0 auto; 16 | } 17 | 18 | .panel-body { 19 | flex: 1 1 auto; 20 | overflow-y: auto; 21 | padding: 0 $layout-spacing-lg; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/spectre-exp.scss: -------------------------------------------------------------------------------- 1 | // Variables and mixins 2 | @import "variables"; 3 | @import "mixins"; 4 | 5 | /*! Spectre.css Experimentals v#{$version} | MIT License | github.com/picturepan2/spectre */ 6 | // Experimentals 7 | @import "autocomplete"; 8 | @import "calendars"; 9 | @import "carousels"; 10 | @import "comparison-sliders"; 11 | @import "filters"; 12 | @import "meters"; 13 | @import "off-canvas"; 14 | @import "parallax"; 15 | @import "progress"; 16 | @import "sliders"; 17 | @import "timelines"; 18 | @import "viewer-360"; 19 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_navbar.scss: -------------------------------------------------------------------------------- 1 | // Navbar 2 | .navbar { 3 | align-items: stretch; 4 | display: flex; 5 | flex-wrap: wrap; 6 | justify-content: space-between; 7 | 8 | .navbar-section { 9 | align-items: center; 10 | display: flex; 11 | flex: 1 0 0; 12 | 13 | &:not(:first-child):last-child { 14 | justify-content: flex-end; 15 | } 16 | } 17 | 18 | .navbar-center { 19 | align-items: center; 20 | display: flex; 21 | flex: 0 0 auto; 22 | } 23 | 24 | .navbar-brand { 25 | font-size: $font-size-lg; 26 | text-decoration: none; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_breadcrumbs.scss: -------------------------------------------------------------------------------- 1 | // Breadcrumbs 2 | .breadcrumb { 3 | list-style: none; 4 | margin: $unit-1 0; 5 | padding: $unit-1 0; 6 | 7 | .breadcrumb-item { 8 | color: $gray-color-dark; 9 | display: inline-block; 10 | margin: 0; 11 | padding: $unit-1 0; 12 | 13 | &:not(:last-child) { 14 | margin-right: $unit-1; 15 | 16 | a { 17 | color: $gray-color-dark; 18 | } 19 | } 20 | 21 | &:not(:first-child) { 22 | &::before { 23 | color: $gray-color-dark; 24 | content: "/"; 25 | padding-right: $unit-2; 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/mixins/_color.scss: -------------------------------------------------------------------------------- 1 | // Background color utility mixin 2 | @mixin bg-color-variant($name: ".bg-primary", $color: $primary-color) { 3 | #{$name} { 4 | background: $color !important; 5 | 6 | @if (lightness($color) < 60) { 7 | color: $light-color; 8 | } 9 | } 10 | } 11 | 12 | // Text color utility mixin 13 | @mixin text-color-variant($name: ".text-primary", $color: $primary-color) { 14 | #{$name} { 15 | color: $color !important; 16 | } 17 | 18 | a#{$name} { 19 | &:focus, 20 | &:hover { 21 | color: darken($color, 5%); 22 | } 23 | &:visited { 24 | color: lighten($color, 5%); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_codes.scss: -------------------------------------------------------------------------------- 1 | // Codes 2 | code { 3 | @include label-base(); 4 | @include label-variant($code-color, lighten($code-color, 42.5%)); 5 | font-size: 85%; 6 | } 7 | 8 | .code { 9 | border-radius: $border-radius; 10 | color: $body-font-color; 11 | position: relative; 12 | 13 | &::before { 14 | color: $gray-color; 15 | content: attr(data-lang); 16 | font-size: $font-size-sm; 17 | position: absolute; 18 | right: $layout-spacing; 19 | top: $unit-h; 20 | } 21 | 22 | code { 23 | background: $bg-color; 24 | color: inherit; 25 | display: block; 26 | line-height: 1.5; 27 | overflow-x: auto; 28 | padding: 1rem; 29 | width: 100%; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_navs.scss: -------------------------------------------------------------------------------- 1 | // Navs 2 | .nav { 3 | display: flex; 4 | flex-direction: column; 5 | list-style: none; 6 | margin: $unit-1 0; 7 | 8 | .nav-item { 9 | a { 10 | color: $gray-color-dark; 11 | padding: $unit-1 $unit-2; 12 | text-decoration: none; 13 | &:focus, 14 | &:hover { 15 | color: $primary-color; 16 | } 17 | } 18 | &.active { 19 | & > a { 20 | color: darken($gray-color-dark, 10%); 21 | font-weight: bold; 22 | &:focus, 23 | &:hover { 24 | color: $primary-color; 25 | } 26 | } 27 | } 28 | } 29 | 30 | & .nav { 31 | margin-bottom: $unit-2; 32 | margin-left: $unit-4; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/addfocus/default.cljs: -------------------------------------------------------------------------------- 1 | (ns addfocus.default 2 | (:require 3 | [re-frame.core :as rf] 4 | [reagent.core :as r] 5 | [addfocus.masterview :as masterview] 6 | [addfocus.events] 7 | [addfocus.subs])) 8 | 9 | (defn load-data [context] 10 | (.loadRemoteData 11 | js/window 12 | context 13 | (fn [data] 14 | (rf/dispatch 15 | [:load-data (keyword context) (js->clj data :keywordize-keys true)]))) 16 | ) 17 | 18 | (defn ^:export render [] 19 | (r/render [masterview/index] 20 | (js/document.getElementById "app"))) 21 | 22 | (defn ^:export init [] 23 | (do 24 | (rf/dispatch-sync [:initialize]) 25 | (render) 26 | (.connectRemote js/window) 27 | (load-data "tasks") 28 | (load-data "history"))) 29 | 30 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_chips.scss: -------------------------------------------------------------------------------- 1 | // Chips 2 | .chip { 3 | align-items: center; 4 | background: $bg-color-dark; 5 | border-radius: 5rem; 6 | display: inline-flex; 7 | font-size: 90%; 8 | height: $unit-6; 9 | line-height: $unit-4; 10 | margin: $unit-h; 11 | max-width: $control-width-sm; 12 | overflow: hidden; 13 | padding: $unit-1 $unit-2; 14 | text-decoration: none; 15 | text-overflow: ellipsis; 16 | vertical-align: middle; 17 | white-space: nowrap; 18 | 19 | &.active { 20 | background: $primary-color; 21 | color: $light-color; 22 | } 23 | 24 | .avatar { 25 | margin-left: -$unit-2; 26 | margin-right: $unit-1; 27 | } 28 | 29 | .btn-clear { 30 | border-radius: 50%; 31 | transform: scale(.75); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_tiles.scss: -------------------------------------------------------------------------------- 1 | // Tiles 2 | .tile { 3 | align-content: space-between; 4 | align-items: flex-start; 5 | display: flex; 6 | 7 | .tile-icon, 8 | .tile-action { 9 | flex: 0 0 auto; 10 | } 11 | .tile-content { 12 | flex: 1 1 auto; 13 | &:not(:first-child) { 14 | padding-left: $unit-2; 15 | } 16 | &:not(:last-child) { 17 | padding-right: $unit-2; 18 | } 19 | } 20 | .tile-title, 21 | .tile-subtitle { 22 | line-height: $line-height; 23 | } 24 | 25 | &.tile-centered { 26 | align-items: center; 27 | 28 | .tile-content { 29 | overflow: hidden; 30 | } 31 | 32 | .tile-title, 33 | .tile-subtitle { 34 | @include text-ellipsis(); 35 | margin-bottom: 0; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_accordions.scss: -------------------------------------------------------------------------------- 1 | // Accordions 2 | .accordion { 3 | input:checked ~, 4 | &[open] { 5 | & .accordion-header { 6 | .icon { 7 | transform: rotate(90deg); 8 | } 9 | } 10 | 11 | & .accordion-body { 12 | max-height: 50rem; 13 | } 14 | } 15 | 16 | .accordion-header { 17 | display: block; 18 | padding: $unit-1 $unit-2; 19 | 20 | .icon { 21 | transition: transform .25s; 22 | } 23 | } 24 | 25 | .accordion-body { 26 | margin-bottom: $layout-spacing; 27 | max-height: 0; 28 | overflow: hidden; 29 | transition: max-height .25s; 30 | } 31 | } 32 | 33 | // Remove default details marker in Webkit 34 | summary.accordion-header { 35 | &::-webkit-details-marker { 36 | display: none; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_asian.scss: -------------------------------------------------------------------------------- 1 | // Optimized for East Asian CJK 2 | html:lang(zh), 3 | html:lang(zh-Hans), 4 | .lang-zh, 5 | .lang-zh-hans { 6 | font-family: $cjk-zh-hans-font-family; 7 | } 8 | 9 | html:lang(zh-Hant), 10 | .lang-zh-hant { 11 | font-family: $cjk-zh-hant-font-family; 12 | } 13 | 14 | html:lang(ja), 15 | .lang-ja { 16 | font-family: $cjk-jp-font-family; 17 | } 18 | 19 | html:lang(ko), 20 | .lang-ko { 21 | font-family: $cjk-ko-font-family; 22 | } 23 | 24 | :lang(zh), 25 | :lang(ja), 26 | .lang-cjk { 27 | ins, 28 | u { 29 | border-bottom: $border-width solid; 30 | text-decoration: none; 31 | } 32 | 33 | del + del, 34 | del + s, 35 | ins + ins, 36 | ins + u, 37 | s + del, 38 | s + s, 39 | u + ins, 40 | u + u { 41 | margin-left: .125em; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_dropdowns.scss: -------------------------------------------------------------------------------- 1 | // Dropdown 2 | .dropdown { 3 | display: inline-block; 4 | position: relative; 5 | 6 | .menu { 7 | animation: slide-down .15s ease 1; 8 | display: none; 9 | left: 0; 10 | max-height: 50vh; 11 | overflow-y: auto; 12 | position: absolute; 13 | top: 100%; 14 | } 15 | 16 | &.dropdown-right { 17 | .menu { 18 | left: auto; 19 | right: 0; 20 | } 21 | } 22 | 23 | &.active .menu, 24 | .dropdown-toggle:focus + .menu, 25 | .menu:hover { 26 | display: block; 27 | } 28 | 29 | // Fix dropdown-toggle border radius in button groups 30 | .btn-group { 31 | .dropdown-toggle:nth-last-child(2) { 32 | border-bottom-right-radius: $border-radius; 33 | border-top-right-radius: $border-radius; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/utilities/_display.scss: -------------------------------------------------------------------------------- 1 | // Display 2 | .d-block { 3 | display: block; 4 | } 5 | .d-inline { 6 | display: inline; 7 | } 8 | .d-inline-block { 9 | display: inline-block; 10 | } 11 | .d-flex { 12 | display: flex; 13 | } 14 | .d-inline-flex { 15 | display: inline-flex; 16 | } 17 | .d-none, 18 | .d-hide { 19 | display: none !important; 20 | } 21 | .d-visible { 22 | visibility: visible; 23 | } 24 | .d-invisible { 25 | visibility: hidden; 26 | } 27 | .text-hide { 28 | background: transparent; 29 | border: 0; 30 | color: transparent; 31 | font-size: 0; 32 | line-height: 0; 33 | text-shadow: none; 34 | } 35 | .text-assistive { 36 | border: 0; 37 | clip: rect(0,0,0,0); 38 | height: 1px; 39 | margin: -1px; 40 | overflow: hidden; 41 | padding: 0; 42 | position: absolute; 43 | width: 1px; 44 | } 45 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_labels.scss: -------------------------------------------------------------------------------- 1 | // Labels 2 | .label { 3 | @include label-base(); 4 | @include label-variant(lighten($body-font-color, 5%), $bg-color-dark); 5 | display: inline-block; 6 | 7 | // Label rounded 8 | &.label-rounded { 9 | border-radius: 5rem; 10 | padding-left: .4rem; 11 | padding-right: .4rem; 12 | } 13 | 14 | // Label colors 15 | &.label-primary { 16 | @include label-variant($light-color, $primary-color); 17 | } 18 | 19 | &.label-secondary { 20 | @include label-variant($primary-color, $secondary-color); 21 | } 22 | 23 | &.label-success { 24 | @include label-variant($light-color, $success-color); 25 | } 26 | 27 | &.label-warning { 28 | @include label-variant($light-color, $warning-color); 29 | } 30 | 31 | &.label-error { 32 | @include label-variant($light-color, $error-color); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_filters.scss: -------------------------------------------------------------------------------- 1 | // Filters 2 | // The number of filter options 3 | $filter-number: 8 !default; 4 | 5 | %filter-checked-nav { 6 | background: $primary-color; 7 | color: $light-color; 8 | } 9 | 10 | %filter-checked-body { 11 | display: none; 12 | } 13 | 14 | .filter { 15 | .filter-nav { 16 | margin: $layout-spacing 0; 17 | } 18 | 19 | .filter-body { 20 | display: flex; 21 | flex-wrap: wrap; 22 | } 23 | 24 | .filter-tag { 25 | @for $i from 0 through ($filter-number) { 26 | &#tag-#{$i}:checked ~ .filter-nav .chip[for="tag-#{$i}"] { 27 | @extend %filter-checked-nav; 28 | } 29 | } 30 | 31 | @for $i from 1 through ($filter-number) { 32 | &#tag-#{$i}:checked ~ .filter-body .filter-item:not([data-tag~="tag-#{$i}"]) { 33 | @extend %filter-checked-body; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_viewer-360.scss: -------------------------------------------------------------------------------- 1 | // 360 Degree Viewer 2 | 3 | // Mixin: Viewer slider sizes 4 | @mixin viewer-slider-size($image-number: 36) { 5 | @for $s from 1 through ($image-number) { 6 | .viewer-slider[max='#{$image-number}'][value='#{$s}'] + .viewer-image { 7 | background-position-y: percentage((($s)-1) * 1/(($image-number)-1)); 8 | } 9 | } 10 | } 11 | 12 | .viewer-360 { 13 | align-items: center; 14 | display: flex; 15 | flex-direction: column; 16 | 17 | // Copy and add more numbers if you need 18 | @include viewer-slider-size(36); 19 | 20 | .viewer-slider { 21 | cursor: ew-resize; 22 | margin: 1rem; 23 | order: 2; 24 | width: 60%; 25 | } 26 | 27 | .viewer-image { 28 | background-position-y: 0; 29 | background-repeat: no-repeat; 30 | background-size: 100%; 31 | max-width: 100%; 32 | order: 1; 33 | } 34 | } -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_base.scss: -------------------------------------------------------------------------------- 1 | // Base 2 | *, 3 | *::before, 4 | *::after { 5 | box-sizing: inherit; 6 | } 7 | 8 | html { 9 | box-sizing: border-box; 10 | font-size: $html-font-size; 11 | line-height: $html-line-height; 12 | -webkit-tap-highlight-color: transparent; 13 | } 14 | 15 | body { 16 | background: $body-bg; 17 | color: $body-font-color; 18 | font-family: $body-font-family; 19 | font-size: $font-size; 20 | overflow-x: hidden; 21 | text-rendering: optimizeLegibility; 22 | } 23 | 24 | a { 25 | color: $link-color; 26 | outline: none; 27 | text-decoration: none; 28 | 29 | &:focus { 30 | @include control-shadow(); 31 | } 32 | 33 | &:focus, 34 | &:hover, 35 | &:active, 36 | &.active { 37 | color: $link-color-dark; 38 | text-decoration: underline; 39 | } 40 | 41 | &:visited { 42 | color: $link-color-light; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/utilities/_loading.scss: -------------------------------------------------------------------------------- 1 | // Loading 2 | .loading { 3 | color: transparent !important; 4 | min-height: $unit-4; 5 | pointer-events: none; 6 | position: relative; 7 | &::after { 8 | animation: loading 500ms infinite linear; 9 | border: $border-width-lg solid $primary-color; 10 | border-radius: 50%; 11 | border-right-color: transparent; 12 | border-top-color: transparent; 13 | content: ""; 14 | display: block; 15 | height: $unit-4; 16 | left: 50%; 17 | margin-left: -$unit-2; 18 | margin-top: -$unit-2; 19 | position: absolute; 20 | top: 50%; 21 | width: $unit-4; 22 | z-index: $zindex-0; 23 | } 24 | 25 | &.loading-lg { 26 | min-height: $unit-10; 27 | &::after { 28 | height: $unit-8; 29 | margin-left: -$unit-4; 30 | margin-top: -$unit-4; 31 | width: $unit-8; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/addfocus/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns addfocus.helpers) 2 | 3 | (defn get-task [id tasks] 4 | (cond 5 | (= id 0) {:id 0 6 | :time 25 7 | :important false 8 | :urgent false 9 | :task "25 Minute Focus"} 10 | (< id 99) {:id id 11 | :time id 12 | :ignore true 13 | :break true 14 | :task (str id " Minute Break")} 15 | :else (first (filter #(= id (:id %)) tasks)))) 16 | 17 | (defn exp->lvl [exp] 18 | (cond 19 | (< exp 13300) 1 20 | (< exp 320000) 21 | (.floor js/Math (/ (.log js/Math (/ (- exp 2500) 10000)) 22 | (.log js/Math 1.08))) 23 | :else 24 | (.floor js/Math (+ 44 (/ (- exp 300000) 20000))))) 25 | 26 | (defn lvl->exp [lvl] 27 | (if 28 | (< lvl 45) (.ceil js/Math (+ 2500 (* 10000 (.pow js/Math 1.08 lvl)))) 29 | (+ 300000 (* 20000 (- lvl 44))))) -------------------------------------------------------------------------------- /shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | ;; shadow-cljs configuration 2 | {:source-paths 3 | ["src"] 4 | 5 | :dependencies 6 | [[reagent "0.9.0-rc3"] 7 | [re-frame "0.10.6"] 8 | [binaryage/devtools "0.9.10"] 9 | [day8.re-frame/re-frame-10x "0.3.7-react16"] 10 | [day8.re-frame/tracing "0.5.1"]] 11 | 12 | :builds {:app {:output-dir "release/js/shadow" 13 | :asset-path "js/shadow" 14 | :target :browser 15 | :modules {:app {:init-fn addfocus.default/init}} 16 | :closure-defines {re-frame.trace/trace-enabled? true 17 | day8.re-frame.tracing/trace-enabled? true} 18 | :devtools {:preloads 19 | [devtools.preload 20 | day8.re-frame-10x.preload] 21 | :http-root "release" 22 | :http-port 5500 23 | :watch-dir "release/css"}}}} 24 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_cards.scss: -------------------------------------------------------------------------------- 1 | // Cards 2 | .card { 3 | background: $bg-color-light; 4 | border: $border-width solid $border-color; 5 | border-radius: $border-radius; 6 | display: flex; 7 | flex-direction: column; 8 | 9 | .card-header, 10 | .card-body, 11 | .card-footer { 12 | padding: $layout-spacing-lg; 13 | padding-bottom: 0; 14 | 15 | &:last-child { 16 | padding-bottom: $layout-spacing-lg; 17 | } 18 | } 19 | 20 | .card-body { 21 | flex: 1 1 auto; 22 | } 23 | 24 | .card-image { 25 | padding-top: $layout-spacing-lg; 26 | 27 | &:first-child { 28 | padding-top: 0; 29 | 30 | img { 31 | border-top-left-radius: $border-radius; 32 | border-top-right-radius: $border-radius; 33 | } 34 | } 35 | 36 | &:last-child { 37 | img { 38 | border-bottom-left-radius: $border-radius; 39 | border-bottom-right-radius: $border-radius; 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_toasts.scss: -------------------------------------------------------------------------------- 1 | // Toasts 2 | .toast { 3 | @include toast-variant($dark-color); 4 | border: $border-width solid $dark-color; 5 | border-radius: $border-radius; 6 | color: $light-color; 7 | display: block; 8 | padding: $layout-spacing; 9 | width: 100%; 10 | 11 | &.toast-primary { 12 | @include toast-variant($primary-color); 13 | } 14 | 15 | &.toast-success { 16 | @include toast-variant($success-color); 17 | } 18 | 19 | &.toast-warning { 20 | @include toast-variant($warning-color); 21 | } 22 | 23 | &.toast-error { 24 | @include toast-variant($error-color); 25 | } 26 | 27 | a { 28 | color: $light-color; 29 | text-decoration: underline; 30 | 31 | &:focus, 32 | &:hover, 33 | &:active, 34 | &.active { 35 | opacity: .75; 36 | } 37 | } 38 | 39 | .btn-clear { 40 | margin: $unit-h; 41 | } 42 | 43 | p { 44 | &:last-child { 45 | margin-bottom: 0; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/utilities/_position.scss: -------------------------------------------------------------------------------- 1 | // Position 2 | .clearfix { 3 | @include clearfix(); 4 | } 5 | 6 | .float-left { 7 | float: left !important; 8 | } 9 | 10 | .float-right { 11 | float: right !important; 12 | } 13 | 14 | .p-relative { 15 | position: relative !important; 16 | } 17 | 18 | .p-absolute { 19 | position: absolute !important; 20 | } 21 | 22 | .p-fixed { 23 | position: fixed !important; 24 | } 25 | 26 | .p-sticky { 27 | position: sticky !important; 28 | } 29 | 30 | .p-centered { 31 | display: block; 32 | float: none; 33 | margin-left: auto; 34 | margin-right: auto; 35 | } 36 | 37 | .flex-centered { 38 | align-items: center; 39 | display: flex; 40 | justify-content: center; 41 | } 42 | 43 | // Spacing 44 | @include margin-variant(0, 0); 45 | 46 | @include margin-variant(1, $unit-1); 47 | 48 | @include margin-variant(2, $unit-2); 49 | 50 | @include padding-variant(0, 0); 51 | 52 | @include padding-variant(1, $unit-1); 53 | 54 | @include padding-variant(2, $unit-2); 55 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_autocomplete.scss: -------------------------------------------------------------------------------- 1 | // Autocomplete 2 | .form-autocomplete { 3 | position: relative; 4 | 5 | .form-autocomplete-input { 6 | align-content: flex-start; 7 | display: flex; 8 | flex-wrap: wrap; 9 | height: auto; 10 | min-height: $unit-8; 11 | padding: $unit-h; 12 | 13 | &.is-focused { 14 | @include control-shadow(); 15 | border-color: $primary-color; 16 | } 17 | 18 | .form-input { 19 | border-color: transparent; 20 | box-shadow: none; 21 | display: inline-block; 22 | flex: 1 0 auto; 23 | height: $unit-6; 24 | line-height: $unit-4; 25 | margin: $unit-h; 26 | width: auto; 27 | } 28 | } 29 | 30 | .menu { 31 | left: 0; 32 | position: absolute; 33 | top: 100%; 34 | width: 100%; 35 | } 36 | 37 | &.autocomplete-oneline { 38 | .form-autocomplete-input { 39 | flex-wrap: nowrap; 40 | overflow-x: auto; 41 | } 42 | 43 | .chip { 44 | flex: 1 0 auto; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/icons/_icons-core.scss: -------------------------------------------------------------------------------- 1 | // Icon variables 2 | $icon-border-width: $border-width-lg; 3 | $icon-prefix: "icon"; 4 | 5 | // Icon base style 6 | .#{$icon-prefix} { 7 | box-sizing: border-box; 8 | display: inline-block; 9 | font-size: inherit; 10 | font-style: normal; 11 | height: 1em; 12 | position: relative; 13 | text-indent: -9999px; 14 | vertical-align: middle; 15 | width: 1em; 16 | &::before, 17 | &::after { 18 | content: ""; 19 | display: block; 20 | left: 50%; 21 | position: absolute; 22 | top: 50%; 23 | transform: translate(-50%, -50%); 24 | } 25 | 26 | // Icon sizes 27 | &.icon-2x { 28 | font-size: 1.6rem; 29 | } 30 | 31 | &.icon-3x { 32 | font-size: 2.4rem; 33 | } 34 | 35 | &.icon-4x { 36 | font-size: 3.2rem; 37 | } 38 | } 39 | 40 | // Component icon support 41 | .accordion, 42 | .btn, 43 | .toast, 44 | .menu { 45 | .#{$icon-prefix} { 46 | vertical-align: -10%; 47 | } 48 | } 49 | 50 | .btn-lg { 51 | .#{$icon-prefix} { 52 | vertical-align: -15%; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/utilities/_colors.scss: -------------------------------------------------------------------------------- 1 | // Text colors 2 | @include text-color-variant(".text-primary", $primary-color); 3 | 4 | @include text-color-variant(".text-secondary", $secondary-color-dark); 5 | 6 | @include text-color-variant(".text-gray", $gray-color); 7 | 8 | @include text-color-variant(".text-light", $light-color); 9 | 10 | @include text-color-variant(".text-dark", $body-font-color); 11 | 12 | @include text-color-variant(".text-success", $success-color); 13 | 14 | @include text-color-variant(".text-warning", $warning-color); 15 | 16 | @include text-color-variant(".text-error", $error-color); 17 | 18 | // Background colors 19 | @include bg-color-variant(".bg-primary", $primary-color); 20 | 21 | @include bg-color-variant(".bg-secondary", $secondary-color); 22 | 23 | @include bg-color-variant(".bg-dark", $dark-color); 24 | 25 | @include bg-color-variant(".bg-gray", $bg-color); 26 | 27 | @include bg-color-variant(".bg-success", $success-color); 28 | 29 | @include bg-color-variant(".bg-warning", $warning-color); 30 | 31 | @include bg-color-variant(".bg-error", $error-color); 32 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_tables.scss: -------------------------------------------------------------------------------- 1 | // Tables 2 | .table { 3 | border-collapse: collapse; 4 | border-spacing: 0; 5 | width: 100%; 6 | @if $rtl == true { 7 | text-align: right; 8 | } @else { 9 | text-align: left; 10 | } 11 | 12 | &.table-striped { 13 | tbody { 14 | tr:nth-of-type(odd) { 15 | background: $bg-color; 16 | } 17 | } 18 | } 19 | 20 | &, 21 | &.table-striped { 22 | tbody { 23 | tr { 24 | &.active { 25 | background: $bg-color-dark; 26 | } 27 | } 28 | } 29 | } 30 | 31 | &.table-hover { 32 | tbody { 33 | tr { 34 | &:hover { 35 | background: $bg-color-dark; 36 | } 37 | } 38 | } 39 | } 40 | 41 | // Scollable tables 42 | &.table-scroll { 43 | display: block; 44 | overflow-x: auto; 45 | padding-bottom: .75rem; 46 | white-space: nowrap; 47 | } 48 | 49 | td, 50 | th { 51 | border-bottom: $border-width solid $border-color; 52 | padding: $unit-3 $unit-2; 53 | } 54 | th { 55 | border-bottom-width: $border-width-lg; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/utilities/_text.scss: -------------------------------------------------------------------------------- 1 | // Text 2 | // Text alignment utilities 3 | .text-left { 4 | text-align: left; 5 | } 6 | 7 | .text-right { 8 | text-align: right; 9 | } 10 | 11 | .text-center { 12 | text-align: center; 13 | } 14 | 15 | .text-justify { 16 | text-align: justify; 17 | } 18 | 19 | // Text transform utilities 20 | .text-lowercase { 21 | text-transform: lowercase; 22 | } 23 | 24 | .text-uppercase { 25 | text-transform: uppercase; 26 | } 27 | 28 | .text-capitalize { 29 | text-transform: capitalize; 30 | } 31 | 32 | // Text style utilities 33 | .text-normal { 34 | font-weight: normal; 35 | } 36 | 37 | .text-bold { 38 | font-weight: bold; 39 | } 40 | 41 | .text-italic { 42 | font-style: italic; 43 | } 44 | 45 | .text-large { 46 | font-size: 1.2em; 47 | } 48 | 49 | // Text overflow utilities 50 | .text-ellipsis { 51 | @include text-ellipsis(); 52 | } 53 | 54 | .text-clip { 55 | overflow: hidden; 56 | text-overflow: clip; 57 | white-space: nowrap; 58 | } 59 | 60 | .text-break { 61 | hyphens: auto; 62 | word-break: break-word; 63 | word-wrap: break-word; 64 | } 65 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/utilities/_divider.scss: -------------------------------------------------------------------------------- 1 | // Divider 2 | .divider, 3 | .divider-vert { 4 | display: block; 5 | position: relative; 6 | 7 | &[data-content]::after { 8 | background: $bg-color-light; 9 | color: $gray-color; 10 | content: attr(data-content); 11 | display: inline-block; 12 | font-size: $font-size-sm; 13 | padding: 0 $unit-2; 14 | transform: translateY(-$font-size-sm + $border-width); 15 | } 16 | } 17 | 18 | .divider { 19 | border-top: $border-width solid $border-color-light; 20 | height: $border-width; 21 | margin: $unit-2 0; 22 | 23 | &[data-content] { 24 | margin: $unit-4 0; 25 | } 26 | } 27 | 28 | .divider-vert { 29 | display: block; 30 | padding: $unit-4; 31 | 32 | &::before { 33 | border-left: $border-width solid $border-color; 34 | bottom: $unit-2; 35 | content: ""; 36 | display: block; 37 | left: 50%; 38 | position: absolute; 39 | top: $unit-2; 40 | transform: translateX(-50%); 41 | } 42 | 43 | &[data-content]::after { 44 | left: 50%; 45 | padding: $unit-1 0; 46 | position: absolute; 47 | top: 50%; 48 | transform: translate(-50%, -50%); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_progress.scss: -------------------------------------------------------------------------------- 1 | // Progress 2 | // Credit: https://css-tricks.com/html5-progress-element/ 3 | .progress { 4 | appearance: none; 5 | background: $bg-color-dark; 6 | border: 0; 7 | border-radius: $border-radius; 8 | color: $primary-color; 9 | height: $unit-1; 10 | position: relative; 11 | width: 100%; 12 | 13 | &::-webkit-progress-bar { 14 | background: transparent; 15 | border-radius: $border-radius; 16 | } 17 | 18 | &::-webkit-progress-value { 19 | background: $primary-color; 20 | border-radius: $border-radius; 21 | } 22 | 23 | &::-moz-progress-bar { 24 | background: $primary-color; 25 | border-radius: $border-radius; 26 | } 27 | 28 | &:indeterminate { 29 | animation: progress-indeterminate 1.5s linear infinite; 30 | background: $bg-color-dark linear-gradient(to right, $primary-color 30%, $bg-color-dark 30%) top left / 150% 150% no-repeat; 31 | 32 | &::-moz-progress-bar { 33 | background: transparent; 34 | } 35 | } 36 | } 37 | 38 | @keyframes progress-indeterminate { 39 | 0% { 40 | background-position: 200% 0; 41 | } 42 | 100% { 43 | background-position: -200% 0; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination 2 | .pagination { 3 | display: flex; 4 | list-style: none; 5 | margin: $unit-1 0; 6 | padding: $unit-1 0; 7 | 8 | .page-item { 9 | margin: $unit-1 $unit-o; 10 | 11 | span { 12 | display: inline-block; 13 | padding: $unit-1 $unit-1; 14 | } 15 | 16 | a { 17 | border-radius: $border-radius; 18 | display: inline-block; 19 | padding: $unit-1 $unit-2; 20 | text-decoration: none; 21 | &:focus, 22 | &:hover { 23 | color: $primary-color; 24 | } 25 | } 26 | 27 | &.disabled { 28 | a { 29 | cursor: default; 30 | opacity: .5; 31 | pointer-events: none; 32 | } 33 | } 34 | 35 | &.active { 36 | a { 37 | background: $primary-color; 38 | color: $light-color; 39 | } 40 | } 41 | 42 | &.page-prev, 43 | &.page-next { 44 | flex: 1 0 50%; 45 | } 46 | 47 | &.page-next { 48 | text-align: right; 49 | } 50 | 51 | .page-item-title { 52 | margin: 0; 53 | } 54 | 55 | .page-item-subtitle { 56 | margin: 0; 57 | opacity: .5; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /assets/scss/addr/_loading.scss: -------------------------------------------------------------------------------- 1 | #loading-overlay { 2 | z-index: 1000; 3 | height: 100%; 4 | width: 100%; 5 | position: fixed; 6 | left: 0; 7 | top: 0; 8 | transition: background-color 2s linear; 9 | 10 | .time-out { 11 | position: relative; 12 | visibility: hidden; 13 | border-radius: $border-radius; 14 | opacity: 0; 15 | transition: visibility 0s, opacity 0.7s ease-in-out; 16 | width: 340px; 17 | margin-left: -170px; 18 | height: 220px; 19 | margin-top: -110px; 20 | top: 50%; 21 | left: 50%; 22 | background-color: rgb(236, 194, 194); 23 | box-shadow: 5 5 5 black; 24 | text-align: center; 25 | padding: 20px; 26 | 27 | span { 28 | display: block; 29 | margin: 10px; 30 | font-size: 16px; 31 | } 32 | 33 | button { 34 | margin: 3px; 35 | } 36 | } 37 | 38 | &.warming-up { 39 | cursor: progress; 40 | background-color: rgba(0, 0, 0, 0); 41 | } 42 | 43 | &.ui-blocked { 44 | cursor: wait; 45 | background-color: rgba(0, 0, 0, 0.3); 46 | } 47 | 48 | &.time-out { 49 | background-color: rgba(0, 0, 0, 0.5); 50 | 51 | .time-out { 52 | visibility: visible; 53 | opacity: 1; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /assets/scss/addr/_openlayers.scss: -------------------------------------------------------------------------------- 1 | 2 | #dashmap { 3 | height: 700px; 4 | } 5 | .ol-popup { 6 | position: absolute; 7 | background-color: white; 8 | -webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2)); 9 | filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2)); 10 | padding: 15px; 11 | border-radius: 10px; 12 | border: 1px solid #cccccc; 13 | bottom: 12px; 14 | left: -50px; 15 | min-width: 280px; 16 | } 17 | .ol-popup:after, .ol-popup:before { 18 | top: 100%; 19 | border: solid transparent; 20 | content: " "; 21 | height: 0; 22 | width: 0; 23 | position: absolute; 24 | pointer-events: none; 25 | } 26 | .ol-popup:after { 27 | border-top-color: white; 28 | border-width: 10px; 29 | left: 48px; 30 | margin-left: -10px; 31 | } 32 | .ol-popup:before { 33 | border-top-color: #cccccc; 34 | border-width: 11px; 35 | left: 48px; 36 | margin-left: -11px; 37 | } 38 | .ol-popup-closer { 39 | text-decoration: none; 40 | position: absolute; 41 | top: 2px; 42 | right: 8px; 43 | } 44 | .ol-popup-closer:after { 45 | content: "✖"; 46 | } 47 | 48 | .ol-control button{ 49 | background-color: rgba(40, 40, 40, 0.85) !important; 50 | } 51 | .ol-control button:hover{ 52 | background-color: rgba(40, 40, 40, 1) !important; 53 | } -------------------------------------------------------------------------------- /assets/scss/addr/_animation.scss: -------------------------------------------------------------------------------- 1 | @keyframes blink { 2 | 50% { 3 | opacity: 0.4; 4 | } 5 | } 6 | 7 | @keyframes grow { 8 | from { 9 | transform: scale(0); 10 | } 11 | to { 12 | transform: scale(1); 13 | } 14 | } 15 | 16 | @keyframes fadein { 17 | from { 18 | opacity: 0; 19 | } 20 | to { 21 | opacity: 1; 22 | } 23 | } 24 | 25 | @keyframes fadeout { 26 | from { 27 | opacity: 1; 28 | } 29 | to { 30 | opacity: 0; 31 | } 32 | } 33 | 34 | .fadeout { 35 | animation: fadeout 0.35s ease 1; 36 | } 37 | 38 | @keyframes attention { 39 | 0% { 40 | background-color: white; 41 | color: black; 42 | } 43 | 20% { 44 | background-color: hsl(233, 68%, 64%); 45 | color: white !important; 46 | } 47 | 100% { 48 | background-color: initial; 49 | color: initial; 50 | } 51 | } 52 | 53 | @keyframes grow { 54 | 0% { 55 | width: 40px; 56 | height: 40px; 57 | } 58 | 50% { 59 | width: 380px; 60 | height: 40px; 61 | } 62 | 100% { 63 | height: 50vh; 64 | } 65 | 66 | } 67 | 68 | 69 | @keyframes fadein8 { 70 | 0%, 80% { 71 | opacity: 0; 72 | } 73 | 100% { 74 | opacity: 1; 75 | } 76 | } 77 | 78 | .fadeout { 79 | animation: fadeout 0.35s ease 1; 80 | } -------------------------------------------------------------------------------- /assets/scss/addr/_orderlayer.scss: -------------------------------------------------------------------------------- 1 | #order-layer { 2 | position: fixed; 3 | left: -646px; 4 | top: 50px; 5 | width: 640px; 6 | z-index: 9000; 7 | background-color: #f6f7f9; 8 | background-image: linear-gradient(85deg,#f6f7f9 90%, #e9e9e9); 9 | border-radius: 0 0 8px 0; 10 | padding: 10px 10px 10px 20px; 11 | box-shadow: 1px 1px 20px #33333355; 12 | border-right: rgb(250, 209, 114) 2px solid; 13 | border-left: 8px solid rgb(187, 187, 187); 14 | transition: all 0.5s ease-in; 15 | 16 | .hidden-handle { 17 | position: absolute; 18 | display: none; 19 | left:620px; 20 | top: -5%; 21 | height: 110%; 22 | width:160px; 23 | } 24 | 25 | &:hover, &.open { 26 | transition: all 0.5s ease-out; 27 | left: -1px; 28 | .hidden-handle { 29 | display: block; 30 | } 31 | } 32 | 33 | .handle { 34 | position: absolute; 35 | font-size: 14px; 36 | font-weight: 600; 37 | left: 596px; 38 | top:36px; 39 | width: 100px; 40 | height: 28px; 41 | text-align: center; 42 | border-radius: 8px 8px 0 0; 43 | transform: rotate(90deg); 44 | background-color: rgb(250, 209, 114); 45 | cursor: default; 46 | } 47 | 48 | .footer { 49 | font-size: 10px; 50 | text-align: center; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /release/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ADD FOCUS - Attention Deficit Disorder TODO App 11 | 12 | 13 | 14 |
15 | 16 | 20 | 21 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/mixins/_button.scss: -------------------------------------------------------------------------------- 1 | // Button variant mixin 2 | @mixin button-variant($color: $primary-color) { 3 | background: $color; 4 | border-color: darken($color, 3%); 5 | color: $light-color; 6 | &:focus { 7 | @include control-shadow($color); 8 | } 9 | &:focus, 10 | &:hover { 11 | background: darken($color, 2%); 12 | border-color: darken($color, 5%); 13 | color: $light-color; 14 | } 15 | &:active, 16 | &.active { 17 | background: darken($color, 7%); 18 | border-color: darken($color, 10%); 19 | color: $light-color; 20 | } 21 | &.loading { 22 | &::after { 23 | border-bottom-color: $light-color; 24 | border-left-color: $light-color; 25 | } 26 | } 27 | } 28 | 29 | @mixin button-outline-variant($color: $primary-color) { 30 | background: $light-color; 31 | border-color: $color; 32 | color: $color; 33 | &:focus { 34 | @include control-shadow($color); 35 | } 36 | &:focus, 37 | &:hover { 38 | background: lighten($color, 50%); 39 | border-color: darken($color, 2%); 40 | color: $color; 41 | } 42 | &:active, 43 | &.active { 44 | background: $color; 45 | border-color: darken($color, 5%); 46 | color: $light-color; 47 | } 48 | &.loading { 49 | &::after { 50 | border-bottom-color: $color; 51 | border-left-color: $color; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_timelines.scss: -------------------------------------------------------------------------------- 1 | // Timelines 2 | .timeline { 3 | .timeline-item { 4 | display: flex; 5 | margin-bottom: $unit-6; 6 | position: relative; 7 | &::before { 8 | background: $border-color; 9 | content: ""; 10 | height: 100%; 11 | left: 11px; 12 | position: absolute; 13 | top: $unit-6; 14 | width: 2px; 15 | } 16 | 17 | .timeline-left { 18 | flex: 0 0 auto; 19 | } 20 | 21 | .timeline-content { 22 | flex: 1 1 auto; 23 | padding: 2px 0 2px $layout-spacing-lg; 24 | } 25 | 26 | .timeline-icon { 27 | align-items: center; 28 | border-radius: 50%; 29 | color: $light-color; 30 | display: flex; 31 | height: $unit-6; 32 | justify-content: center; 33 | text-align: center; 34 | width: $unit-6; 35 | &::before { 36 | border: $border-width-lg solid $primary-color; 37 | border-radius: 50%; 38 | content: ""; 39 | display: block; 40 | height: $unit-2; 41 | left: $unit-2; 42 | position: absolute; 43 | top: $unit-2; 44 | width: $unit-2; 45 | } 46 | 47 | &.icon-lg { 48 | background: $primary-color; 49 | line-height: $line-height; 50 | &::before { 51 | content: none; 52 | } 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/mixins/_position.scss: -------------------------------------------------------------------------------- 1 | // Margin utility mixin 2 | @mixin margin-variant($id: 1, $size: $unit-1) { 3 | .m-#{$id} { 4 | margin: $size !important; 5 | } 6 | 7 | .mb-#{$id} { 8 | margin-bottom: $size !important; 9 | } 10 | 11 | .ml-#{$id} { 12 | margin-left: $size !important; 13 | } 14 | 15 | .mr-#{$id} { 16 | margin-right: $size !important; 17 | } 18 | 19 | .mt-#{$id} { 20 | margin-top: $size !important; 21 | } 22 | 23 | .mx-#{$id} { 24 | margin-left: $size !important; 25 | margin-right: $size !important; 26 | } 27 | 28 | .my-#{$id} { 29 | margin-bottom: $size !important; 30 | margin-top: $size !important; 31 | } 32 | } 33 | 34 | // Padding utility mixin 35 | @mixin padding-variant($id: 1, $size: $unit-1) { 36 | .p-#{$id} { 37 | padding: $size !important; 38 | } 39 | 40 | .pb-#{$id} { 41 | padding-bottom: $size !important; 42 | } 43 | 44 | .pl-#{$id} { 45 | padding-left: $size !important; 46 | } 47 | 48 | .pr-#{$id} { 49 | padding-right: $size !important; 50 | } 51 | 52 | .pt-#{$id} { 53 | padding-top: $size !important; 54 | } 55 | 56 | .px-#{$id} { 57 | padding-left: $size !important; 58 | padding-right: $size !important; 59 | } 60 | 61 | .py-#{$id} { 62 | padding-bottom: $size !important; 63 | padding-top: $size !important; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_meters.scss: -------------------------------------------------------------------------------- 1 | // Meters 2 | // Credit: https://css-tricks.com/html5-meter-element/ 3 | .meter { 4 | appearance: none; 5 | background: $bg-color; 6 | border: 0; 7 | border-radius: $border-radius; 8 | display: block; 9 | width: 100%; 10 | height: $unit-4; 11 | 12 | &::-webkit-meter-inner-element { 13 | display: block; 14 | } 15 | 16 | &::-webkit-meter-bar, 17 | &::-webkit-meter-optimum-value, 18 | &::-webkit-meter-suboptimum-value, 19 | &::-webkit-meter-even-less-good-value { 20 | border-radius: $border-radius; 21 | } 22 | 23 | &::-webkit-meter-bar { 24 | background: $bg-color; 25 | } 26 | 27 | &::-webkit-meter-optimum-value { 28 | background: $success-color; 29 | } 30 | 31 | &::-webkit-meter-suboptimum-value { 32 | background: $warning-color; 33 | } 34 | 35 | &::-webkit-meter-even-less-good-value { 36 | background: $error-color; 37 | } 38 | 39 | &::-moz-meter-bar, 40 | &:-moz-meter-optimum, 41 | &:-moz-meter-sub-optimum, 42 | &:-moz-meter-sub-sub-optimum { 43 | border-radius: $border-radius; 44 | } 45 | 46 | &:-moz-meter-optimum::-moz-meter-bar { 47 | background: $success-color; 48 | } 49 | 50 | &:-moz-meter-sub-optimum::-moz-meter-bar { 51 | background: $warning-color; 52 | } 53 | 54 | &:-moz-meter-sub-sub-optimum::-moz-meter-bar { 55 | background: $error-color; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_badges.scss: -------------------------------------------------------------------------------- 1 | // Badges 2 | .badge { 3 | position: relative; 4 | white-space: nowrap; 5 | 6 | &[data-badge], 7 | &:not([data-badge]) { 8 | &::after { 9 | background: $primary-color; 10 | background-clip: padding-box; 11 | border-radius: .5rem; 12 | box-shadow: 0 0 0 .1rem $bg-color-light; 13 | color: $light-color; 14 | content: attr(data-badge); 15 | display: inline-block; 16 | transform: translate(-.05rem, -.5rem); 17 | } 18 | } 19 | &[data-badge] { 20 | &::after { 21 | font-size: $font-size-sm; 22 | height: .9rem; 23 | line-height: 1; 24 | min-width: .9rem; 25 | padding: .1rem .2rem; 26 | text-align: center; 27 | white-space: nowrap; 28 | } 29 | } 30 | &:not([data-badge]), 31 | &[data-badge=""] { 32 | &::after { 33 | height: 6px; 34 | min-width: 6px; 35 | padding: 0; 36 | width: 6px; 37 | } 38 | } 39 | 40 | // Badges for Buttons 41 | &.btn { 42 | &::after { 43 | position: absolute; 44 | top: 0; 45 | right: 0; 46 | transform: translate(50%, -50%); 47 | } 48 | } 49 | 50 | // Badges for Avatars 51 | &.avatar { 52 | &::after { 53 | position: absolute; 54 | top: 14.64%; 55 | right: 14.64%; 56 | transform: translate(50%, -50%); 57 | z-index: $zindex-1; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/spectre.scss: -------------------------------------------------------------------------------- 1 | // Variables and mixins 2 | @import "spectre/variables"; 3 | @import "spectre/mixins"; 4 | 5 | /*! Spectre.css v#{$version} | MIT License | github.com/picturepan2/spectre */ 6 | // Reset and dependencies 7 | @import "spectre/normalize"; 8 | @import "spectre/base"; 9 | 10 | // Elements 11 | @import "spectre/typography"; 12 | //@import "spectre/asian"; 13 | @import "spectre/tables"; 14 | @import "spectre/buttons"; 15 | @import "spectre/forms"; 16 | @import "spectre/labels"; 17 | //@import "spectre/codes"; 18 | @import "spectre/media"; 19 | 20 | // Layout 21 | @import "spectre/layout"; 22 | //@import "spectre/hero"; 23 | //@import "spectre/navbar"; 24 | 25 | // Components 26 | //@import "spectre/accordions"; 27 | //@import "spectre/avatars"; 28 | //@import "spectre/badges"; 29 | //@import "spectre/breadcrumbs"; 30 | //@import "spectre/bars"; 31 | //@import "spectre/cards"; 32 | //@import "spectre/chips"; 33 | //@import "spectre/dropdowns"; 34 | //@import "spectre/empty"; 35 | //@import "spectre/menus"; 36 | @import "spectre/modals"; 37 | //@import "spectre/navs"; 38 | //@import "spectre/pagination"; 39 | //@import "spectre/panels"; 40 | //@import "spectre/popovers"; 41 | //@import "spectre/steps"; 42 | //@import "spectre/tabs"; 43 | //@import "spectre/tiles"; 44 | //@import "spectre/toasts"; 45 | //@import "spectre/tooltips"; 46 | 47 | // Utility classes 48 | @import "spectre/animations"; 49 | @import "spectre/utilities"; 50 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_tabs.scss: -------------------------------------------------------------------------------- 1 | // Tabs 2 | .tab { 3 | align-items: center; 4 | border-bottom: $border-width solid $border-color; 5 | display: flex; 6 | flex-wrap: wrap; 7 | list-style: none; 8 | margin: $unit-1 0 ($unit-1 - $border-width) 0; 9 | 10 | .tab-item { 11 | margin-top: 0; 12 | 13 | a { 14 | border-bottom: $border-width-lg solid transparent; 15 | color: inherit; 16 | display: block; 17 | margin: 0 $unit-2 0 0; 18 | padding: $unit-2 $unit-1 $unit-2 - $border-width-lg $unit-1; 19 | text-decoration: none; 20 | &:focus, 21 | &:hover { 22 | color: $link-color; 23 | } 24 | } 25 | &.active a, 26 | a.active { 27 | border-bottom-color: $primary-color; 28 | color: $link-color; 29 | } 30 | 31 | &.tab-action { 32 | flex: 1 0 auto; 33 | text-align: right; 34 | } 35 | 36 | .btn-clear { 37 | margin-top: -$unit-1; 38 | } 39 | } 40 | 41 | &.tab-block { 42 | .tab-item { 43 | flex: 1 0 0; 44 | text-align: center; 45 | 46 | a { 47 | margin: 0; 48 | } 49 | 50 | .badge { 51 | &[data-badge]::after { 52 | position: absolute; 53 | right: $unit-h; 54 | top: $unit-h; 55 | transform: translate(0, 0); 56 | } 57 | } 58 | } 59 | } 60 | 61 | &:not(.tab-block) { 62 | .badge { 63 | padding-right: 0; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /assets/scss/addr/_tools.scss: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------- */ 2 | /* TOOLS */ 3 | /* -------------------------------------------------------------------------- */ 4 | 5 | #debug { 6 | position: absolute; 7 | padding: 4px; 8 | font-size: 12px; 9 | top: 15px; 10 | right: 15px; 11 | background-color: #33333377; 12 | } 13 | 14 | .pointer { 15 | cursor: pointer; 16 | } 17 | 18 | .fxs { 19 | font-size: x-small; 20 | } 21 | 22 | .flex { 23 | display: flex; 24 | } 25 | 26 | .percent-bg { 27 | width: 100%; 28 | background: linear-gradient(to right, rgb(11, 204, 37) 0%, rgba(255, 215, 10, 1) 50%, rgba(255, 0, 0, 1) 100%); 29 | border-radius: 6px; 30 | height: 12px; 31 | box-shadow: 1px 1px 2px #33333377; 32 | 33 | .percent { 34 | margin: 0 -1px; 35 | float: right; 36 | border-radius: 0 6px 6px 0; 37 | background-color: #ddd; 38 | height: 12px; 39 | background-size: 35% 5%; 40 | } 41 | } 42 | 43 | .shadow { 44 | box-shadow: 1px 1px 2px #33333377; 45 | } 46 | 47 | .clickable { 48 | cursor: pointer; 49 | &:hover { 50 | box-shadow: 0 0 6px hsl(200, 55%, 60%, 50%); 51 | } 52 | } 53 | 54 | .hover-switch { 55 | .auto-show { 56 | display: none; 57 | } 58 | 59 | &:hover { 60 | .auto-show { 61 | display: initial; 62 | } 63 | .auto-hide { 64 | display: none; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_popovers.scss: -------------------------------------------------------------------------------- 1 | // Popovers 2 | .popover { 3 | display: inline-block; 4 | position: relative; 5 | 6 | .popover-container { 7 | left: 50%; 8 | opacity: 0; 9 | padding: $layout-spacing; 10 | position: absolute; 11 | top: 0; 12 | transform: translate(-50%, -50%) scale(0); 13 | transition: transform .2s; 14 | width: $control-width-sm; 15 | z-index: $zindex-3; 16 | } 17 | 18 | *:focus + .popover-container, 19 | &:hover .popover-container { 20 | display: block; 21 | opacity: 1; 22 | transform: translate(-50%, -100%) scale(1); 23 | } 24 | 25 | &.popover-right { 26 | .popover-container { 27 | left: 100%; 28 | top: 50%; 29 | } 30 | 31 | *:focus + .popover-container, 32 | &:hover .popover-container { 33 | transform: translate(0, -50%) scale(1); 34 | } 35 | } 36 | 37 | &.popover-bottom { 38 | .popover-container { 39 | left: 50%; 40 | top: 100%; 41 | } 42 | 43 | *:focus + .popover-container, 44 | &:hover .popover-container { 45 | transform: translate(-50%, 0) scale(1); 46 | } 47 | } 48 | 49 | &.popover-left { 50 | .popover-container { 51 | left: 0; 52 | top: 50%; 53 | } 54 | 55 | *:focus + .popover-container, 56 | &:hover .popover-container { 57 | transform: translate(-100%, -50%) scale(1); 58 | } 59 | } 60 | 61 | .card { 62 | @include shadow-variant(.2rem); 63 | border: 0; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_menus.scss: -------------------------------------------------------------------------------- 1 | // Menus 2 | .menu { 3 | @include shadow-variant(.05rem); 4 | background: $bg-color-light; 5 | border-radius: $border-radius; 6 | list-style: none; 7 | margin: 0; 8 | min-width: $control-width-xs; 9 | padding: $unit-2; 10 | transform: translateY($layout-spacing-sm); 11 | z-index: $zindex-3; 12 | 13 | &.menu-nav { 14 | background: transparent; 15 | box-shadow: none; 16 | } 17 | 18 | .menu-item { 19 | margin-top: 0; 20 | padding: 0 $unit-2; 21 | position: relative; 22 | text-decoration: none; 23 | 24 | & > a { 25 | border-radius: $border-radius; 26 | color: inherit; 27 | display: block; 28 | margin: 0 (-$unit-2); 29 | padding: $unit-1 $unit-2; 30 | text-decoration: none; 31 | &:focus, 32 | &:hover { 33 | background: $secondary-color; 34 | color: $primary-color; 35 | } 36 | &:active, 37 | &.active { 38 | background: $secondary-color; 39 | color: $primary-color; 40 | } 41 | } 42 | 43 | .form-checkbox, 44 | .form-radio, 45 | .form-switch { 46 | margin: $unit-h 0; 47 | } 48 | 49 | & + .menu-item { 50 | margin-top: $unit-1; 51 | } 52 | } 53 | 54 | .menu-badge { 55 | align-items: center; 56 | display: flex; 57 | height: 100%; 58 | position: absolute; 59 | right: 0; 60 | top: 0; 61 | 62 | .label { 63 | margin-right: $unit-2; 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /assets/scss/addr/_call.scss: -------------------------------------------------------------------------------- 1 | #call-holder { 2 | position: sticky; 3 | bottom: 50px; 4 | z-index: 90; 5 | text-align: center; 6 | 7 | .call { 8 | width: 380px; 9 | text-align: left; 10 | animation: call 1.2s ease-in; 11 | height: 60px; 12 | overflow: hidden; 13 | border-radius: 30px; 14 | box-shadow: #33333377 3px 3px 6px; 15 | margin: 12px auto; 16 | padding: 1px; 17 | background-color: $m-color-lighter; 18 | 19 | .phone-icon { 20 | display: block; 21 | margin: 4px 12px 4px 4px; 22 | width: 50px; 23 | height: 50px; 24 | border-radius: 50%; 25 | float: left; 26 | text-align: center; 27 | 28 | i { 29 | padding: 10px; 30 | font-size: 30px; 31 | animation: callicon 0.8s infinite; 32 | } 33 | } 34 | 35 | .info { 36 | animation: fadein8 1.6s; 37 | color: white; 38 | } 39 | 40 | .action { 41 | color: $ms-text-color; 42 | margin: 5px; 43 | float: right; 44 | margin-right: 20px; 45 | i {margin: 0 6px;} 46 | span {display: block; 47 | cursor: pointer; 48 | &:hover {color: white;}} 49 | .order {color:hsl(105, 70%, 64%);} 50 | .close {color:hsl(0, 90%, 74%);} 51 | } 52 | .name { 53 | font-weight: 700; 54 | font-size: 18px; 55 | display: block; 56 | max-height: 30px; 57 | overflow: hidden; 58 | } 59 | .callid { 60 | display: block; 61 | font-size: 12px; 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_media.scss: -------------------------------------------------------------------------------- 1 | // Media 2 | // Image responsive 3 | .img-responsive { 4 | display: block; 5 | height: auto; 6 | max-width: 100%; 7 | } 8 | 9 | // object-fit support is coming to Microsoft Edge 10 | // https://developer.microsoft.com/en-us/microsoft-edge/platform/status/objectfitandobjectposition/ 11 | .img-fit-cover { 12 | object-fit: cover; 13 | } 14 | 15 | .img-fit-contain { 16 | object-fit: contain; 17 | } 18 | 19 | // Video responsive 20 | .video-responsive { 21 | display: block; 22 | overflow: hidden; 23 | padding: 0; 24 | position: relative; 25 | width: 100%; 26 | &::before { 27 | content: ""; 28 | display: block; 29 | padding-bottom: 56.25%; // Default ratio 16:9, you can calculate this value by dividing 9 by 16 30 | } 31 | 32 | iframe, 33 | object, 34 | embed { 35 | border: 0; 36 | bottom: 0; 37 | height: 100%; 38 | left: 0; 39 | position: absolute; 40 | right: 0; 41 | top: 0; 42 | width: 100%; 43 | } 44 | } 45 | 46 | video.video-responsive { 47 | height: auto; 48 | max-width: 100%; 49 | 50 | &::before { 51 | content: none; 52 | } 53 | } 54 | 55 | .video-responsive-4-3 { 56 | &::before { 57 | padding-bottom: 75%; // Ratio 4:3 58 | } 59 | } 60 | 61 | .video-responsive-1-1 { 62 | &::before { 63 | padding-bottom: 100%; // Ratio 1:1 64 | } 65 | } 66 | 67 | // Figure 68 | .figure { 69 | margin: 0 0 $layout-spacing 0; 70 | 71 | .figure-caption { 72 | color: $gray-color-dark; 73 | margin-top: $layout-spacing; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_bars.scss: -------------------------------------------------------------------------------- 1 | // Bars 2 | .bar { 3 | background: $bg-color-dark; 4 | border-radius: $border-radius; 5 | display: flex; 6 | flex-wrap: nowrap; 7 | height: $unit-4; 8 | width: 100%; 9 | 10 | &.bar-sm { 11 | height: $unit-1; 12 | } 13 | 14 | .bar-item { 15 | background: $primary-color; 16 | color: $light-color; 17 | display: block; 18 | font-size: $font-size-sm; 19 | flex-shrink: 0; 20 | line-height: $unit-4; 21 | height: 100%; 22 | position: relative; 23 | text-align: center; 24 | width: 0; 25 | 26 | &:first-child { 27 | border-bottom-left-radius: $border-radius; 28 | border-top-left-radius: $border-radius; 29 | } 30 | &:last-child { 31 | border-bottom-right-radius: $border-radius; 32 | border-top-right-radius: $border-radius; 33 | flex-shrink: 1; 34 | } 35 | } 36 | } 37 | 38 | // Slider bar 39 | .bar-slider { 40 | height: $border-width-lg; 41 | margin: $layout-spacing 0; 42 | position: relative; 43 | 44 | .bar-item { 45 | left: 0; 46 | padding: 0; 47 | position: absolute; 48 | &:not(:last-child):first-child { 49 | background: $bg-color-dark; 50 | z-index: $zindex-0; 51 | } 52 | } 53 | 54 | .bar-slider-btn { 55 | background: $primary-color; 56 | border: 0; 57 | border-radius: 50%; 58 | height: $unit-3; 59 | padding: 0; 60 | position: absolute; 61 | right: 0; 62 | top: 50%; 63 | transform: translate(50%, -50%); 64 | width: $unit-3; 65 | 66 | &:active { 67 | box-shadow: 0 0 0 .1rem $primary-color; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_steps.scss: -------------------------------------------------------------------------------- 1 | // Steps 2 | .step { 3 | display: flex; 4 | flex-wrap: nowrap; 5 | list-style: none; 6 | margin: $unit-1 0; 7 | width: 100%; 8 | 9 | .step-item { 10 | flex: 1 1 0; 11 | margin-top: 0; 12 | min-height: 1rem; 13 | text-align: center; 14 | position: relative; 15 | 16 | &:not(:first-child)::before { 17 | background: $primary-color; 18 | content: ""; 19 | height: 2px; 20 | left: -50%; 21 | position: absolute; 22 | top: 9px; 23 | width: 100%; 24 | } 25 | 26 | a { 27 | color: $primary-color; 28 | display: inline-block; 29 | padding: 20px 10px 0; 30 | text-decoration: none; 31 | 32 | &::before { 33 | background: $primary-color; 34 | border: $border-width-lg solid $light-color; 35 | border-radius: 50%; 36 | content: ""; 37 | display: block; 38 | height: $unit-3; 39 | left: 50%; 40 | position: absolute; 41 | top: $unit-1; 42 | transform: translateX(-50%); 43 | width: $unit-3; 44 | z-index: $zindex-0; 45 | } 46 | } 47 | 48 | &.active { 49 | a { 50 | &::before { 51 | background: $light-color; 52 | border: $border-width-lg solid $primary-color; 53 | } 54 | } 55 | 56 | & ~ .step-item { 57 | &::before { 58 | background: $border-color; 59 | } 60 | 61 | a { 62 | color: $gray-color; 63 | 64 | &::before { 65 | background: $border-color; 66 | } 67 | } 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /release/js/remote.js: -------------------------------------------------------------------------------- 1 | 2 | window.connectRemote = function() { 3 | const remoteStorage = new RemoteStorage({ 4 | changeEvents: { 5 | local: true, 6 | window: true, 7 | remote: true, 8 | conflicts: true 9 | } 10 | }); 11 | 12 | // Init remote storage // 13 | remoteStorage.setApiKeys({ 14 | dropbox: '86gt09zt4ykmr3w' 15 | }); 16 | remoteStorage.access.claim('addfocus', 'rw'); 17 | 18 | // Create & Add connection widget 19 | const widget = new Widget(remoteStorage, {modalBackdrop: false}); 20 | widget.attach('settings'); 21 | 22 | //Create scope for remote storage 23 | window.rsClient = remoteStorage.scope('/addfocus/'); 24 | 25 | //Helper functions 26 | const log = function(){ 27 | console.log("Data sent to remote storage.") 28 | } 29 | 30 | window.saveRemoteData = function (name, content, callback) { 31 | window.rsClient.storeFile( 32 | 'application/json', 33 | name + '.json', 34 | JSON.stringify(content) 35 | ).then(() => {if (typeof callback !== 'undefined'){callback()}}); 36 | 37 | } 38 | 39 | window.loadRemoteData = function (name, callback) { 40 | window.rsClient.getFile(name + '.json') 41 | .then(file => {callback(JSON.parse(file.data))}); 42 | } 43 | 44 | // TODO: When connected loadRemoteData 45 | //remoteStorage.on('connected', function () { 46 | // Storage account has been connected, let’s roll! 47 | //}); 48 | 49 | //window.saveRemoteText = function (name, content, callback) { 50 | // window.rsClient.storeFile('text/plain', name + '.txt', content) 51 | // .then(() => {if (typeof callback !== 'undefined') { callback() } }); 52 | //} 53 | } -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_avatars.scss: -------------------------------------------------------------------------------- 1 | // Avatars 2 | .avatar { 3 | @include avatar-base(); 4 | background: $primary-color; 5 | border-radius: 50%; 6 | color: rgba($light-color, .85); 7 | display: inline-block; 8 | font-weight: 300; 9 | line-height: 1.25; 10 | margin: 0; 11 | position: relative; 12 | vertical-align: middle; 13 | 14 | &.avatar-xs { 15 | @include avatar-base($unit-4); 16 | } 17 | &.avatar-sm { 18 | @include avatar-base($unit-6); 19 | } 20 | &.avatar-lg { 21 | @include avatar-base($unit-12); 22 | } 23 | &.avatar-xl { 24 | @include avatar-base($unit-16); 25 | } 26 | 27 | img { 28 | border-radius: 50%; 29 | height: 100%; 30 | position: relative; 31 | width: 100%; 32 | z-index: $zindex-0; 33 | } 34 | 35 | .avatar-icon, 36 | .avatar-presence { 37 | background: $bg-color-light; 38 | bottom: 14.64%; 39 | height: 50%; 40 | padding: $border-width-lg; 41 | position: absolute; 42 | right: 14.64%; 43 | transform: translate(50%, 50%); 44 | width: 50%; 45 | z-index: $zindex-0 + 1; 46 | } 47 | 48 | .avatar-presence { 49 | background: $gray-color; 50 | box-shadow: 0 0 0 $border-width-lg $light-color; 51 | border-radius: 50%; 52 | height: .5em; 53 | width: .5em; 54 | 55 | &.online { 56 | background: $success-color; 57 | } 58 | 59 | &.busy { 60 | background: $error-color; 61 | } 62 | 63 | &.away { 64 | background: $warning-color; 65 | } 66 | } 67 | 68 | &[data-initial]::before { 69 | color: currentColor; 70 | content: attr(data-initial); 71 | left: 50%; 72 | position: absolute; 73 | top: 50%; 74 | transform: translate(-50%, -50%); 75 | z-index: $zindex-0; 76 | } 77 | } -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_modals.scss: -------------------------------------------------------------------------------- 1 | // Modals 2 | .modal { 3 | align-items: center; 4 | bottom: 0; 5 | display: none; 6 | justify-content: center; 7 | left: 0; 8 | opacity: 0; 9 | overflow: hidden; 10 | padding: $layout-spacing; 11 | position: fixed; 12 | right: 0; 13 | top: 0; 14 | 15 | &:target, 16 | &.active { 17 | display: flex; 18 | opacity: 1; 19 | z-index: $zindex-4; 20 | 21 | .modal-overlay { 22 | background: rgba($bg-color, .75); 23 | bottom: 0; 24 | cursor: default; 25 | display: block; 26 | left: 0; 27 | position: absolute; 28 | right: 0; 29 | top: 0; 30 | } 31 | 32 | .modal-container { 33 | animation: slide-down .2s ease 1; 34 | z-index: $zindex-0; 35 | } 36 | } 37 | 38 | &.modal-sm { 39 | .modal-container { 40 | max-width: $control-width-sm; 41 | padding: 0 $unit-2; 42 | } 43 | } 44 | 45 | &.modal-lg { 46 | .modal-overlay { 47 | background: $bg-color-light; 48 | } 49 | 50 | .modal-container { 51 | box-shadow: none; 52 | max-width: $control-width-lg; 53 | } 54 | } 55 | } 56 | 57 | .modal-container { 58 | @include shadow-variant(.2rem); 59 | background: $bg-color-light; 60 | border-radius: $border-radius; 61 | display: flex; 62 | flex-direction: column; 63 | max-height: 75vh; 64 | max-width: $control-width-md; 65 | padding: 0 $unit-4; 66 | width: 100%; 67 | 68 | &.modal-fullheight { 69 | max-height: 100vh; 70 | } 71 | 72 | .modal-header { 73 | color: $dark-color; 74 | padding: $unit-4; 75 | } 76 | 77 | .modal-body { 78 | overflow-y: auto; 79 | padding: $unit-4; 80 | position: relative; 81 | } 82 | 83 | .modal-footer { 84 | padding: $unit-4; 85 | text-align: right; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_tooltips.scss: -------------------------------------------------------------------------------- 1 | // Tooltips 2 | .tooltip { 3 | position: relative; 4 | &::after { 5 | background: rgba($dark-color, .95); 6 | border-radius: $border-radius; 7 | bottom: 100%; 8 | color: $light-color; 9 | content: attr(data-tooltip); 10 | display: block; 11 | font-size: $font-size-sm; 12 | left: 50%; 13 | max-width: $control-width-sm; 14 | opacity: 0; 15 | overflow: hidden; 16 | padding: $unit-1 $unit-2; 17 | pointer-events: none; 18 | position: absolute; 19 | text-overflow: ellipsis; 20 | transform: translate(-50%, $unit-2); 21 | transition: opacity .2s, transform .2s; 22 | white-space: pre; 23 | z-index: $zindex-3; 24 | } 25 | &:focus, 26 | &:hover { 27 | &::after { 28 | opacity: 1; 29 | transform: translate(-50%, -$unit-1); 30 | } 31 | } 32 | &[disabled], 33 | &.disabled { 34 | pointer-events: auto; 35 | } 36 | 37 | &.tooltip-right { 38 | &::after { 39 | bottom: 50%; 40 | left: 100%; 41 | transform: translate(-$unit-1, 50%); 42 | } 43 | &:focus, 44 | &:hover { 45 | &::after { 46 | transform: translate($unit-1, 50%); 47 | } 48 | } 49 | } 50 | 51 | &.tooltip-bottom { 52 | &::after { 53 | bottom: auto; 54 | top: 100%; 55 | transform: translate(-50%, -$unit-2); 56 | } 57 | &:focus, 58 | &:hover { 59 | &::after { 60 | transform: translate(-50%, $unit-1); 61 | } 62 | } 63 | } 64 | 65 | &.tooltip-left { 66 | &::after { 67 | bottom: 50%; 68 | left: auto; 69 | right: 100%; 70 | transform: translate($unit-2, 50%); 71 | } 72 | &:focus, 73 | &:hover { 74 | &::after { 75 | transform: translate(-$unit-1, 50%); 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /assets/scss/addr/_modals.scss: -------------------------------------------------------------------------------- 1 | // Modals 2 | .modal { 3 | align-items: center; 4 | bottom: 0; 5 | display: none; 6 | justify-content: center; 7 | left: 0; 8 | opacity: 0; 9 | overflow: hidden; 10 | padding: $layout-spacing; 11 | position: fixed; 12 | right: 0; 13 | top: 0; 14 | 15 | &:target, 16 | &.active { 17 | display: flex; 18 | opacity: 1; 19 | z-index: $zindex-4; 20 | 21 | .modal-overlay { 22 | background: rgba($bg-color, .6); 23 | bottom: 0; 24 | cursor: default; 25 | display: block; 26 | left: 0; 27 | position: absolute; 28 | right: 0; 29 | top: 0; 30 | animation: fadein 0.3s ease 1; 31 | } 32 | 33 | .modal-container { 34 | animation: fadein 0.5s ease 1; 35 | z-index: $zindex-0; 36 | } 37 | } 38 | 39 | &.modal-sm { 40 | .modal-container { 41 | max-width: $control-width-sm; 42 | padding: 0 $unit-2; 43 | } 44 | } 45 | 46 | &.modal-lg { 47 | .modal-container { 48 | box-shadow: none; 49 | max-width: $control-width-lg; 50 | border-radius: 8px; 51 | box-shadow: 1px 1px 3px #33333355; 52 | } 53 | } 54 | } 55 | 56 | .modal-container { 57 | @include shadow-variant(.2rem); 58 | background: $bg-color-light; 59 | border-radius: $border-radius; 60 | display: flex; 61 | flex-direction: column; 62 | max-height: 75vh; 63 | max-width: $control-width-md; 64 | padding: 0 $unit-4; 65 | width: 100%; 66 | 67 | &.modal-fullheight { 68 | max-height: 70%; 69 | } 70 | 71 | .modal-header { 72 | color: $dark-color; 73 | padding: $unit-2; 74 | } 75 | 76 | .modal-body { 77 | overflow-y: auto; 78 | padding: $unit-4; 79 | position: relative; 80 | min-height: 400px; 81 | } 82 | 83 | .modal-footer { 84 | padding: $unit-2; 85 | text-align: right; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /assets/scss/addr/_smartbox.scss: -------------------------------------------------------------------------------- 1 | #smart-box { 2 | position: absolute; 3 | top: 0; 4 | left: 25vw; 5 | width: 50vw; 6 | text-align: center; 7 | .pusher { 8 | height: 0px; 9 | } 10 | #smart-search { 11 | border-radius: 3px 3px 20px 20px; 12 | text-align: center; 13 | border: none; 14 | height: 14px; 15 | padding: 12px; 16 | box-sizing: border-box; 17 | background-color: $m-color; 18 | color: $ms-text-color; 19 | font-weight: bold; 20 | transition-duration: 0.2s; 21 | opacity: 0.5; 22 | width: 100px; 23 | 24 | &:focus { 25 | height: 50px; 26 | width: 260px; 27 | font-size: 20px; 28 | opacity: 1; 29 | border-radius: 4px 4px 40px 40px; 30 | outline: none; 31 | } 32 | } 33 | 34 | .results { 35 | background-color: $m-color; 36 | border-radius: 20px; 37 | color: $ms-text-color; 38 | margin-top: 60px; 39 | animation: fadein 0.8s; 40 | padding: 6px; 41 | max-height: 80vh; 42 | overflow: hidden; 43 | 44 | .result { 45 | text-align: left; 46 | padding: 5px 10px; 47 | margin: 6px; 48 | border-radius: 10px; 49 | background-color: $m-color-dark; 50 | display: flex; 51 | justify-content: space-between; 52 | 53 | .title { 54 | font-weight: 700; 55 | } 56 | 57 | .type { 58 | color: $ms-text-color-dark; 59 | font-size: small; 60 | font-style: italic; 61 | } 62 | 63 | .detail { 64 | color: $ms-text-color-dark; 65 | font-size: small; 66 | display: block; 67 | } 68 | 69 | .right { 70 | text-align: right; 71 | } 72 | button { 73 | font-size: 12px; 74 | font-weight: 600; 75 | border-radius: 4px; 76 | border: none; 77 | padding: 4px; 78 | margin: 2px; 79 | cursor: pointer; 80 | box-shadow: 1px 1px 1px #33333377 inset; 81 | 82 | &:hover { 83 | color: $m-color; 84 | background-color: white; 85 | } 86 | } 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_off-canvas.scss: -------------------------------------------------------------------------------- 1 | // Off canvas menus 2 | $off-canvas-breakpoint: $size-lg !default; 3 | 4 | .off-canvas { 5 | display: flex; 6 | flex-flow: nowrap; 7 | height: 100%; 8 | position: relative; 9 | width: 100%; 10 | 11 | .off-canvas-toggle { 12 | display: block; 13 | position: absolute; 14 | top: $layout-spacing; 15 | transition: none; 16 | z-index: $zindex-0; 17 | @if $rtl == true { 18 | right: $layout-spacing; 19 | } @else { 20 | left: $layout-spacing; 21 | } 22 | } 23 | 24 | .off-canvas-sidebar { 25 | background: $bg-color; 26 | bottom: 0; 27 | min-width: 10rem; 28 | overflow-y: auto; 29 | position: fixed; 30 | top: 0; 31 | transition: transform .25s; 32 | z-index: $zindex-2; 33 | @if $rtl == true { 34 | right: 0; 35 | transform: translateX(100%); 36 | } @else { 37 | left: 0; 38 | transform: translateX(-100%); 39 | } 40 | } 41 | 42 | .off-canvas-content { 43 | flex: 1 1 auto; 44 | height: 100%; 45 | padding: $layout-spacing $layout-spacing $layout-spacing 4rem; 46 | } 47 | 48 | .off-canvas-overlay { 49 | background: rgba($dark-color, .1); 50 | border-color: transparent; 51 | border-radius: 0; 52 | bottom: 0; 53 | display: none; 54 | height: 100%; 55 | left: 0; 56 | position: fixed; 57 | right: 0; 58 | top: 0; 59 | width: 100%; 60 | } 61 | 62 | .off-canvas-sidebar { 63 | &:target, 64 | &.active { 65 | transform: translateX(0); 66 | } 67 | 68 | &:target ~ .off-canvas-overlay, 69 | &.active ~ .off-canvas-overlay { 70 | display: block; 71 | z-index: $zindex-1; 72 | } 73 | } 74 | } 75 | 76 | // Responsive layout 77 | @media (min-width: $off-canvas-breakpoint) { 78 | .off-canvas { 79 | &.off-canvas-sidebar-show { 80 | .off-canvas-toggle { 81 | display: none; 82 | } 83 | 84 | .off-canvas-sidebar { 85 | flex: 0 0 auto; 86 | position: relative; 87 | transform: none; 88 | } 89 | 90 | .off-canvas-overlay { 91 | display: none !important; 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /release/js/progressbar.js: -------------------------------------------------------------------------------- 1 | let startingTime = 0 2 | let endingTime = 1 3 | let completeCallback = function(){} 4 | let visualUpdates 5 | let grower 6 | let completeTimeout = setTimeout(function () {completeCallback() }, 1000) 7 | let completionSound = document.getElementById("timer-completion") 8 | let startSound = document.getElementById("timer-start") 9 | let masterVolume = 0.6 10 | completionSound.volume = masterVolume 11 | startSound.volume = masterVolume 12 | 13 | let updateVisuals = function () { 14 | const totalTime = endingTime - startingTime 15 | const passedTime = Date.now() - startingTime 16 | const percent = passedTime / totalTime * 100 17 | 18 | if (percent < 100) { 19 | for (i = 0; i < grower.length; i++) { 20 | grower[i].style.width = percent.toFixed(2) + "%" 21 | } 22 | } else { 23 | for (i = 0; i < grower.length; i++) { 24 | grower[i].style.width = "100%" 25 | } 26 | clearInterval(visualUpdates) 27 | } 28 | } 29 | 30 | window.timerBar = function (minutes, start, callback) { 31 | clearTimeout(completeTimeout) 32 | grower = document.getElementsByClassName("growing-bar") 33 | 34 | startingTime = Date.now() - start * 60 * 1000 35 | endingTime = startingTime + minutes * 60 * 1000 36 | 37 | const totalTime = endingTime - startingTime 38 | const passedTime = Date.now() - startingTime 39 | const percent = (passedTime / totalTime * 100).toFixed(2) 40 | 41 | startSound.play() 42 | 43 | for (i = 0; i < grower.length; i++) { 44 | grower[i].style.width = percent + "%" 45 | } 46 | 47 | visualUpdates = setInterval(() => { 48 | if (!document.hidden) {updateVisuals()}}, 100) 49 | 50 | completeCallback = callback; 51 | completeTimeout = setTimeout(() => { 52 | completionSound.play() 53 | completeCallback() 54 | }, endingTime - Date.now()) 55 | } 56 | 57 | window.stopTimerBar = function () { 58 | clearTimeout(completeTimeout) 59 | clearInterval(visualUpdates) 60 | } 61 | 62 | window.clearTimerBar = function () { 63 | if (typeof grower == 'undefined') { 64 | grower = document.getElementsByClassName("growing-bar") 65 | } 66 | for (i = 0; i < grower.length; i++) { 67 | grower[i].style.width = "0%" 68 | } 69 | } -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_typography.scss: -------------------------------------------------------------------------------- 1 | // Typography 2 | // Headings 3 | h1, 4 | h2, 5 | h3, 6 | h4, 7 | h5, 8 | h6 { 9 | color: inherit; 10 | font-weight: 500; 11 | line-height: 1.2; 12 | margin-bottom: .5em; 13 | margin-top: 0; 14 | } 15 | .h1, 16 | .h2, 17 | .h3, 18 | .h4, 19 | .h5, 20 | .h6 { 21 | font-weight: 500; 22 | } 23 | h1, 24 | .h1 { 25 | font-size: 2rem; 26 | } 27 | h2, 28 | .h2 { 29 | font-size: 1.6rem; 30 | } 31 | h3, 32 | .h3 { 33 | font-size: 1.4rem; 34 | } 35 | h4, 36 | .h4 { 37 | font-size: 1.2rem; 38 | } 39 | h5, 40 | .h5 { 41 | font-size: 1rem; 42 | } 43 | h6, 44 | .h6 { 45 | font-size: .8rem; 46 | } 47 | 48 | // Paragraphs 49 | p { 50 | margin: 0 0 $line-height; 51 | } 52 | 53 | // Semantic text elements 54 | a, 55 | ins, 56 | u { 57 | text-decoration-skip: ink edges; 58 | } 59 | 60 | abbr[title] { 61 | border-bottom: $border-width dotted; 62 | cursor: help; 63 | text-decoration: none; 64 | } 65 | 66 | kbd { 67 | @include label-base(); 68 | @include label-variant($light-color, $dark-color); 69 | font-size: $font-size-sm; 70 | } 71 | 72 | mark { 73 | @include label-variant($body-font-color, $highlight-color); 74 | border-bottom: $unit-o solid darken($highlight-color, 15%); 75 | border-radius: $border-radius; 76 | padding: $unit-o $unit-h 0; 77 | } 78 | 79 | // Blockquote 80 | blockquote { 81 | border-left: $border-width-lg solid $border-color; 82 | margin-left: 0; 83 | padding: $unit-2 $unit-4; 84 | 85 | p:last-child { 86 | margin-bottom: 0; 87 | } 88 | } 89 | 90 | // Lists 91 | ul, 92 | ol { 93 | margin: $unit-4 0 $unit-4 $unit-4; 94 | padding: 0; 95 | 96 | ul, 97 | ol { 98 | margin: $unit-4 0 $unit-4 $unit-4; 99 | } 100 | 101 | li { 102 | margin-top: $unit-2; 103 | } 104 | } 105 | 106 | ul { 107 | list-style: disc inside; 108 | 109 | ul { 110 | list-style-type: circle; 111 | } 112 | } 113 | 114 | ol { 115 | list-style: decimal inside; 116 | 117 | ol { 118 | list-style-type: lower-alpha; 119 | } 120 | } 121 | 122 | dl { 123 | dt { 124 | font-weight: bold; 125 | } 126 | dd { 127 | margin: $unit-2 0 $unit-4 0; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /assets/scss/addr/_dashboardtable.scss: -------------------------------------------------------------------------------- 1 | //.percentball is around line 60 2 | //TABLE CELLS 3 | .cell { 4 | font-size: $unit-3; 5 | 6 | &.new { 7 | animation-name: attention; 8 | animation-duration: 4s; 9 | } 10 | 11 | span { 12 | display: block; 13 | float: left; 14 | clear: both; 15 | } 16 | 17 | .firstcol { 18 | width: 40px; 19 | } 20 | .name { 21 | font-size: $unit-4; 22 | font-weight: 600; 23 | } 24 | .namenote { 25 | padding: 0 6px; 26 | color: $error-color !important; 27 | font-weight: 400; 28 | color: $m-color; 29 | } 30 | //.phone { font-weight: 600; } 31 | .address { 32 | color: $gray-color-dark; 33 | } 34 | 35 | .mark { 36 | border-radius: $unit-3; 37 | padding: 2px 10px 2px 0; 38 | margin: 2px; 39 | font-weight: 600; 40 | 41 | .ball { 42 | border-radius: 0.5rem; 43 | height: 1rem; 44 | min-width: 1rem; 45 | padding: 0 3px; 46 | text-align: center; 47 | margin: 0 8px 0 2px; 48 | font-weight: 700; 49 | box-shadow: inset 1px 1px 1px hsl(0, 0%, 0%, 0.6); 50 | &.lighter { 51 | background-color: hsl(0, 0%, 100%, 0.55); 52 | } 53 | } 54 | } 55 | } 56 | 57 | //PERCENT BALL 58 | .percentball { 59 | width: $unit-6; 60 | height: $unit-6; 61 | border-radius: 50%; 62 | overflow: hidden; 63 | background: hsl(0, 0%, 80%); 64 | position: relative; 65 | display: inline-block; 66 | vertical-align: middle; 67 | margin: $unit-o $unit-1; 68 | text-align: center; 69 | 70 | .percent { 71 | background-color: hsl(207, 100%, 50%); 72 | width: 100%; 73 | position: absolute; 74 | bottom: 0; 75 | 76 | &.warn { 77 | background-color: $warning-color; 78 | } 79 | 80 | &.done { 81 | background-color: $success-color; 82 | } 83 | 84 | &.danger { 85 | background-color: $error-color; 86 | animation: blink 0.7s infinite; 87 | } 88 | } 89 | 90 | .text { 91 | font-size: 0.7rem; 92 | font-weight: 600; 93 | text-shadow: 1px 1px 1px hsla(0, 0%, 20%, 0.6); 94 | color: hsl(0, 0%, 100%); 95 | z-index: 1; 96 | position: absolute; 97 | top: 50%; 98 | left: 50%; 99 | transform: translate(-50%, -50%); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /assets/scss/addr/_menubar.scss: -------------------------------------------------------------------------------- 1 | //MENUBAR 2 | .menubar { 3 | background-color: $m-color; 4 | position: fixed; 5 | bottom: 0px; 6 | width: 100%; 7 | height: $unit-10; 8 | border-top: solid $unit-h $m-color-lighter; 9 | z-index: $zindex-4; 10 | 11 | display: flex; 12 | flex-wrap: wrap; 13 | justify-content: flex-start; 14 | 15 | box-shadow: inset 0 0 $unit-4 $m-color-dark; 16 | 17 | .section { 18 | &:not(:first-child):last-child { 19 | margin-left: auto; 20 | display: flex; 21 | } 22 | } 23 | .logo { 24 | height: 22px; 25 | margin: $unit-2 $unit-3; 26 | } 27 | 28 | .menu-item .item, 29 | .menu-item button { 30 | color: $ms-text-color; 31 | font-weight: 400; 32 | display: block; 33 | padding: $unit-2 $unit-3; 34 | border: none; 35 | background-color: $m-color; 36 | 37 | &:focus, 38 | &:hover, 39 | &:active { 40 | background-color: $m-color-light; 41 | text-decoration: none; 42 | color: $ms-link-color; 43 | border: none; 44 | outline: none; 45 | } 46 | 47 | i { 48 | padding: 0 $unit-1; 49 | display: unset; 50 | } 51 | } 52 | 53 | .navmenu { 54 | padding: 0px; 55 | display: flex; 56 | } 57 | 58 | .fa { 59 | color: $ms-text-color; 60 | padding: 12px; 61 | } 62 | 63 | .has-dropup { 64 | .dropup { 65 | visibility: hidden; 66 | opacity: 0; 67 | transition: visibility 0s, opacity 0.2s ease-in-out; 68 | color: $ms-text-color; 69 | padding: $unit-2; 70 | bottom: $unit-9; 71 | width: 260px; 72 | position: fixed; 73 | background-color: $m-color-light; 74 | z-index: zindex-4; 75 | 76 | &.right { 77 | right: 0px; 78 | } 79 | 80 | 81 | } 82 | 83 | &:hover { 84 | .dropup { 85 | visibility: visible; 86 | opacity: 1; 87 | 88 | ::after { 89 | position: absolute; 90 | width: 100%; 91 | bottom: -10px; 92 | height: 12px; 93 | display: block; 94 | content: ""; 95 | } 96 | } 97 | 98 | background-color: $m-color-light; 99 | .dropup-trigger { 100 | color: $ms-link-color; 101 | position: relative; 102 | } 103 | } 104 | } 105 | } 106 | // END OF MENUBAR 107 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_sliders.scss: -------------------------------------------------------------------------------- 1 | // Sliders 2 | // Credit: https://css-tricks.com/styling-cross-browser-compatible-range-inputs-css/ 3 | .slider { 4 | appearance: none; 5 | background: transparent; 6 | display: block; 7 | width: 100%; 8 | height: $unit-6; 9 | 10 | &:focus { 11 | @include control-shadow(); 12 | outline: none; 13 | } 14 | 15 | &.tooltip:not([data-tooltip]) { 16 | &::after { 17 | content: attr(value); 18 | } 19 | } 20 | 21 | // Slider Thumb 22 | &::-webkit-slider-thumb { 23 | -webkit-appearance: none; 24 | background: $primary-color; 25 | border: 0; 26 | border-radius: 50%; 27 | height: $unit-3; 28 | margin-top: -($unit-3 - $unit-h) / 2; 29 | transition: transform .2s; 30 | width: $unit-3; 31 | } 32 | &::-moz-range-thumb { 33 | background: $primary-color; 34 | border: 0; 35 | border-radius: 50%; 36 | height: $unit-3; 37 | transition: transform .2s; 38 | width: $unit-3; 39 | } 40 | &::-ms-thumb { 41 | background: $primary-color; 42 | border: 0; 43 | border-radius: 50%; 44 | height: $unit-3; 45 | transition: transform .2s; 46 | width: $unit-3; 47 | } 48 | 49 | &:active { 50 | &::-webkit-slider-thumb { 51 | transform: scale(1.25); 52 | } 53 | &::-moz-range-thumb { 54 | transform: scale(1.25); 55 | } 56 | &::-ms-thumb { 57 | transform: scale(1.25); 58 | } 59 | } 60 | 61 | &:disabled, 62 | &.disabled { 63 | &::-webkit-slider-thumb { 64 | background: $gray-color-light; 65 | transform: scale(1); 66 | } 67 | &::-moz-range-thumb { 68 | background: $gray-color-light; 69 | transform: scale(1); 70 | } 71 | &::-ms-thumb { 72 | background: $gray-color-light; 73 | transform: scale(1); 74 | } 75 | } 76 | 77 | // Slider Track 78 | &::-webkit-slider-runnable-track { 79 | background: $bg-color-dark; 80 | border-radius: $border-radius; 81 | height: $unit-h; 82 | width: 100%; 83 | } 84 | &::-moz-range-track { 85 | background: $bg-color-dark; 86 | border-radius: $border-radius; 87 | height: $unit-h; 88 | width: 100%; 89 | } 90 | &::-ms-track { 91 | background: $bg-color-dark; 92 | border-radius: $border-radius; 93 | height: $unit-h; 94 | width: 100%; 95 | } 96 | &::-ms-fill-lower { 97 | background: $primary-color; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_comparison-sliders.scss: -------------------------------------------------------------------------------- 1 | // Image comparison slider 2 | // Credit: http://codepen.io/solipsistacp/pen/Gpmaq 3 | .comparison-slider { 4 | height: 50vh; 5 | overflow: hidden; 6 | position: relative; 7 | width: 100%; 8 | -webkit-overflow-scrolling: touch; 9 | 10 | .comparison-before, 11 | .comparison-after { 12 | height: 100%; 13 | left: 0; 14 | margin: 0; 15 | overflow: hidden; 16 | position: absolute; 17 | top: 0; 18 | 19 | img { 20 | height: 100%; 21 | object-fit: cover; 22 | object-position: left center; 23 | position: absolute; 24 | width: 100%; 25 | } 26 | } 27 | 28 | .comparison-before { 29 | width: 100%; 30 | z-index: 1; 31 | 32 | .comparison-label { 33 | right: $unit-4; 34 | } 35 | } 36 | 37 | .comparison-after { 38 | max-width: 100%; 39 | min-width: 0; 40 | z-index: 2; 41 | 42 | &::before { 43 | background: transparent; 44 | content: ""; 45 | cursor: default; 46 | height: 100%; 47 | left: 0; 48 | position: absolute; 49 | right: $unit-4; 50 | top: 0; 51 | z-index: $zindex-0; 52 | } 53 | 54 | &::after { 55 | background: currentColor; 56 | border-radius: 50%; 57 | box-shadow: 0 -5px, 0 5px; 58 | color: $light-color; 59 | content: ""; 60 | height: 3px; 61 | position: absolute; 62 | right: $unit-2; 63 | top: 50%; 64 | transform: translate(50%, -50%); 65 | width: 3px; 66 | } 67 | 68 | .comparison-label { 69 | left: $unit-4; 70 | } 71 | } 72 | 73 | .comparison-resizer { 74 | animation: first-run 1.5s 1 ease-in-out; 75 | cursor: ew-resize; 76 | height: $unit-4; 77 | left: 0; 78 | max-width: 100%; 79 | min-width: $unit-4; 80 | opacity: 0; 81 | outline: none; 82 | position: relative; 83 | resize: horizontal; 84 | top: 50%; 85 | transform: translateY(-50%) scaleY(30); 86 | width: 0; 87 | } 88 | 89 | .comparison-label { 90 | background: rgba($dark-color, .5); 91 | bottom: $unit-4; 92 | color: $light-color; 93 | padding: $unit-1 $unit-2; 94 | position: absolute; 95 | user-select: none; 96 | } 97 | } 98 | 99 | @keyframes first-run { 100 | 0% { 101 | width: 0; 102 | } 103 | 25% { 104 | width: $unit-12; 105 | } 106 | 50% { 107 | width: $unit-4; 108 | } 109 | 75% { 110 | width: $unit-6; 111 | } 112 | 100% { 113 | width: 0; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/icons/_icons-navigation.scss: -------------------------------------------------------------------------------- 1 | // Icon arrows 2 | .icon-arrow-down, 3 | .icon-arrow-left, 4 | .icon-arrow-right, 5 | .icon-arrow-up, 6 | .icon-downward, 7 | .icon-back, 8 | .icon-forward, 9 | .icon-upward { 10 | &::before { 11 | border: $icon-border-width solid currentColor; 12 | border-bottom: 0; 13 | border-right: 0; 14 | height: .65em; 15 | width: .65em; 16 | } 17 | } 18 | 19 | .icon-arrow-down { 20 | &::before { 21 | transform: translate(-50%, -75%) rotate(225deg); 22 | } 23 | } 24 | 25 | .icon-arrow-left { 26 | &::before { 27 | transform: translate(-25%, -50%) rotate(-45deg); 28 | } 29 | } 30 | 31 | .icon-arrow-right { 32 | &::before { 33 | transform: translate(-75%, -50%) rotate(135deg); 34 | } 35 | } 36 | 37 | .icon-arrow-up { 38 | &::before { 39 | transform: translate(-50%, -25%) rotate(45deg); 40 | } 41 | } 42 | 43 | .icon-back, 44 | .icon-forward { 45 | &::after { 46 | background: currentColor; 47 | height: $icon-border-width; 48 | width: .8em; 49 | } 50 | } 51 | 52 | .icon-downward, 53 | .icon-upward { 54 | &::after { 55 | background: currentColor; 56 | height: .8em; 57 | width: $icon-border-width; 58 | } 59 | } 60 | 61 | .icon-back { 62 | &::after { 63 | left: 55%; 64 | } 65 | &::before { 66 | transform: translate(-50%, -50%) rotate(-45deg); 67 | } 68 | } 69 | 70 | .icon-downward { 71 | &::after { 72 | top: 45%; 73 | } 74 | &::before { 75 | transform: translate(-50%, -50%) rotate(-135deg); 76 | } 77 | } 78 | 79 | .icon-forward { 80 | &::after { 81 | left: 45%; 82 | } 83 | &::before { 84 | transform: translate(-50%, -50%) rotate(135deg); 85 | } 86 | } 87 | 88 | .icon-upward { 89 | &::after { 90 | top: 55%; 91 | } 92 | &::before { 93 | transform: translate(-50%, -50%) rotate(45deg); 94 | } 95 | } 96 | 97 | // Icon caret 98 | .icon-caret { 99 | &::before { 100 | border-top: .3em solid currentColor; 101 | border-right: .3em solid transparent; 102 | border-left: .3em solid transparent; 103 | height: 0; 104 | transform: translate(-50%, -25%); 105 | width: 0; 106 | } 107 | } 108 | 109 | // Icon menu 110 | .icon-menu { 111 | &::before { 112 | background: currentColor; 113 | box-shadow: 0 -.35em, 0 .35em; 114 | height: $icon-border-width; 115 | width: 100%; 116 | } 117 | } 118 | 119 | // Icon apps 120 | .icon-apps { 121 | &::before { 122 | background: currentColor; 123 | box-shadow: -.35em -.35em, -.35em 0, -.35em .35em, 0 -.35em, 0 .35em, .35em -.35em, .35em 0, .35em .35em; 124 | height: 3px; 125 | width: 3px; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /assets/scss/addr/_login.scss: -------------------------------------------------------------------------------- 1 | .login-container { 2 | height: 100%; 3 | padding: 0; 4 | margin: 0; 5 | display: flex; 6 | align-items: center; 7 | justify-content: center; 8 | background: radial-gradient(lighten($m-color, 11%), $m-color); 9 | } 10 | 11 | .login-box { 12 | position: relative; 13 | padding: 0 20px 10px !important; 14 | box-shadow: 4px 4px 4px hsl(120, 3%, 4%, 0.2); 15 | 16 | .head-logo { 17 | background-color: $m-color; 18 | position: relative; 19 | top: -20px; 20 | height: 44px; 21 | margin: 0 14px; 22 | border-radius: 4px; 23 | padding: 6px 20px; 24 | text-align: center; 25 | box-shadow: 0 0 10px hsl(210, 62%, 55%, 0.3); 26 | 27 | img { 28 | height: 30px; 29 | } 30 | 31 | label { 32 | font-weight: 600; 33 | } 34 | } //head logo 35 | 36 | .form-input-hint { 37 | position: absolute; 38 | text-align: right; 39 | right: 20px; 40 | margin-top: -18px; 41 | font-size: $unit-3; 42 | animation: fadein 0.6s; 43 | } 44 | 45 | input { 46 | width: 260px; 47 | margin-bottom: 16px; 48 | } 49 | .btn { 50 | margin-top: 30px; 51 | height: 2rem; 52 | } 53 | 54 | .bottom { 55 | text-align: center; 56 | font-size: $unit-4; 57 | } 58 | 59 | .login-error { 60 | position: absolute; 61 | top: 100px; 62 | height: 100px; 63 | padding-top: 40px; 64 | left: 30px; 65 | width: 240px; 66 | background-color: hsl(0, 100%, 55%, 0.8); 67 | border-radius: 10px; 68 | text-align: center; 69 | color: white; 70 | font-weight: 500; 71 | animation: grow 0.25s; 72 | 73 | i { 74 | position: absolute; 75 | top: 10px; 76 | right: 10px; 77 | } 78 | } 79 | } 80 | 81 | .load-box { 82 | position: relative; 83 | padding: 0 20px 10px !important; 84 | box-shadow: 4px 4px 4px hsl(120, 3%, 4%, 0.2); 85 | color: lighten($m-color, 10%); 86 | text-align: center; 87 | 88 | h1 { 89 | font-size: 26px; 90 | margin: 20px; 91 | color: lighten($m-color, 40%); 92 | } 93 | 94 | p { 95 | margin: 10px 4px 4px; 96 | width: 250px; 97 | font-size: 12px; 98 | display: inline-block; 99 | } 100 | 101 | //[:div.load-context 102 | //[:h3 "Aboneler"] 103 | //[:span.details (reveal :customer :loaded)] 104 | //[:div.bar [:div.percent]]] 105 | 106 | .load-context { 107 | width: 100%; 108 | 109 | h3 { 110 | font-size: 16px; 111 | margin: 4px 0 -1px 0; 112 | } 113 | 114 | .details { 115 | display: block; 116 | float: left; 117 | z-index: 5; 118 | color: lighten($m-color, 40%); 119 | margin: -1px 0 0 3px; 120 | font-size: 13px; 121 | font-weight: bold; 122 | } 123 | 124 | .bar { 125 | border-radius: 6px; 126 | background-color: lighten($m-color, 40%); 127 | } 128 | .percent { 129 | border-radius: 6px; 130 | transition: width 0.2s ease-out; 131 | height: 18px; 132 | background-color: lighten($m-color, 8%); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_carousels.scss: -------------------------------------------------------------------------------- 1 | // Carousels 2 | // The number of carousel images 3 | $carousel-number: 8; 4 | 5 | %carousel-image-checked { 6 | animation: carousel-slidein .75s ease-in-out 1; 7 | opacity: 1; 8 | z-index: $zindex-1; 9 | } 10 | 11 | %carousel-nav-checked { 12 | color: $gray-color-light; 13 | } 14 | 15 | .carousel { 16 | background: $bg-color; 17 | display: block; 18 | overflow: hidden; 19 | position: relative; 20 | width: 100%; 21 | -webkit-overflow-scrolling: touch; 22 | z-index: $zindex-0; 23 | 24 | .carousel-container { 25 | height: 100%; 26 | left: 0; 27 | position: relative; 28 | &::before { 29 | content: ""; 30 | display: block; 31 | padding-bottom: 56.25%; 32 | } 33 | 34 | .carousel-item { 35 | animation: carousel-slideout 1s ease-in-out 1; 36 | height: 100%; 37 | left: 0; 38 | margin: 0; 39 | opacity: 0; 40 | position: absolute; 41 | top: 0; 42 | width: 100%; 43 | 44 | &:hover { 45 | .item-prev, 46 | .item-next { 47 | opacity: 1; 48 | } 49 | } 50 | } 51 | 52 | .item-prev, 53 | .item-next { 54 | background: rgba($gray-color-light, .25); 55 | border-color: rgba($gray-color-light, .5); 56 | color: $gray-color-light; 57 | opacity: 0; 58 | position: absolute; 59 | top: 50%; 60 | transition: all .4s; 61 | transform: translateY(-50%); 62 | z-index: $zindex-1; 63 | } 64 | .item-prev { 65 | left: 1rem; 66 | } 67 | .item-next { 68 | right: 1rem; 69 | } 70 | } 71 | 72 | .carousel-locator { 73 | @for $i from 1 through ($carousel-number) { 74 | &:nth-of-type(#{$i}):checked ~ .carousel-container .carousel-item:nth-of-type(#{$i}) { 75 | @extend %carousel-image-checked; 76 | } 77 | } 78 | 79 | @for $i from 1 through ($carousel-number) { 80 | &:nth-of-type(#{$i}):checked ~ .carousel-nav .nav-item:nth-of-type(#{$i}) { 81 | @extend %carousel-nav-checked; 82 | } 83 | } 84 | } 85 | 86 | .carousel-nav { 87 | bottom: $layout-spacing; 88 | display: flex; 89 | justify-content: center; 90 | left: 50%; 91 | position: absolute; 92 | transform: translateX(-50%); 93 | width: 10rem; 94 | z-index: $zindex-1; 95 | 96 | .nav-item { 97 | color: rgba($gray-color-light, .5); 98 | display: block; 99 | flex: 1 0 auto; 100 | height: $unit-8; 101 | margin: $unit-1; 102 | max-width: 2.5rem; 103 | position: relative; 104 | 105 | &::before { 106 | background: currentColor; 107 | content: ""; 108 | display: block; 109 | height: $unit-h; 110 | position: absolute; 111 | top: .5rem; 112 | width: 100%; 113 | } 114 | } 115 | } 116 | } 117 | 118 | @keyframes carousel-slidein { 119 | 0% { 120 | transform: translateX(100%); 121 | } 122 | 100% { 123 | transform: translateX(0); 124 | } 125 | } 126 | 127 | @keyframes carousel-slideout { 128 | 0% { 129 | opacity: 1; 130 | transform: translateX(0); 131 | } 132 | 100% { 133 | opacity: 1; 134 | transform: translateX(-50%); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # ADHD Focus 2 | 3 | This is a TODO app follows Eisenhower method and main focus is helping ADHD people to improve their time management skills. 4 | 5 | You can access to the app here: [https://addfocus.5apps.com/](https://addfocus.5apps.com/) 6 | 7 | ## What is the Eisenhower Method 8 | 9 | The "Eisenhower Method" stems from a quote attributed to Dwight D. Eisenhower: "I have two kinds of problems, the urgent and the important. The urgent are not important, and the important are never urgent."Note that Eisenhower does not claim this insight for his own, but attributes it to an (unnamed) "former college president." 10 | 11 | Using the Eisenhower Decision Principle, tasks are evaluated using the criteria important/unimportant and urgent/not urgent and then placed in according quadrants in an Eisenhower Matrix. Tasks are then handled as follows: 12 | 13 | - **Important/Urgent** quadrant are done immediately and personally e.g. crises, deadlines, problems. 14 | - **Important/Not Urgent** quadrant get an end date and are done personally e.g. relationships, planning, recreation. 15 | - **Unimportant/Urgent** quadrant are delegated e.g. interruptions, meetings, activities. 16 | - **Unimportant/Not Urgent** quadrant are dropped e.g. time wasters, pleasant activities, trivia. 17 | 18 | [![Eisenhower Method](https://upload.wikimedia.org/wikipedia/commons/3/32/MerrillCoveyMatrix.png)](https://en.wikipedia.org/wiki/Time_management#The_Eisenhower_Method) 19 | 20 | ## Features 21 | - Gamification 22 | - You earn levels as you complete tasks 23 | - If you work everyday you get bonus XP 24 | - Add your desired time wasters and win them with XP points 25 | - You will collect coins to play SlotMachine game to win your desired tasks. (Eg: Watch 1 episoe of your favorite series) 26 | - Instead of releasing big amount dopamine at once with gambling it will be divided to each task so after completing each task you'll release small amount dopamine. It will create addiction in long term. 27 | 28 | ## Why it's good for ADHD people 29 | - You never see all tasks together and get overwhelmed. 30 | - It helps you to focus most important tasks 31 | - Design is distraction friendly you wont get distracted with other tasks or other elements on the page. 32 | - Gamification designed in the way to make you addicted to complete tasks. 33 | - It uses basic casino games methods to trick your reward system (https://en.wikipedia.org/wiki/Nucleus_accumbens#Addiction) 34 | - I've followed most ideas from ADDitute magazine when I design the app (https://www.additudemag.com/category/manage-adhd-life/getting-things-done/) 35 | 36 | # Roadmap 37 | - [x] Basic functionality 38 | - [x] Saving sessions to history 39 | - [x] Connect dropbox to save & sync data 40 | - [x] Detailed history page 41 | - [x] Add XP earning system 42 | - [x] Levelling system 43 | - [ ] Add your own rewards 44 | - [ ] Slot machines to earn rewards & collectibles 45 | 46 | ## Maybe 47 | - [ ] Earning random collectibles after tasks 48 | - [ ] Chrome Browser Extention (App) 49 | - [ ] Mobile App (Currently accesible via mobile browser) 50 | 51 | 52 | ### References 53 | * [Addiction and Dopamine](https://www.youtube.com/watch?v=NxHNxmJv2bQ) 54 | * [Thomas Brown](https://www.youtube.com/watch?v=1LkZguH9o7o) 55 | * [ADDitute Magazine](https://www.additudemag.com/category/manage-adhd-life/getting-things-done/) 56 | * [Slot Machines & Addiction](https://www.youtube.com/watch?v=JgkvTRz_Alo) -------------------------------------------------------------------------------- /assets/scss/addr/_progressbar.scss: -------------------------------------------------------------------------------- 1 | //Credit this guy: https://codepen.io/rgg/pen/QbRyOq 2 | 3 | $yellow: #f1c40f; 4 | $lime: hsl(85, 100%, 39%); 5 | $navy: #0a4069; 6 | $cyan: #57caf4; 7 | $red: #ec008c; 8 | $white: #fefefe; 9 | $gray: #444; 10 | $lightGray: lighten($gray, 30); 11 | 12 | .chart 13 | { 14 | font-size: 1em; 15 | perspective: 1000px; 16 | perspective-origin: 50% 50%; 17 | backface-visibility: visible; 18 | } 19 | 20 | $faceColor: rgba($white, .3); 21 | $growColor: rgba($lime, .6); 22 | 23 | .bar 24 | { 25 | font-size: 1em; 26 | 27 | position: relative; 28 | 29 | height: 10em; 30 | 31 | transition: all 0.9s ease-in-out; 32 | transform: rotateX(60deg) rotateY(0deg); 33 | 34 | transform-style: preserve-3d; 35 | 36 | .face 37 | { 38 | font-size: 2em; 39 | 40 | position: relative; 41 | 42 | width: 100%; 43 | height: 2em; 44 | 45 | background-color: $faceColor; 46 | 47 | &.side-a, 48 | &.side-b 49 | { 50 | width: 2em; 51 | } 52 | } 53 | .side-a 54 | { 55 | transform: rotateX(90deg) rotateY(-90deg) translateX(2em) translateY(1em) translateZ(1em); 56 | } 57 | .side-b 58 | { 59 | transform: rotateX(90deg) rotateY(-90deg) translateX(4em) translateY(1em) translateZ(-1em); 60 | position: absolute; 61 | right: 0; 62 | } 63 | .side-0 64 | { 65 | transform: rotateX(90deg) rotateY(0) translateX(0) translateY(1em) translateZ(-1em); 66 | } 67 | .side-1 68 | { 69 | transform: rotateX(90deg) rotateY(0) translateX(0) translateY(1em) translateZ(3em); 70 | } 71 | .top 72 | { 73 | transform: rotateX(0deg) rotateY(0) translateX(0em) translateY(4em) translateZ(2em); 74 | } 75 | .floor 76 | { 77 | box-shadow: 0 .1em 0.6em rgba(0,0,0,.3), .6em -0.5em 3em rgba(0,0,0,.3), 1em -1em 8em $white; 78 | } 79 | } 80 | 81 | .growing-bar 82 | { 83 | transition: all 0.1s linear; 84 | width: 0; 85 | background-color: $growColor; 86 | height: 2em; 87 | } 88 | 89 | @mixin drawSkin($color, $name) 90 | { 91 | .bar.#{$name} 92 | { 93 | .side-a, 94 | // &.bar-100 .side-b, 95 | .growing-bar 96 | { 97 | background-color: rgba($color, .6); 98 | } 99 | .side-0 .growing-bar 100 | { 101 | box-shadow: -0.5em -1.5em 4em $color; 102 | } 103 | .floor .growing-bar 104 | { 105 | box-shadow: 0em 0em 2em $color; 106 | } 107 | } 108 | } 109 | 110 | @mixin drawFaces($color, $name) 111 | { 112 | .chart .bar.#{$name} .face 113 | { 114 | background-color: rgba($color, .2); 115 | } 116 | } 117 | 118 | //@include drawSkin(rgba($yellow, .8), 'yellow'); 119 | //@include drawSkin(rgba($red, .8), 'red'); 120 | @include drawSkin($cyan, 'cyan'); 121 | //@include drawSkin(rgba($navy, .8), 'navy'); 122 | @include drawSkin($lime, 'lime'); 123 | //@include drawSkin($white, 'white'); 124 | //@include drawSkin($gray, 'gray'); 125 | 126 | //@include drawFaces(rgba($yellow, .6), 'yellow-face'); 127 | @include drawFaces($lime, 'lime-face'); 128 | //@include drawFaces(rgba($red, .6), 'red-face'); 129 | //@include drawFaces(rgba($navy, .6), 'navy-face'); 130 | @include drawFaces($cyan, 'cyan-face'); 131 | //@include drawFaces($gray, 'gray-face'); 132 | //@include drawFaces($lightGray, 'lightGray-face'); 133 | 134 | //@for $i from 0 to 101 135 | //{ 136 | // .bar-#{$i} 137 | // { 138 | // .growing-bar 139 | // { 140 | // width: percentage($i/100); 141 | // } 142 | // } 143 | //} -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_parallax.scss: -------------------------------------------------------------------------------- 1 | // Parallax 2 | $parallax-deg: 3deg !default; 3 | $parallax-offset: 4.5px !default; 4 | $parallax-offset-z: 50px !default; 5 | $parallax-perspective: 1000px !default; 6 | $parallax-scale: .95 !default; 7 | $parallax-fade-color: rgba(255, 255, 255, .35) !default; 8 | 9 | // Mixin: Parallax direction 10 | @mixin parallax-dir() { 11 | height: 50%; 12 | outline: none; 13 | position: absolute; 14 | width: 50%; 15 | z-index: $zindex-1; 16 | } 17 | 18 | .parallax { 19 | display: block; 20 | height: auto; 21 | position: relative; 22 | width: auto; 23 | 24 | .parallax-content { 25 | @include shadow-variant(1rem); 26 | height: auto; 27 | transform: perspective($parallax-perspective); 28 | transform-style: preserve-3d; 29 | transition: all .4s ease; 30 | width: 100%; 31 | 32 | &::before { 33 | content: ""; 34 | display: block; 35 | height: 100%; 36 | left: 0; 37 | position: absolute; 38 | top: 0; 39 | width: 100%; 40 | } 41 | } 42 | 43 | .parallax-front { 44 | align-items: center; 45 | color: $light-color; 46 | display: flex; 47 | height: 100%; 48 | justify-content: center; 49 | left: 0; 50 | position: absolute; 51 | text-align: center; 52 | text-shadow: 0 0 20px rgba($dark-color, .75); 53 | top: 0; 54 | transform: translateZ($parallax-offset-z) scale($parallax-scale); 55 | transition: transform .4s; 56 | width: 100%; 57 | z-index: $zindex-0; 58 | } 59 | 60 | .parallax-top-left { 61 | @include parallax-dir(); 62 | left: 0; 63 | top: 0; 64 | 65 | &:focus ~ .parallax-content, 66 | &:hover ~ .parallax-content { 67 | transform: perspective($parallax-perspective) rotateX($parallax-deg) rotateY(-$parallax-deg); 68 | 69 | &::before { 70 | background: linear-gradient(135deg, $parallax-fade-color 0%, transparent 50%); 71 | } 72 | 73 | .parallax-front { 74 | transform: translate3d($parallax-offset, $parallax-offset, $parallax-offset-z) scale($parallax-scale); 75 | } 76 | } 77 | } 78 | 79 | .parallax-top-right { 80 | @include parallax-dir(); 81 | right: 0; 82 | top: 0; 83 | 84 | &:focus ~ .parallax-content, 85 | &:hover ~ .parallax-content { 86 | transform: perspective($parallax-perspective) rotateX($parallax-deg) rotateY($parallax-deg); 87 | 88 | &::before { 89 | background: linear-gradient(-135deg, $parallax-fade-color 0%, transparent 50%); 90 | } 91 | 92 | .parallax-front { 93 | transform: translate3d(-$parallax-offset, $parallax-offset, $parallax-offset-z) scale($parallax-scale); 94 | } 95 | } 96 | } 97 | 98 | .parallax-bottom-left { 99 | @include parallax-dir(); 100 | bottom: 0; 101 | left: 0; 102 | 103 | &:focus ~ .parallax-content, 104 | &:hover ~ .parallax-content { 105 | transform: perspective($parallax-perspective) rotateX(-$parallax-deg) rotateY(-$parallax-deg); 106 | 107 | &::before { 108 | background: linear-gradient(45deg, $parallax-fade-color 0%, transparent 50%); 109 | } 110 | 111 | .parallax-front { 112 | transform: translate3d($parallax-offset, -$parallax-offset, $parallax-offset-z) scale($parallax-scale); 113 | } 114 | } 115 | } 116 | 117 | .parallax-bottom-right { 118 | @include parallax-dir(); 119 | bottom: 0; 120 | right: 0; 121 | 122 | &:focus ~ .parallax-content, 123 | &:hover ~ .parallax-content { 124 | transform: perspective($parallax-perspective) rotateX(-$parallax-deg) rotateY($parallax-deg); 125 | 126 | &::before { 127 | background: linear-gradient(-45deg, $parallax-fade-color 0%, transparent 50%); 128 | } 129 | 130 | .parallax-front { 131 | transform: translate3d(-$parallax-offset, -$parallax-offset, $parallax-offset-z) scale($parallax-scale); 132 | } 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/icons/_icons-object.scss: -------------------------------------------------------------------------------- 1 | // Icon time 2 | .icon-time { 3 | border: $icon-border-width solid currentColor; 4 | border-radius: 50%; 5 | &::before { 6 | background: currentColor; 7 | height: .4em; 8 | transform: translate(-50%, -75%); 9 | width: $icon-border-width; 10 | } 11 | &::after { 12 | background: currentColor; 13 | height: .3em; 14 | transform: translate(-50%, -75%) rotate(90deg); 15 | transform-origin: 50% 90%; 16 | width: $icon-border-width; 17 | } 18 | } 19 | 20 | // Icon mail 21 | .icon-mail { 22 | &::before { 23 | border: $icon-border-width solid currentColor; 24 | border-radius: $border-radius; 25 | height: .8em; 26 | width: 1em; 27 | } 28 | &::after { 29 | border: $icon-border-width solid currentColor; 30 | border-right: 0; 31 | border-top: 0; 32 | height: .5em; 33 | transform: translate(-50%, -90%) rotate(-45deg) skew(10deg, 10deg); 34 | width: .5em; 35 | } 36 | } 37 | 38 | // Icon people 39 | .icon-people { 40 | &::before { 41 | border: $icon-border-width solid currentColor; 42 | border-radius: 50%; 43 | height: .45em; 44 | top: 25%; 45 | width: .45em; 46 | } 47 | &::after { 48 | border: $icon-border-width solid currentColor; 49 | border-radius: 50% 50% 0 0; 50 | height: .4em; 51 | top: 75%; 52 | width: .9em; 53 | } 54 | } 55 | 56 | // Icon message 57 | .icon-message { 58 | border: $icon-border-width solid currentColor; 59 | border-bottom: 0; 60 | border-radius: $border-radius; 61 | border-right: 0; 62 | &::before { 63 | border: $icon-border-width solid currentColor; 64 | border-bottom-right-radius: $border-radius; 65 | border-left: 0; 66 | border-top: 0; 67 | height: .8em; 68 | left: 65%; 69 | top: 40%; 70 | width: .7em; 71 | } 72 | &::after { 73 | background: currentColor; 74 | border-radius: $border-radius; 75 | height: .3em; 76 | left: 10%; 77 | top: 100%; 78 | transform: translate(0, -90%) rotate(45deg); 79 | width: $icon-border-width; 80 | } 81 | } 82 | 83 | // Icon photo 84 | .icon-photo { 85 | border: $icon-border-width solid currentColor; 86 | border-radius: $border-radius; 87 | &::before { 88 | border: $icon-border-width solid currentColor; 89 | border-radius: 50%; 90 | height: .25em; 91 | left: 35%; 92 | top: 35%; 93 | width: .25em; 94 | } 95 | &::after { 96 | border: $icon-border-width solid currentColor; 97 | border-bottom: 0; 98 | border-left: 0; 99 | height: .5em; 100 | left: 60%; 101 | transform: translate(-50%, 25%) rotate(-45deg); 102 | width: .5em; 103 | } 104 | } 105 | 106 | // Icon link 107 | .icon-link { 108 | &::before, 109 | &::after { 110 | border: $icon-border-width solid currentColor; 111 | border-radius: 5em 0 0 5em; 112 | border-right: 0; 113 | height: .5em; 114 | width: .75em; 115 | } 116 | &::before { 117 | transform: translate(-70%, -45%) rotate(-45deg); 118 | } 119 | &::after { 120 | transform: translate(-30%, -55%) rotate(135deg); 121 | } 122 | } 123 | 124 | // Icon location 125 | .icon-location { 126 | &::before { 127 | border: $icon-border-width solid currentColor; 128 | border-radius: 50% 50% 50% 0; 129 | height: .8em; 130 | transform: translate(-50%, -60%) rotate(-45deg); 131 | width: .8em; 132 | } 133 | &::after { 134 | border: $icon-border-width solid currentColor; 135 | border-radius: 50%; 136 | height: .2em; 137 | transform: translate(-50%, -80%); 138 | width: .2em; 139 | } 140 | } 141 | 142 | // Icon emoji 143 | .icon-emoji { 144 | border: $icon-border-width solid currentColor; 145 | border-radius: 50%; 146 | &::before { 147 | border-radius: 50%; 148 | box-shadow: -.17em -.1em, .17em -.1em; 149 | height: .15em; 150 | width: .15em; 151 | } 152 | &::after { 153 | border: $icon-border-width solid currentColor; 154 | border-bottom-color: transparent; 155 | border-radius: 50%; 156 | border-right-color: transparent; 157 | height: .5em; 158 | transform: translate(-50%, -40%) rotate(-135deg); 159 | width: .5em; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_buttons.scss: -------------------------------------------------------------------------------- 1 | // Buttons 2 | .btn { 3 | appearance: none; 4 | background: $bg-color-light; 5 | border: $border-width solid $primary-color; 6 | border-radius: $border-radius; 7 | color: $primary-color; 8 | cursor: pointer; 9 | display: inline-block; 10 | font-size: $font-size; 11 | height: $control-size; 12 | line-height: $line-height; 13 | outline: none; 14 | padding: $control-padding-y $control-padding-x; 15 | text-align: center; 16 | text-decoration: none; 17 | transition: background .2s, border .2s, box-shadow .2s, color .2s; 18 | user-select: none; 19 | vertical-align: middle; 20 | white-space: nowrap; 21 | &:focus { 22 | @include control-shadow(); 23 | } 24 | &:focus, 25 | &:hover { 26 | background: $secondary-color; 27 | border-color: $primary-color-dark; 28 | text-decoration: none; 29 | } 30 | &:active, 31 | &.active { 32 | background: $primary-color-dark; 33 | border-color: darken($primary-color-dark, 5%); 34 | color: $light-color; 35 | text-decoration: none; 36 | &.loading { 37 | &::after { 38 | border-bottom-color: $light-color; 39 | border-left-color: $light-color; 40 | } 41 | } 42 | } 43 | &[disabled], 44 | &:disabled, 45 | &.disabled { 46 | cursor: default; 47 | opacity: .5; 48 | pointer-events: none; 49 | } 50 | 51 | // Button Primary 52 | &.btn-primary { 53 | background: $primary-color; 54 | border-color: $primary-color-dark; 55 | color: $light-color; 56 | &:focus, 57 | &:hover { 58 | background: darken($primary-color-dark, 2%); 59 | border-color: darken($primary-color-dark, 5%); 60 | color: $light-color; 61 | } 62 | &:active, 63 | &.active { 64 | background: darken($primary-color-dark, 4%); 65 | border-color: darken($primary-color-dark, 7%); 66 | color: $light-color; 67 | } 68 | &.loading { 69 | &::after { 70 | border-bottom-color: $light-color; 71 | border-left-color: $light-color; 72 | } 73 | } 74 | } 75 | 76 | // Button Colors 77 | &.btn-success { 78 | @include button-variant($success-color); 79 | } 80 | 81 | &.btn-error { 82 | @include button-variant($error-color); 83 | } 84 | 85 | // Button Link 86 | &.btn-link { 87 | background: transparent; 88 | border-color: transparent; 89 | color: $link-color; 90 | &:focus, 91 | &:hover, 92 | &:active, 93 | &.active { 94 | color: $link-color-dark; 95 | } 96 | } 97 | 98 | // Button Sizes 99 | &.btn-sm { 100 | font-size: $font-size-sm; 101 | height: $control-size-sm; 102 | padding: $control-padding-y-sm $control-padding-x-sm; 103 | } 104 | 105 | &.btn-lg { 106 | font-size: $font-size-lg; 107 | height: $control-size-lg; 108 | padding: $control-padding-y-lg $control-padding-x-lg; 109 | } 110 | 111 | // Button Block 112 | &.btn-block { 113 | display: block; 114 | width: 100%; 115 | } 116 | 117 | // Button Action 118 | &.btn-action { 119 | width: $control-size; 120 | padding-left: 0; 121 | padding-right: 0; 122 | 123 | &.btn-sm { 124 | width: $control-size-sm; 125 | } 126 | 127 | &.btn-lg { 128 | width: $control-size-lg; 129 | } 130 | } 131 | 132 | // Button Clear 133 | &.btn-clear { 134 | background: transparent; 135 | border: 0; 136 | color: currentColor; 137 | height: $unit-5; 138 | line-height: $unit-4; 139 | margin-left: $unit-1; 140 | margin-right: -2px; 141 | opacity: 1; 142 | padding: $unit-h; 143 | text-decoration: none; 144 | width: $unit-5; 145 | 146 | &:focus, 147 | &:hover { 148 | background: rgba($bg-color, .5); 149 | opacity: .95; 150 | } 151 | 152 | &::before { 153 | content: "\2715"; 154 | } 155 | } 156 | } 157 | 158 | // Button groups 159 | .btn-group { 160 | display: inline-flex; 161 | flex-wrap: wrap; 162 | 163 | .btn { 164 | flex: 1 0 auto; 165 | &:first-child:not(:last-child) { 166 | border-bottom-right-radius: 0; 167 | border-top-right-radius: 0; 168 | } 169 | &:not(:first-child):not(:last-child) { 170 | border-radius: 0; 171 | margin-left: -$border-width; 172 | } 173 | &:last-child:not(:first-child) { 174 | border-bottom-left-radius: 0; 175 | border-top-left-radius: 0; 176 | margin-left: -$border-width; 177 | } 178 | &:focus, 179 | &:hover, 180 | &:active, 181 | &.active { 182 | z-index: $zindex-0; 183 | } 184 | } 185 | 186 | &.btn-group-block { 187 | display: flex; 188 | 189 | .btn { 190 | flex: 1 0 0; 191 | } 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_variables.scss: -------------------------------------------------------------------------------- 1 | // Core variables 2 | $version: "0.5.8"; 3 | 4 | // Core features 5 | $rtl: false !default; 6 | 7 | // Core colors 8 | $primary-color: hsl(210, 62%, 55%) !default; 9 | $primary-color-dark: darken($primary-color, 3%) !default; 10 | $primary-color-light: lighten($primary-color, 3%) !default; 11 | $secondary-color: lighten($primary-color, 37.5%) !default; 12 | $secondary-color-dark: darken($secondary-color, 3%) !default; 13 | $secondary-color-light: lighten($secondary-color, 3%) !default; 14 | 15 | // Gray colors 16 | $dark-color: hsl(217, 16%, 22%) !default; 17 | $light-color: hsl(0, 0%, 100%) !default; 18 | $gray-color: lighten($dark-color, 55%) !default; 19 | $gray-color-dark: darken($gray-color, 30%) !default; 20 | $gray-color-light: lighten($gray-color, 20%) !default; 21 | 22 | $border-color: lighten($dark-color, 65%) !default; 23 | $border-color-dark: darken($border-color, 10%) !default; 24 | $border-color-light: lighten($border-color, 8%) !default; 25 | $bg-color: lighten($dark-color, 75%) !default; 26 | $bg-color-dark: darken($bg-color, 3%) !default; 27 | $bg-color-light: $light-color !default; 28 | 29 | // Control colors 30 | $success-color: hsl(128, 57%, 45%) !default; 31 | $warning-color: hsl(43, 100%, 50%) !default; 32 | $error-color: hsl(0, 90%, 62%) !default; 33 | 34 | // Other colors 35 | $code-color: hsl(356, 66%, 54%) !default; 36 | $highlight-color: hsl(43, 100%, 85%) !default; 37 | $body-bg: $bg-color-light !default; 38 | $body-font-color: lighten($dark-color, 5%) !default; 39 | $link-color: hsl(215, 65%, 36%) !default; 40 | $link-color-dark: darken($link-color, 10%) !default; 41 | $link-color-light: lighten($link-color, 10%) !default; 42 | 43 | // Fonts 44 | // Credit: https://www.smashingmagazine.com/2015/11/using-system-ui-fonts-practical-guide/ 45 | $base-font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto !default; 46 | $mono-font-family: "SF Mono", "Segoe UI Mono", "Roboto Mono", Menlo, Courier, monospace !default; 47 | $fallback-font-family: "Helvetica Neue", sans-serif !default; 48 | $cjk-zh-hans-font-family: $base-font-family, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", $fallback-font-family !default; 49 | $cjk-zh-hant-font-family: $base-font-family, "PingFang TC", "Hiragino Sans CNS", "Microsoft JhengHei", $fallback-font-family !default; 50 | $cjk-jp-font-family: $base-font-family, "Hiragino Sans", "Hiragino Kaku Gothic Pro", "Yu Gothic", YuGothic, Meiryo, $fallback-font-family !default; 51 | $cjk-ko-font-family: $base-font-family, "Malgun Gothic", $fallback-font-family !default; 52 | $body-font-family: $base-font-family, $fallback-font-family !default; 53 | 54 | // Unit sizes 55 | $unit-o: .05rem !default; 56 | $unit-h: .1rem !default; 57 | $unit-1: .2rem !default; 58 | $unit-2: .4rem !default; 59 | $unit-3: .6rem !default; 60 | $unit-4: .8rem !default; 61 | $unit-5: 1rem !default; 62 | $unit-6: 1.2rem !default; 63 | $unit-7: 1.4rem !default; 64 | $unit-8: 1.6rem !default; 65 | $unit-9: 1.8rem !default; 66 | $unit-10: 2rem !default; 67 | $unit-12: 2.4rem !default; 68 | $unit-16: 3.2rem !default; 69 | 70 | // Font sizes 71 | $html-font-size: 20px !default; 72 | $html-line-height: 1.5 !default; 73 | $font-size: .8rem !default; 74 | $font-size-sm: .7rem !default; 75 | $font-size-lg: .9rem !default; 76 | $line-height: 1.2rem !default; 77 | 78 | // Sizes 79 | $layout-spacing: $unit-2 !default; 80 | $layout-spacing-sm: $unit-1 !default; 81 | $layout-spacing-lg: $unit-4 !default; 82 | $border-radius: $unit-1 !default; 83 | $border-width: $unit-o !default; 84 | $border-width-lg: $unit-h !default; 85 | $control-size: $unit-9 !default; 86 | $control-size-sm: $unit-7 !default; 87 | $control-size-lg: $unit-10 !default; 88 | $control-padding-x: $unit-2 !default; 89 | $control-padding-x-sm: $unit-2 * .75 !default; 90 | $control-padding-x-lg: $unit-2 * 1.5 !default; 91 | $control-padding-y: ($control-size - $line-height) / 2 - $border-width !default; 92 | $control-padding-y-sm: ($control-size-sm - $line-height) / 2 - $border-width !default; 93 | $control-padding-y-lg: ($control-size-lg - $line-height) / 2 - $border-width !default; 94 | $control-icon-size: .8rem !default; 95 | 96 | $control-width-xs: 180px !default; 97 | $control-width-sm: 320px !default; 98 | $control-width-md: 640px !default; 99 | $control-width-lg: 960px !default; 100 | $control-width-xl: 1280px !default; 101 | 102 | // Responsive breakpoints 103 | $size-xs: 480px !default; 104 | $size-sm: 600px !default; 105 | $size-md: 840px !default; 106 | $size-lg: 960px !default; 107 | $size-xl: 1280px !default; 108 | $size-2x: 1440px !default; 109 | 110 | $responsive-breakpoint: $size-xs !default; 111 | 112 | // Z-index 113 | $zindex-0: 1 !default; 114 | $zindex-1: 100 !default; 115 | $zindex-2: 200 !default; 116 | $zindex-3: 300 !default; 117 | $zindex-4: 400 !default; 118 | -------------------------------------------------------------------------------- /assets/scss/addr/_infocards.scss: -------------------------------------------------------------------------------- 1 | .info-card { 2 | flex-grow: 1; 3 | flex-basis: 0; 4 | margin: 3px; 5 | padding: 4px; 6 | text-align: center; 7 | border-radius: $border-radius; 8 | color: white; 9 | box-shadow: 1px 1px 2px #33333377; 10 | &.blue { 11 | background: linear-gradient(to bottom right, hsl(210, 70%, 64%), hsl(210, 50%, 44%)); 12 | } 13 | &.orange { 14 | background: linear-gradient(to bottom right, hsl(015, 70%, 64%), hsl(015, 50%, 44%)); 15 | } 16 | &.green { 17 | background: linear-gradient(to bottom right, hsl(135, 70%, 64%), hsl(135, 50%, 44%)); 18 | } 19 | 20 | .focus { 21 | &.number { 22 | font-size: 34px; 23 | font-weight: bold; 24 | } 25 | } 26 | 27 | .subject { 28 | font-weight: 600; 29 | } 30 | } 31 | 32 | .info-status { 33 | margin: 3px; 34 | padding: 5px; 35 | border-radius: $border-radius; 36 | box-shadow: 1px 1px 2px #33333377; 37 | background: linear-gradient(to bottom right, hsl(208, 100%, 97%), hsl(0, 0%, 88%)); 38 | 39 | .company { 40 | font-size: larger; 41 | font-weight: bold; 42 | color: #444; 43 | } 44 | div { 45 | margin: 1px; 46 | } 47 | strong { 48 | font-weight: 600; 49 | } 50 | 51 | // [:div.status-percent 52 | // [:span.title "Yoğunluk"] 53 | // [:div.percent-bg 54 | .status-percent { 55 | margin: 3px; 56 | .title { 57 | font-size: 12px; 58 | font-weight: 600; 59 | } 60 | .percent-bg { 61 | margin: -3px 0 0 0; 62 | } 63 | } 64 | 65 | .delivery-card { 66 | background-color: #fff; 67 | border-radius: $border-radius; 68 | margin: 10px 0 0 0; 69 | padding: 3px; 70 | .color { 71 | margin: 6px 2px 6px 6px; 72 | width: 20px; 73 | height: 20px; 74 | border-radius: 30%; 75 | } 76 | .name { 77 | flex-grow: 1; 78 | margin: 4px; 79 | font-weight: 600; 80 | } 81 | .car, 82 | .pos { 83 | flex-basis: 0; 84 | flex-grow: 1; 85 | font-size: small; 86 | padding: 2px; 87 | background-color: #eee; 88 | border-radius: 8px; 89 | i { 90 | margin: 0 8px; 91 | font-size: smaller; 92 | } 93 | } 94 | 95 | .status { 96 | color: white; 97 | border-radius: 8px; 98 | height: 16px; 99 | font-size: 11px; 100 | letter-spacing: 0.05em; 101 | font-weight: 600; 102 | margin: 8px; 103 | padding: 0px 4px; 104 | &.on { 105 | background-color: rgb(49, 189, 44); 106 | } 107 | &.pause { 108 | background-color: rgb(38, 121, 216); 109 | } 110 | &.off { 111 | background-color: rgb(212, 81, 37); 112 | } 113 | } 114 | 115 | &.off { 116 | background-color: #eee; 117 | .color { 118 | background-color: rgb(161, 161, 161); 119 | } 120 | transform: scale(0.7); 121 | margin: -2px 0 -10px; 122 | color: #666; 123 | } 124 | } 125 | } 126 | 127 | /* -------------------------------------------------------------------------- */ 128 | /* INVENTORY */ 129 | /* -------------------------------------------------------------------------- */ 130 | 131 | .inventory-card { 132 | background-color: #fff; 133 | border-radius: $border-radius; 134 | width: 100%; 135 | padding:4px; 136 | 137 | div {overflow: hidden; 138 | max-height: 1.8rem;} 139 | 140 | .color { 141 | margin: 6px 2px 6px 6px; 142 | width: 20px; 143 | height: 20px; 144 | border-radius: 30%; 145 | } 146 | .name { 147 | flex-grow: 1; 148 | margin: 4px; 149 | font-weight: 600; 150 | } 151 | .key { 152 | margin: 6px 6px 6px 6px; 153 | border-radius: 8px; 154 | padding: 0 4px; 155 | background-color: #eee; 156 | } 157 | 158 | .brand, 159 | .price { 160 | flex-basis: 0; 161 | flex-grow: 1; 162 | margin: 0 3px; 163 | text-align: center; 164 | font-weight: 400; 165 | padding: 2px; 166 | background-color: #eee; 167 | border-radius: 8px; 168 | i { 169 | margin: 0 8px; 170 | font-size: smaller; 171 | } 172 | } 173 | 174 | .status { 175 | color: white; 176 | border-radius: 8px; 177 | height: 16px; 178 | font-size: 11px; 179 | letter-spacing: 0.05em; 180 | font-weight: 600; 181 | margin: 8px; 182 | padding: 0px 4px; 183 | &.on { 184 | background-color: rgb(49, 189, 44); 185 | } 186 | &.pause { 187 | background-color: rgb(38, 121, 216); 188 | } 189 | &.off { 190 | background-color: rgb(212, 81, 37); 191 | } 192 | } 193 | 194 | &.off { 195 | background-color: #eee; 196 | .color { 197 | background-color: rgb(161, 161, 161); 198 | } 199 | transform: scale(0.7); 200 | margin: -2px 0 -10px; 201 | color: #666; 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /assets/scss/addr/core.scss: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------- */ 2 | /* PAGE */ 3 | /* -------------------------------------------------------------------------- */ 4 | 5 | html, 6 | body, 7 | #app { 8 | height: 100%; 9 | font-family: Optima, "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; 10 | } 11 | .app-container { 12 | margin-bottom: $unit-12; 13 | min-height: calc(100% - 2.4rem); 14 | background-color: #ffffff; 15 | //background-image: url("data:image/svg+xml,%3Csvg width='100' height='20' viewBox='0 0 100 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.184 20c.357-.13.72-.264 1.088-.402l1.768-.661C33.64 15.347 39.647 14 50 14c10.271 0 15.362 1.222 24.629 4.928.955.383 1.869.74 2.75 1.072h6.225c-2.51-.73-5.139-1.691-8.233-2.928C65.888 13.278 60.562 12 50 12c-10.626 0-16.855 1.397-26.66 5.063l-1.767.662c-2.475.923-4.66 1.674-6.724 2.275h6.335zm0-20C13.258 2.892 8.077 4 0 4V2c5.744 0 9.951-.574 14.85-2h6.334zM77.38 0C85.239 2.966 90.502 4 100 4V2c-6.842 0-11.386-.542-16.396-2h-6.225zM0 14c8.44 0 13.718-1.21 22.272-4.402l1.768-.661C33.64 5.347 39.647 4 50 4c10.271 0 15.362 1.222 24.629 4.928C84.112 12.722 89.438 14 100 14v-2c-10.271 0-15.362-1.222-24.629-4.928C65.888 3.278 60.562 2 50 2 39.374 2 33.145 3.397 23.34 7.063l-1.767.662C13.223 10.84 8.163 12 0 12v2z' fill='%23191e58' fill-opacity='0.12' fill-rule='evenodd'/%3E%3C/svg%3E"); 16 | } 17 | 18 | /* --------------------------------- COLORS --------------------------------- */ 19 | // Core colors 20 | $m-color: hsl(210, 29%, 24%) !default; 21 | $m-color-dark: darken($m-color, 3%) !default; 22 | $m-color-darker: darken($m-color, 5%) !default; 23 | $m-color-light: lighten($m-color, 3%) !default; 24 | $m-color-lighter: lighten($m-color, 5%) !default; 25 | 26 | $n-color: lighten($m-color, 37.5%) !default; 27 | $n-color-dark: darken($n-color, 3%) !default; 28 | $n-color-light: lighten($n-color, 3%) !default; 29 | 30 | // Other colors 31 | $ms-link-color: hsl(168.3, 75%, 35%) !default; 32 | $ms-text-color: hsl(210, 6%, 84%) !default; 33 | $ms-text-color-dark: hsl(210, 6%, 50%) !default; 34 | $ms-text-color-darker: hsl(210, 6%, 30%) !default; 35 | $visible-light: hsl(210, 3%, 87%); 36 | 37 | // BC colors 38 | .bc0, .bc00 {background: hsl(210, 03%, 87%)} 39 | .bc1, .bc01 {background: hsl(000, 70%, 64%)} 40 | .bc2, .bc02 {background: hsl(015, 70%, 64%)} 41 | .bc3, .bc03 {background: hsl(030, 70%, 64%)} 42 | .bc4, .bc04 {background: hsl(045, 70%, 64%)} 43 | .bc5, .bc05 {background: hsl(060, 70%, 64%)} 44 | .bc6, .bc06 {background: hsl(075, 70%, 64%)} 45 | .bc7, .bc07 {background: hsl(090, 70%, 64%)} 46 | .bc8, .bc08 {background: hsl(105, 70%, 64%)} 47 | .bc9, .bc09 {background: hsl(120, 70%, 64%)} 48 | .bc10 {background: hsl(135, 70%, 64%)} 49 | .bc11 {background: hsl(150, 70%, 64%)} 50 | .bc12 {background: hsl(165, 70%, 64%)} 51 | .bc13 {background: hsl(180, 70%, 64%)} 52 | .bc14 {background: hsl(195, 70%, 64%)} 53 | .bc15 {background: hsl(210, 70%, 64%)} 54 | .bc16 {background: hsl(225, 72%, 70%)} 55 | .bc17 {background: hsl(240, 74%, 74%)} 56 | .bc18 {background: hsl(255, 72%, 70%)} 57 | .bc19 {background: hsl(270, 70%, 67%)} 58 | .bc20 {background: hsl(285, 70%, 64%)} 59 | .bc21 {background: hsl(300, 70%, 64%)} 60 | .bc22 {background: hsl(315, 70%, 64%)} 61 | .bc23 {background: hsl(330, 70%, 64%)} 62 | .bc24 {background: hsl(345, 70%, 64%)} 63 | 64 | 65 | // BC colors 66 | .bcd0, .bcd00 {background: hsl(210, 03%, 37%)} 67 | .bcd1, .bcd01 {background: hsl(000, 50%, 44%)} 68 | .bcd2, .bcd02 {background: hsl(015, 50%, 44%)} 69 | .bcd3, .bcd03 {background: hsl(030, 25%, 44%)} 70 | .bcd4, .bcd04 {background: hsl(045, 50%, 36%)} 71 | .bcd5, .bcd05 {background: hsl(060, 35%, 44%)} 72 | .bcd6, .bcd06 {background: hsl(075, 50%, 44%)} 73 | .bcd7, .bcd07 {background: hsl(090, 40%, 44%)} 74 | .bcd8, .bcd08 {background: hsl(105, 50%, 44%)} 75 | .bcd9, .bcd09 {background: hsl(120, 50%, 44%)} 76 | .bcd10 {background: hsl(135, 50%, 44%)} 77 | .bcd11 {background: hsl(150, 50%, 44%)} 78 | .bcd12 {background: hsl(165, 50%, 44%)} 79 | .bcd13 {background: hsl(180, 45%, 44%)} 80 | .bcd14 {background: hsl(195, 50%, 44%)} 81 | .bcd15 {background: hsl(210, 50%, 44%)} 82 | .bcd16 {background: hsl(225, 50%, 44%)} 83 | .bcd17 {background: hsl(240, 50%, 44%)} 84 | .bcd18 {background: hsl(255, 50%, 44%)} 85 | .bcd19 {background: hsl(270, 50%, 44%)} 86 | .bcd20 {background: hsl(285, 50%, 44%)} 87 | .bcd21 {background: hsl(300, 50%, 44%)} 88 | .bcd22 {background: hsl(315, 50%, 44%)} 89 | .bcd23 {background: hsl(330, 50%, 44%)} 90 | .bcd24 {background: hsl(345, 50%, 44%)} 91 | 92 | .fc9 {color: hsl(0, 0%, 100%)} 93 | .fc8 {color: hsl(0, 0%, 90%)} 94 | .fc7 {color: hsl(0, 0%, 80%)} 95 | .fc6 {color: hsl(0, 0%, 70%)} 96 | .fc5 {color: hsl(0, 0%, 60%)} 97 | .fc4 {color: hsl(0, 0%, 48%)} 98 | .fc3 {color: hsl(0, 0%, 36%)} 99 | .fc2 {color: hsl(0, 0%, 24%)} 100 | .fc1 {color: hsl(0, 0%, 12%)} 101 | .fc0 {color: hsl(0, 0%, 02%)} 102 | 103 | .tb {font-weight: 600;} -------------------------------------------------------------------------------- /src/addfocus/subs.cljs: -------------------------------------------------------------------------------- 1 | (ns addfocus.subs 2 | (:require 3 | [re-frame.core :as rf] 4 | [tools.time :as time] 5 | [addfocus.helpers :refer [get-task]])) 6 | 7 | ; ---------------------------------------------------------------------------- ; 8 | ; Task subs ; 9 | ; ---------------------------------------------------------------------------- ; 10 | 11 | (rf/reg-sub 12 | :all-tasks 13 | (fn [db _] 14 | (:tasks db))) 15 | 16 | (rf/reg-sub 17 | :task/iu 18 | :<- [:all-tasks] 19 | (fn [tasks _] 20 | (filter #(and (:important %) (:urgent %)) tasks))) 21 | 22 | (rf/reg-sub 23 | :task/i 24 | :<- [:all-tasks] 25 | (fn [tasks _] 26 | (filter #(and (:important %) (not (:urgent %))) tasks))) 27 | 28 | (rf/reg-sub 29 | :task/u 30 | :<- [:all-tasks] 31 | (fn [tasks _] 32 | (filter #(and (not (:important %)) (:urgent %)) tasks))) 33 | 34 | (rf/reg-sub 35 | :task/trivia 36 | :<- [:all-tasks] 37 | (fn [tasks _] 38 | (filter #(and (not (:important %)) (not (:urgent %))) tasks))) 39 | 40 | ; -------------------------------- Active task ------------------------------- ; 41 | 42 | (rf/reg-sub 43 | :active-task 44 | (fn [db _] 45 | (cond 46 | (> 99 (:id (:active-task db))) 47 | (merge (:active-task db) 48 | {:task (get-task (:id (:active-task db)) [])}) 49 | :else 50 | (merge (:active-task db) 51 | {:task (first (filter 52 | #(= (:id (:active-task db)) 53 | (:id %)) 54 | (:tasks db)))})))) 55 | 56 | ; ---------------------------------------------------------------------------- ; 57 | ; History subs ; 58 | ; ---------------------------------------------------------------------------- ; 59 | 60 | (rf/reg-sub 61 | :all-history 62 | (fn [db _] 63 | (:history db))) 64 | 65 | (defn day-filter [day list] 66 | (filter #(< 67 | (time/midnight day) 68 | (:date %) 69 | (time/next-midnight day)) 70 | list)) 71 | 72 | (defn hour-filter [day hour list] 73 | (filter #(< 74 | (+ (time/midnight day) (* hour time/h-ms)) 75 | (:date %) 76 | (+ (time/midnight day) (* (+ 1 hour) time/h-ms))) 77 | list)) 78 | 79 | (defn sum-work-minutes [day hour list] 80 | (let [data (hour-filter day hour list)] 81 | (reduce + (map #(:duration %) data)))) 82 | 83 | (rf/reg-sub 84 | :history-data 85 | :<- [:all-history] 86 | (fn [history _] 87 | (into {} 88 | (for [ago (reverse (range -7 1))] 89 | (let [day (+ (time/now) (* ago time/d-ms)) 90 | day-data (day-filter day @(rf/subscribe [:all-history])) 91 | d (time/unix->datemap day)] 92 | [ago 93 | (into {} (for [hour (range 24)] 94 | [hour 95 | (sum-work-minutes day hour day-data)]))]))))) 96 | 97 | (rf/reg-sub 98 | :bonus-data 99 | :<- [:history-data] 100 | (fn [history-data _] 101 | (let [week-minutes (reduce + 102 | (for [x history-data] 103 | (reduce + 104 | (for [y (second x)] (second y))))) 105 | week-multiplier (+ 1 (/ week-minutes 2500)) 106 | hour-fn (fn [h] 107 | (+ 1 (/ 108 | (reduce + 109 | (for [x history-data] 110 | (+ (get (second x) h) 111 | (get (second x) 112 | (if (= h 23) 0 (+ 1 h)))))) 113 | 1000))) 114 | hour-bonus (into {} 115 | (for [h (range 24)] 116 | [h (* (hour-fn h) week-multiplier) 2]))] 117 | {:week-minutes week-minutes 118 | :hour-bonus hour-bonus}))) 119 | 120 | (rf/reg-sub 121 | :history-chart-data 122 | :<- [:history-data] 123 | (fn [history _] 124 | (into [] 125 | (for [ago (reverse (range -7 1))] 126 | (let [day (+ (time/now) (* ago time/d-ms)) 127 | day-data (get history ago) 128 | d (time/unix->datemap day)] 129 | {:name (if (= ago 0) 130 | "Today" 131 | (str (:day d) " " (time/short-month-name (:month d)))) 132 | :data (for [hour (range 24)] 133 | {:x (str (time/s-zero hour) :00) 134 | :y (get day-data hour)})}))))) 135 | 136 | (defn abs [n] (max n (- n))) 137 | (defn distance [x y] (abs (- (if (< x y) (- y x) (- x y)) 12))) 138 | (rf/reg-sub 139 | :history-data-random 140 | (fn [_ _] 141 | (into [] 142 | (for 143 | [day (reverse ["Mon" "Tue" "Wed" "Thu" "Fri" "Sat" "Sun"])] 144 | {:name day 145 | :data (into [] 146 | (for [x (range 24)] 147 | {:x (str x) :y (+ (rand-int 24) (* 3 (distance 12 x)))}))})))) 148 | 149 | ;Steps 150 | ;Filter day data 151 | ;Get day name 152 | ;Loop day data -> get hour string, get work duration 153 | -------------------------------------------------------------------------------- /src/tools/time.cljs: -------------------------------------------------------------------------------- 1 | (ns tools.time) 2 | 3 | (defn now [] (.now js/Date)) 4 | (defn obj 5 | ([] (obj (now))) 6 | ([ut] (js/Date. (if (< ut 10000000000) (* 1000 ut) ut)))) 7 | 8 | (defn datemap 9 | ([] (datemap (now))) 10 | ([ut] 11 | (let [date (obj ut)] 12 | {:year (.getFullYear date) 13 | :month (.getMonth date) 14 | :day (.getDate date) 15 | :hour (.getHours date) 16 | :minute (.getMinutes date) 17 | :second (.getSeconds date) 18 | :weekday (.getDay date)}))) 19 | 20 | (defn unix->datemap [ut] (datemap ut)) 21 | (defn datemap->unix [dm] 22 | ;new Date (year, month, day, hours, minutes, seconds, milliseconds); 23 | (.parse js/Date 24 | (js/Date. (:year dm) 25 | (:month dm) 26 | (:day dm) 27 | (:hour dm) 28 | (:minute dm) 29 | (:second dm))) 30 | ) 31 | 32 | (def s-ms 1000) 33 | (def m-ms 60000) 34 | (def h-ms 3600000) 35 | (def d-ms 86400000) 36 | (defn round [x] (.round js/Math x)) 37 | 38 | 39 | (defn midnight 40 | ([] (midnight (now))) 41 | ([unixtime] (- (doto (js/Date. unixtime) (.setHours 0 0 0 1)) 1))) 42 | 43 | (defn next-midnight 44 | ([] (+ (midnight) d-ms)) 45 | ([unixtime] (+ (midnight unixtime) d-ms)) 46 | ) 47 | 48 | (defn sec-of-day 49 | ([] (sec-of-day (now))) 50 | ([unixtime] 51 | (round (/ (- unixtime (midnight unixtime)) s-ms)))) 52 | 53 | (defn min-of-day 54 | ([] (min-of-day (now))) 55 | ([unixtime] 56 | (round (/ (- unixtime (midnight unixtime)) m-ms)))) 57 | 58 | ;Leftpads 0 to hours lower than 10 59 | (defn s-zero [a] (if (> 10 a) (str 0 a) (str a))) 60 | (defn unix->time 61 | "Returns hours and minutes as string" 62 | [unixtime] 63 | (let [date (js/Date. unixtime)] 64 | (str (s-zero (.getHours date)) ":" (s-zero (.getMinutes date))))) 65 | 66 | (defn todaytime->unix [hour minute] 67 | (+ (midnight) (* hour 3600000) (* minute 60000))) 68 | 69 | (defn diff 70 | ([a b] (diff a b m-ms)) 71 | ([a b unit] (round (/ (- b a) unit)))) 72 | 73 | 74 | (defn days-in-month [year month] 75 | (let [date (js/Date. year month 0)] 76 | (.getDate date))) 77 | 78 | (defn weekday 79 | ([year month day] 80 | (let [date (js/Date. year month day)] 81 | (.getDay date))) 82 | ([unixtime] 83 | (let [date (js/Date. unixtime)] 84 | (.getDay date)))) 85 | 86 | ;we will mark holidays in the future 87 | ;(defn is-holiday [year month day]) 88 | 89 | (defn make-calendar [year month] 90 | (let [days (days-in-month year month) 91 | prev-end (days-in-month year (- month 1)) 92 | first-day (weekday year (- month 1) 1)] 93 | (take 35 94 | (concat 95 | (reverse 96 | (for [d (range (- first-day 1))] 97 | {:day (- prev-end d) 98 | :weekday (mod (- first-day d 1) 7) 99 | :month "prev"})) 100 | (drop 1 101 | (for [d (range (+ days 1))] 102 | {:day d, 103 | :weekday (mod (+ (- d 1) first-day) 7) 104 | :month "this"})) 105 | (drop 1 106 | (for [d (range 7)] 107 | {:day d 108 | :weekday (mod (+ (- d 1) days first-day) 7) 109 | :month "next"})))))) 110 | 111 | (defn month-name [month] 112 | (case month 113 | 0 "Ocak" 114 | 1 "Şubat" 115 | 2 "Mart" 116 | 3 "Nisan" 117 | 4 "Mayıs" 118 | 5 "Haziran" 119 | 6 "Temmuz" 120 | 7 "Ağustos" 121 | 8 "Eylül" 122 | 9 "Ekim" 123 | 10 "Kasım" 124 | 11 "Aralık")) 125 | 126 | (defn short-month-name [month] 127 | (case month 128 | 0 "Jan" 129 | 1 "Feb" 130 | 2 "Mar" 131 | 3 "Apr" 132 | 4 "May" 133 | 5 "Jun" 134 | 6 "Jul" 135 | 7 "Agu" 136 | 8 "Sep" 137 | 9 "Oct" 138 | 10 "Nov" 139 | 11 "Dec")) 140 | 141 | (defn weekday-name [weekday] 142 | (case weekday 143 | 0 "Mon" 144 | 1 "Tue" 145 | 2 "Wed" 146 | 3 "Thu" 147 | 4 "Fri" 148 | 5 "Sat" 149 | 6 "Sun")) 150 | 151 | (defn nicedate [unixtime type] 152 | (if (number? unixtime) 153 | (let [d (unix->datemap unixtime)] 154 | (case type 155 | :short-date (str (:day d) "/" 156 | (:month d) "/" 157 | (:year d)) 158 | :fixed-short-date (str (s-zero (:day d)) "/" 159 | (s-zero (:month d)) "/" 160 | (:year d)) 161 | :named-date (str (:day d) " " 162 | (month-name (:month d)) " " 163 | (:year d)) 164 | :date-time (str (s-zero (:day d)) "/" 165 | (s-zero (:month d)) "/" 166 | (:year d) " - " 167 | (s-zero (:hour d)) ":" 168 | (s-zero (:minute d))) 169 | :fixed-named-date (str (s-zero (:day d)) " " 170 | (short-month-name (:month d)) " " 171 | (:year d)) 172 | :fixed-hiccup [:span.date [:span.d (s-zero (:day d))] 173 | [:span.m (short-month-name (:month d))] 174 | [:span.y (:year d)]])))) -------------------------------------------------------------------------------- /assets/scss/addr/_realledger.scss: -------------------------------------------------------------------------------- 1 | 2 | /* -------------------------------------------------------------------------- */ 3 | /* LEDGER TABLE */ 4 | /* -------------------------------------------------------------------------- */ 5 | 6 | .ledger { 7 | > div { 8 | border-radius: $border-radius; 9 | border-top: #e2e2e2 2px solid; 10 | border-bottom: #e6e6e6 1px solid; 11 | padding: 10px; 12 | font-family: "Roboto Mono", monospace; 13 | &.summary { 14 | padding: 0 10px; 15 | position: relative; 16 | font-size: 0.9em; 17 | 18 | .sum-info { 19 | position: absolute; 20 | left: 50%; 21 | top: -8px; 22 | padding: 1px 4px; 23 | font-size: small; 24 | background-color: #e2e2e2; 25 | border-radius: $border-radius; 26 | } 27 | } 28 | 29 | .info-tag { 30 | background-color: #e2e2e2; 31 | border-radius: 0 2em 2em 0; 32 | padding: 4px 4px 4px 8px; 33 | font-size: 12px; 34 | position: absolute; 35 | margin: -13px 0 0 -22px; 36 | text-align: center; 37 | 38 | .id { 39 | min-width: 30px; 40 | display: inline-block; 41 | font-weight: bold; 42 | } 43 | 44 | .date { 45 | margin-left: 14px; 46 | background-color: #595685; 47 | border-radius: 1em; 48 | padding: 2px; 49 | color: white; 50 | width: 124px; 51 | display: inline-block; 52 | } 53 | } 54 | 55 | .header { 56 | min-height: 50px; 57 | } 58 | 59 | .footer { 60 | min-height: 50px; 61 | 62 | .note { 63 | padding: 4px 8px; 64 | border-left: 3px solid #e6e6e6; 65 | border-radius: 4px; 66 | margin: 6px; 67 | font-style: italic; 68 | background-color: rgba(255, 255, 255, 0.479); 69 | display: block; 70 | font-family: cursive; 71 | } 72 | } 73 | } 74 | } 75 | 76 | .ledger, 77 | .ledger-form { 78 | .lborder { 79 | border-left: #e6e6e6 2px solid; 80 | } 81 | 82 | .lines { 83 | border: #e6e6e6 1px solid; 84 | margin-top: -1px; 85 | border-radius: $border-radius; 86 | font-weight: 500; 87 | 88 | div { 89 | padding: 3px 5px 3px 0; 90 | } 91 | 92 | &.mark { 93 | color: rgb(140, 0, 255); 94 | } 95 | 96 | &:hover { 97 | background-color: #33333325; 98 | } 99 | 100 | .hover-switch { 101 | min-height: 44px; 102 | } 103 | } 104 | 105 | .line-group { 106 | position: relative; 107 | 108 | .col-6 {padding-top:8px;} 109 | 110 | .amount-btns { 111 | position: absolute; 112 | width:10px; 113 | left:-12px; 114 | margin-top: -52px; 115 | 116 | 117 | &.credit { 118 | left: calc(16.66666667% - 16px); 119 | } 120 | 121 | button { 122 | border-radius: $border-radius; 123 | background-color: hsl(0, 0%, 95%); 124 | border: #e6e6e6 solid 1px; 125 | font-weight: 500; 126 | border-top: none; 127 | overflow: hidden; 128 | padding: 0px 4px; 129 | margin: 1px 0 0 0; 130 | width: 20px; 131 | } 132 | } 133 | 134 | .not-equal{ 135 | position: absolute; 136 | left: calc(83.33333333% - 18px); 137 | color: white; 138 | background-color: rgb(170, 23, 23); 139 | line-height: 20px; 140 | font-size: 22px; 141 | width: 24px; 142 | height: 24px; 143 | border-radius: 12px; 144 | text-align: center; 145 | padding: 0; 146 | margin-top: -12px; 147 | font-weight: bold; 148 | z-index: 4; 149 | box-shadow: 0 0 6px 2px #333333AA; 150 | } 151 | } 152 | 153 | .acc-id { 154 | padding: 4px 8px; 155 | margin: 4px; 156 | border-radius: $border-radius; 157 | background-color: rgba(228, 230, 213, 0.726); 158 | font-family: "Roboto Mono", monospace; 159 | } 160 | 161 | .input { 162 | margin: 1px 2px; 163 | } 164 | 165 | .auto-show { 166 | height: 100%; 167 | width: 100%; 168 | margin-left: 6px; 169 | } 170 | .hover-switch { 171 | position: relative; 172 | } 173 | 174 | //TODO: Remove this. (Duplicate) 175 | .auto-show:focus { 176 | display: block; 177 | 178 | ~ .picker { 179 | display: block !important; 180 | } 181 | 182 | ~ .auto-hide { 183 | display: none; 184 | } 185 | } 186 | 187 | //TODO: Remove this. (Duplicate) 188 | .picker { 189 | position: absolute; 190 | border-radius: $border-radius; 191 | left: 0px; 192 | top: 95%; 193 | margin: 0 6px; 194 | width: calc(100% - 6px); 195 | background-color: white; 196 | z-index: 8; 197 | display: none; 198 | max-height: 200px; 199 | overflow: auto; 200 | 201 | &:hover { 202 | display: block; 203 | } 204 | 205 | .item { 206 | padding: 3px; 207 | margin: 3px; 208 | border-radius: 2px; 209 | cursor: pointer; 210 | 211 | &:nth-of-type(odd) { 212 | background: #ececec; 213 | } 214 | 215 | &:hover { 216 | background-color: bisque; 217 | } 218 | } 219 | } 220 | } 221 | 222 | .ledger > div:nth-of-type(odd) { 223 | background: #f0f5ef; 224 | } 225 | 226 | .ledger > div:nth-of-type(even) { 227 | background: #faf9f6; 228 | } 229 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_calendars.scss: -------------------------------------------------------------------------------- 1 | // Calendars 2 | .calendar { 3 | border: $border-width solid $border-color; 4 | border-radius: $border-radius; 5 | display: block; 6 | min-width: 280px; 7 | 8 | .calendar-nav { 9 | align-items: center; 10 | background: $bg-color; 11 | border-top-left-radius: $border-radius; 12 | border-top-right-radius: $border-radius; 13 | display: flex; 14 | font-size: $font-size-lg; 15 | padding: $layout-spacing; 16 | } 17 | 18 | .calendar-header, 19 | .calendar-body { 20 | display: flex; 21 | flex-wrap: wrap; 22 | justify-content: center; 23 | padding: $layout-spacing 0; 24 | 25 | .calendar-date { 26 | flex: 0 0 14.28%; // 7 calendar-items each row 27 | max-width: 14.28%; 28 | } 29 | } 30 | 31 | .calendar-header { 32 | background: $bg-color; 33 | border-bottom: $border-width solid $border-color; 34 | color: $gray-color; 35 | font-size: $font-size-sm; 36 | text-align: center; 37 | } 38 | 39 | .calendar-body { 40 | color: $gray-color-dark; 41 | } 42 | 43 | .calendar-date { 44 | border: 0; 45 | padding: $unit-1; 46 | 47 | .date-item { 48 | appearance: none; 49 | background: transparent; 50 | border: $border-width solid transparent; 51 | border-radius: 50%; 52 | color: $gray-color-dark; 53 | cursor: pointer; 54 | font-size: $font-size-sm; 55 | height: $unit-7; 56 | line-height: $unit-5; 57 | outline: none; 58 | padding: $unit-h; 59 | position: relative; 60 | text-align: center; 61 | text-decoration: none; 62 | transition: background .2s, border .2s, box-shadow .2s, color .2s; 63 | vertical-align: middle; 64 | white-space: nowrap; 65 | width: $unit-7; 66 | 67 | &.date-today { 68 | border-color: $secondary-color-dark; 69 | color: $primary-color; 70 | } 71 | 72 | &:focus { 73 | @include control-shadow(); 74 | } 75 | 76 | &:focus, 77 | &:hover { 78 | background: $secondary-color-light; 79 | border-color: $secondary-color-dark; 80 | color: $primary-color; 81 | text-decoration: none; 82 | } 83 | &:active, 84 | &.active { 85 | background: $primary-color-dark; 86 | border-color: darken($primary-color-dark, 5%); 87 | color: $light-color; 88 | } 89 | 90 | // Calendar badge support 91 | &.badge { 92 | &::after { 93 | position: absolute; 94 | top: 3px; 95 | right: 3px; 96 | transform: translate(50%, -50%); 97 | } 98 | } 99 | } 100 | 101 | .date-item, 102 | .calendar-event { 103 | &:disabled, 104 | &.disabled { 105 | cursor: default; 106 | opacity: .25; 107 | pointer-events: none; 108 | } 109 | } 110 | 111 | &.prev-month, 112 | &.next-month { 113 | .date-item, 114 | .calendar-event { 115 | opacity: .25; 116 | } 117 | } 118 | } 119 | 120 | .calendar-range { 121 | position: relative; 122 | 123 | &::before { 124 | background: $secondary-color; 125 | content: ""; 126 | height: $unit-7; 127 | left: 0; 128 | position: absolute; 129 | right: 0; 130 | top: 50%; 131 | transform: translateY(-50%); 132 | } 133 | &.range-start { 134 | &::before { 135 | left: 50%; 136 | } 137 | } 138 | &.range-end { 139 | &::before { 140 | right: 50%; 141 | } 142 | } 143 | 144 | &.range-start, 145 | &.range-end { 146 | .date-item { 147 | background: $primary-color-dark; 148 | border-color: darken($primary-color-dark, 5%); 149 | color: $light-color; 150 | } 151 | } 152 | 153 | .date-item { 154 | color: $primary-color; 155 | } 156 | } 157 | 158 | // Calendars size 159 | &.calendar-lg { 160 | .calendar-body { 161 | padding: 0; 162 | 163 | .calendar-date { 164 | border-bottom: $border-width solid $border-color; 165 | border-right: $border-width solid $border-color; 166 | display: flex; 167 | flex-direction: column; 168 | height: 5.5rem; 169 | padding: 0; 170 | 171 | &:nth-child(7n) { 172 | border-right: 0; 173 | } 174 | &:nth-last-child(-n+7) { 175 | border-bottom: 0; 176 | } 177 | } 178 | } 179 | 180 | .date-item { 181 | align-self: flex-end; 182 | height: $unit-7; 183 | margin-right: $layout-spacing-sm; 184 | margin-top: $layout-spacing-sm; 185 | } 186 | 187 | .calendar-range { 188 | &::before { 189 | top: 19px; 190 | } 191 | &.range-start { 192 | &::before { 193 | left: auto; 194 | width: 19px; 195 | } 196 | } 197 | &.range-end { 198 | &::before { 199 | right: 19px; 200 | } 201 | } 202 | } 203 | 204 | .calendar-events { 205 | flex-grow: 1; 206 | line-height: 1; 207 | overflow-y: auto; 208 | padding: $layout-spacing-sm; 209 | } 210 | 211 | .calendar-event { 212 | border-radius: $border-radius; 213 | font-size: $font-size-sm; 214 | display: block; 215 | margin: $unit-h auto; 216 | overflow: hidden; 217 | padding: 3px 4px; 218 | text-overflow: ellipsis; 219 | white-space: nowrap; 220 | } 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /assets/scss/addr/spectre/icons/_icons-action.scss: -------------------------------------------------------------------------------- 1 | // Icon resize 2 | .icon-resize-horiz, 3 | .icon-resize-vert { 4 | &::before, 5 | &::after { 6 | border: $icon-border-width solid currentColor; 7 | border-bottom: 0; 8 | border-right: 0; 9 | height: .45em; 10 | width: .45em; 11 | } 12 | &::before { 13 | transform: translate(-50%, -90%) rotate(45deg); 14 | } 15 | &::after { 16 | transform: translate(-50%, -10%) rotate(225deg); 17 | } 18 | } 19 | 20 | .icon-resize-horiz { 21 | &::before { 22 | transform: translate(-90%, -50%) rotate(-45deg); 23 | } 24 | &::after { 25 | transform: translate(-10%, -50%) rotate(135deg); 26 | } 27 | } 28 | 29 | // Icon more 30 | .icon-more-horiz, 31 | .icon-more-vert { 32 | &::before { 33 | background: currentColor; 34 | box-shadow: -.4em 0, .4em 0; 35 | border-radius: 50%; 36 | height: 3px; 37 | width: 3px; 38 | } 39 | } 40 | 41 | .icon-more-vert { 42 | &::before { 43 | box-shadow: 0 -.4em, 0 .4em; 44 | } 45 | } 46 | 47 | // Icon plus, minus, cross 48 | .icon-plus, 49 | .icon-minus, 50 | .icon-cross { 51 | &::before { 52 | background: currentColor; 53 | height: $icon-border-width; 54 | width: 100%; 55 | } 56 | } 57 | 58 | .icon-plus, 59 | .icon-cross { 60 | &::after { 61 | background: currentColor; 62 | height: 100%; 63 | width: $icon-border-width; 64 | } 65 | } 66 | 67 | .icon-cross { 68 | &::before { 69 | width: 100%; 70 | } 71 | &::after { 72 | height: 100%; 73 | } 74 | &::before, 75 | &::after { 76 | transform: translate(-50%, -50%) rotate(45deg); 77 | } 78 | } 79 | 80 | // Icon check 81 | .icon-check { 82 | &::before { 83 | border: $icon-border-width solid currentColor; 84 | border-right: 0; 85 | border-top: 0; 86 | height: .5em; 87 | width: .9em; 88 | transform: translate(-50%, -75%) rotate(-45deg); 89 | } 90 | } 91 | 92 | // Icon stop 93 | .icon-stop { 94 | border: $icon-border-width solid currentColor; 95 | border-radius: 50%; 96 | &::before { 97 | background: currentColor; 98 | height: $icon-border-width; 99 | transform: translate(-50%, -50%) rotate(45deg); 100 | width: 1em; 101 | } 102 | } 103 | 104 | // Icon shutdown 105 | .icon-shutdown { 106 | border: $icon-border-width solid currentColor; 107 | border-radius: 50%; 108 | border-top-color: transparent; 109 | &::before { 110 | background: currentColor; 111 | content: ""; 112 | height: .5em; 113 | top: .1em; 114 | width: $icon-border-width; 115 | } 116 | } 117 | 118 | // Icon refresh 119 | .icon-refresh { 120 | &::before { 121 | border: $icon-border-width solid currentColor; 122 | border-radius: 50%; 123 | border-right-color: transparent; 124 | height: 1em; 125 | width: 1em; 126 | } 127 | &::after { 128 | border: .2em solid currentColor; 129 | border-top-color: transparent; 130 | border-left-color: transparent; 131 | height: 0; 132 | left: 80%; 133 | top: 20%; 134 | width: 0; 135 | } 136 | } 137 | 138 | // Icon search 139 | .icon-search { 140 | &::before { 141 | border: $icon-border-width solid currentColor; 142 | border-radius: 50%; 143 | height: .75em; 144 | left: 5%; 145 | top: 5%; 146 | transform: translate(0, 0) rotate(45deg); 147 | width: .75em; 148 | } 149 | &::after { 150 | background: currentColor; 151 | height: $icon-border-width; 152 | left: 80%; 153 | top: 80%; 154 | transform: translate(-50%, -50%) rotate(45deg); 155 | width: .4em; 156 | } 157 | } 158 | 159 | // Icon edit 160 | .icon-edit { 161 | &::before { 162 | border: $icon-border-width solid currentColor; 163 | height: .4em; 164 | transform: translate(-40%, -60%) rotate(-45deg); 165 | width: .85em; 166 | } 167 | &::after { 168 | border: .15em solid currentColor; 169 | border-top-color: transparent; 170 | border-right-color: transparent; 171 | height: 0; 172 | left: 5%; 173 | top: 95%; 174 | transform: translate(0, -100%); 175 | width: 0; 176 | } 177 | } 178 | 179 | // Icon delete 180 | .icon-delete { 181 | &::before { 182 | border: $icon-border-width solid currentColor; 183 | border-bottom-left-radius: $border-radius; 184 | border-bottom-right-radius: $border-radius; 185 | border-top: 0; 186 | height: .75em; 187 | top: 60%; 188 | width: .75em; 189 | } 190 | &::after { 191 | background: currentColor; 192 | box-shadow: -.25em .2em, .25em .2em; 193 | height: $icon-border-width; 194 | top: $icon-border-width/2; 195 | width: .5em; 196 | } 197 | } 198 | 199 | // Icon share 200 | .icon-share { 201 | border: $icon-border-width solid currentColor; 202 | border-radius: $border-radius; 203 | border-right: 0; 204 | border-top: 0; 205 | &::before { 206 | border: $icon-border-width solid currentColor; 207 | border-left: 0; 208 | border-top: 0; 209 | height: .4em; 210 | left: 100%; 211 | top: .25em; 212 | transform: translate(-125%, -50%) rotate(-45deg); 213 | width: .4em; 214 | } 215 | &::after { 216 | border: $icon-border-width solid currentColor; 217 | border-bottom: 0; 218 | border-right: 0; 219 | border-radius: 75% 0; 220 | height: .5em; 221 | width: .6em; 222 | } 223 | } 224 | 225 | // Icon flag 226 | .icon-flag { 227 | &::before { 228 | background: currentColor; 229 | height: 1em; 230 | left: 15%; 231 | width: $icon-border-width; 232 | } 233 | &::after { 234 | border: $icon-border-width solid currentColor; 235 | border-bottom-right-radius: $border-radius; 236 | border-left: 0; 237 | border-top-right-radius: $border-radius; 238 | height: .65em; 239 | top: 35%; 240 | left: 60%; 241 | width: .8em; 242 | } 243 | } 244 | 245 | // Icon bookmark 246 | .icon-bookmark { 247 | &::before { 248 | border: $icon-border-width solid currentColor; 249 | border-bottom: 0; 250 | border-top-left-radius: $border-radius; 251 | border-top-right-radius: $border-radius; 252 | height: .9em; 253 | width: .8em; 254 | } 255 | &::after { 256 | border: $icon-border-width solid currentColor; 257 | border-bottom: 0; 258 | border-left: 0; 259 | border-radius: $border-radius; 260 | height: .5em; 261 | transform: translate(-50%, 35%) rotate(-45deg) skew(15deg, 15deg); 262 | width: .5em; 263 | } 264 | } 265 | 266 | // Icon download & upload 267 | .icon-download, 268 | .icon-upload { 269 | border-bottom: $icon-border-width solid currentColor; 270 | &::before { 271 | border: $icon-border-width solid currentColor; 272 | border-bottom: 0; 273 | border-right: 0; 274 | height: .5em; 275 | width: .5em; 276 | transform: translate(-50%, -60%) rotate(-135deg); 277 | } 278 | &::after { 279 | background: currentColor; 280 | height: .6em; 281 | top: 40%; 282 | width: $icon-border-width; 283 | } 284 | } 285 | 286 | .icon-upload { 287 | &::before { 288 | transform: translate(-50%, -60%) rotate(45deg); 289 | } 290 | &::after { 291 | top: 50%; 292 | } 293 | } 294 | 295 | // Icon copy 296 | .icon-copy { 297 | &::before { 298 | border: $icon-border-width solid currentColor; 299 | border-radius: $border-radius; 300 | border-right: 0; 301 | border-bottom: 0; 302 | height: .8em; 303 | left: 40%; 304 | top: 35%; 305 | width: .8em; 306 | } 307 | &::after { 308 | border: $icon-border-width solid currentColor; 309 | border-radius: $border-radius; 310 | height: .8em; 311 | left: 60%; 312 | top: 60%; 313 | width: .8em; 314 | } 315 | } -------------------------------------------------------------------------------- /src/addfocus/masterview.cljs: -------------------------------------------------------------------------------- 1 | (ns addfocus.masterview 2 | (:require 3 | [reagent.core :as r] 4 | [re-frame.core :as rf] 5 | [tools.time :as time] 6 | ["apexcharts" :as charts])) 7 | 8 | (defn add-task [] 9 | (r/with-let 10 | [empty-task {:task "" 11 | :time 25 12 | :important false 13 | :urgent false} 14 | task (r/atom empty-task) 15 | saved-task (r/atom {}) 16 | pick-time (fn [x] (swap! task assoc :time x))] 17 | [:div.add-task 18 | [:div.invisible-handle] 19 | [:div.task-form 20 | [:label.form-label "Task"] 21 | [:input.text-input 22 | {:type "text" 23 | :on-change #(swap! task assoc :task (.. % -target -value))}] 24 | [:label.form-label "Duration: " [:strong (:time @task)] " minutes"] 25 | [:div.time-selector 26 | (for [x [1 2 3 5 8 10 15 20 25 30 40 50 60]] 27 | [:label {:key x} 28 | [:input {:on-click #(pick-time x) :type "radio", :name "time"}] 29 | [:span (str x)]])] 30 | [:div.clearfix] 31 | [:div.columns.col-gapless 32 | [:div.column.col-12 33 | [:div.switchers 34 | [:label.switch 35 | [:input.check 36 | {:on-change #(swap! task assoc 37 | :important (not (:important @task))) 38 | :type "checkbox" :name "i"}] 39 | [:span "Important"]] 40 | [:label.switch 41 | [:input.check 42 | {:on-change #(swap! task assoc 43 | :urgent (not (:urgent @task))) 44 | :type "checkbox" :name "u"}] 45 | [:span "Urgent"]]] 46 | [:div.clearfix] 47 | (if (= @saved-task @task) 48 | [:div.saved "Task saved!"] 49 | [:<> 50 | [:button 51 | {:on-click #(do (rf/dispatch [:new-task @task true]) 52 | (reset! saved-task @task))} 53 | "Start now"] 54 | [:button 55 | {:on-click #(do (rf/dispatch [:new-task @task]) 56 | (reset! saved-task @task))} 57 | "Do later"]])]]] 58 | [:div.handle "Add New"]])) 59 | 60 | (defn task-list [{:keys [name sub-to]}] 61 | [:div.task-list 62 | [:h5 name] 63 | [:ul 64 | (for 65 | [x @(rf/subscribe [sub-to])] 66 | [:<> {:key x} 67 | [:li 68 | [:span 69 | {:on-click #(rf/dispatch [:active-task (:id x)])} 70 | (:task x)] 71 | [:i.fa.fa-edit] 72 | [:i.fa.fa-trash-o 73 | {:on-click #(rf/dispatch [:delete-task (:id x)])}]]])]]) 74 | 75 | (defn active-task [active] 76 | [:div.active-task 77 | [:div.task-name "- " (:task (:task active))] 78 | [:div.start (time/unix->time (:start-time active))] 79 | [:div.end (time/unix->time (:end-time active))] 80 | [:article 81 | [:div.chart 82 | [:div {:class (str "bar bar-0 lightGray-face " 83 | (if (:break (:task active)) "lime" "cyan"))} 84 | [:div {:class "face top"} 85 | [:div.growing-bar]] 86 | [:div {:class "face side-0"} 87 | [:div.growing-bar]] 88 | [:div {:class "face floor"} 89 | [:div.growing-bar]] 90 | [:div {:class "face side-a"}] 91 | [:div {:class "face side-b"}] 92 | [:div {:class "face side-1"} 93 | [:div.growing-bar]]]]] 94 | [:div.buttons 95 | (case (:state active) 96 | :ready [:i.fa.fa-play-circle-o 97 | {:on-click #(rf/dispatch [:run-active-task])}] 98 | :running (if (not (:break (:task active))) 99 | [:i.fa.fa-pause-circle-o 100 | {:on-click #(rf/dispatch [:pause-active-task])}]) 101 | :paused [:<> 102 | [:i.fa.fa-play-circle-o 103 | {:on-click #(rf/dispatch [:resume-active-task])}] 104 | [:i.fa.fa-times-circle-o 105 | {:on-click #(rf/dispatch [:run-active-task])}]] 106 | :completed [:div.completed 107 | ;[:h6 "Task completed and saved to history."] 108 | [:button {:on-click #(rf/dispatch [:cancel-session])} 109 | " ▶ Start again"] 110 | [:button {:on-click #(rf/dispatch [:cancel-session])} 111 | " ✖ Delete"] 112 | [:hr] 113 | [:h6 "Break timer"] 114 | [:button.break 115 | {:on-click #(rf/dispatch [:break-timer 3])} 116 | "3"] 117 | [:button.break 118 | {:on-click #(rf/dispatch [:break-timer 5])} 119 | "5"] 120 | [:button.break 121 | {:on-click #(rf/dispatch [:break-timer 10])} 122 | "10"] 123 | [:button.break 124 | {:on-click #(rf/dispatch [:break-timer 20])} 125 | "20"]] 126 | :break-completed [:div.completed 127 | [:button.break 128 | {:on-click #(rf/dispatch [:break-timer 5])} 129 | "5"]])]]) 130 | 131 | (defn history [series] 132 | (let [data (clj->js {:chart {:type "heatmap"} 133 | :series series}) 134 | ref-chart (atom nil)] 135 | (r/create-class 136 | {:reagent-render 137 | (fn [] 138 | [:div 139 | [:h6 (:week-minutes @(rf/subscribe [:bonus-data])) " minutes"] 140 | [:div#chart {:ref (fn [e] (reset! ref-chart e))}] 141 | [:p "Hello"]]) 142 | :component-did-mount 143 | (fn [] 144 | (.render 145 | (charts. @ref-chart data)))}))) 146 | 147 | 148 | (defn index [] 149 | (r/with-let 150 | [settings (r/atom false) 151 | modal (r/atom :none) 152 | modal-route (fn [page] 153 | (if (= page @modal) 154 | (reset! modal :none) 155 | (reset! modal page)))] 156 | [:<> 157 | [add-task] 158 | [:ul.down-buttons 159 | [:li 160 | {:on-click #(modal-route :settings)} 161 | [:span.litext "Settings"] 162 | [:i.fa.fa-gears]] 163 | [:li 164 | {:on-click #(modal-route :history)} 165 | [:span.litext "History "] 166 | [:i.fa.fa-history]] 167 | [:li 168 | [:span.litext "Feedback"] 169 | [:i.fa.fa-commenting-o]] 170 | [:li 171 | {:on-click #(rf/dispatch [:save-temp-history])} 172 | [:span.litext "About"] 173 | [:i.fa.fa-info]]] 174 | 175 | [:div#settings.modal 176 | {:class (if (= :settings @modal) "open" "")} 177 | [:div.close-button 178 | {:on-click #(modal-route :none)} 179 | [:i.fa.fa-close]] 180 | [:div.header [:h1 "Settings"]]] 181 | 182 | (case @modal 183 | :history [:div.modal.open 184 | [:div.close-button 185 | {:on-click #(modal-route :none)} 186 | [:i.fa.fa-close]] 187 | [:div.header [:h1 "History"]] 188 | [history @(rf/subscribe [:history-chart-data])]] 189 | :info [:div.modal.open 190 | [:div.close-button 191 | {:on-click #(modal-route :none)} 192 | [:i.fa.fa-close]] 193 | [:div.header [:h1 "Info"]] 194 | [:div "Info will be here"]] 195 | nil) 196 | 197 | [:div.corner.tl 198 | [:div.icon 199 | [:i.fa.fa-list]] 200 | [:div [task-list 201 | {:name "Important & Urgent" 202 | :sub-to :task/iu}]]] 203 | 204 | [:div.corner.tr 205 | [:div.icon 206 | [:i.fa.fa-list]] 207 | [:div [task-list 208 | {:name "Important" 209 | :sub-to :task/i}]]] 210 | 211 | [:div.corner.bl 212 | [:div.icon 213 | [:i.fa.fa-list]] 214 | [:div [task-list 215 | {:name "Urgent" 216 | :sub-to :task/u}]]] 217 | 218 | [:div.corner.br 219 | [:div.icon 220 | [:i.fa.fa-list]] 221 | [:div [task-list 222 | {:name "Trivial" 223 | :sub-to :task/trivia}]]] 224 | 225 | [active-task @(rf/subscribe [:active-task])]])) -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_layout.scss: -------------------------------------------------------------------------------- 1 | // Layout 2 | .container { 3 | margin-left: auto; 4 | margin-right: auto; 5 | padding-left: $layout-spacing; 6 | padding-right: $layout-spacing; 7 | width: 100%; 8 | 9 | $grid-spacing: ($layout-spacing / ($layout-spacing * 0 + 1)) * $html-font-size; 10 | 11 | &.grid-xl { 12 | max-width: $grid-spacing * 2 + $size-xl; 13 | } 14 | 15 | &.grid-lg { 16 | max-width: $grid-spacing * 2 + $size-lg; 17 | } 18 | 19 | &.grid-md { 20 | max-width: $grid-spacing * 2 + $size-md; 21 | } 22 | 23 | &.grid-sm { 24 | max-width: $grid-spacing * 2 + $size-sm; 25 | } 26 | 27 | &.grid-xs { 28 | max-width: $grid-spacing * 2 + $size-xs; 29 | } 30 | } 31 | 32 | // Responsive breakpoint system 33 | .show-xs, 34 | .show-sm, 35 | .show-md, 36 | .show-lg, 37 | .show-xl { 38 | display: none !important; 39 | } 40 | 41 | // Responsive grid system 42 | .columns { 43 | display: flex; 44 | flex-wrap: wrap; 45 | margin-left: -$layout-spacing; 46 | margin-right: -$layout-spacing; 47 | 48 | &.col-gapless { 49 | margin-left: 0; 50 | margin-right: 0; 51 | 52 | & > .column { 53 | padding-left: 0; 54 | padding-right: 0; 55 | } 56 | } 57 | &.col-oneline { 58 | flex-wrap: nowrap; 59 | overflow-x: auto; 60 | } 61 | } 62 | .column { 63 | flex: 1; 64 | max-width: 100%; 65 | padding-left: $layout-spacing; 66 | padding-right: $layout-spacing; 67 | 68 | &.col-12, 69 | &.col-11, 70 | &.col-10, 71 | &.col-9, 72 | &.col-8, 73 | &.col-7, 74 | &.col-6, 75 | &.col-5, 76 | &.col-4, 77 | &.col-3, 78 | &.col-2, 79 | &.col-1, 80 | &.col-auto { 81 | flex: none; 82 | } 83 | } 84 | .col-12 { 85 | width: 100%; 86 | } 87 | .col-11 { 88 | width: 91.66666667%; 89 | } 90 | .col-10 { 91 | width: 83.33333333%; 92 | } 93 | .col-9 { 94 | width: 75%; 95 | } 96 | .col-8 { 97 | width: 66.66666667%; 98 | } 99 | .col-7 { 100 | width: 58.33333333%; 101 | } 102 | .col-6 { 103 | width: 50%; 104 | } 105 | .col-5 { 106 | width: 41.66666667%; 107 | } 108 | .col-4 { 109 | width: 33.33333333%; 110 | } 111 | .col-3 { 112 | width: 25%; 113 | } 114 | .col-2 { 115 | width: 16.66666667%; 116 | } 117 | .col-1 { 118 | width: 8.33333333%; 119 | } 120 | .col-auto { 121 | flex: 0 0 auto; 122 | max-width: none; 123 | width: auto; 124 | } 125 | .col-mx-auto { 126 | margin-left: auto; 127 | margin-right: auto; 128 | } 129 | .col-ml-auto { 130 | margin-left: auto; 131 | } 132 | .col-mr-auto { 133 | margin-right: auto; 134 | } 135 | @media (max-width: $size-xl) { 136 | .col-xl-12, 137 | .col-xl-11, 138 | .col-xl-10, 139 | .col-xl-9, 140 | .col-xl-8, 141 | .col-xl-7, 142 | .col-xl-6, 143 | .col-xl-5, 144 | .col-xl-4, 145 | .col-xl-3, 146 | .col-xl-2, 147 | .col-xl-1, 148 | .col-xl-auto { 149 | flex: none; 150 | } 151 | .col-xl-12 { 152 | width: 100%; 153 | } 154 | .col-xl-11 { 155 | width: 91.66666667%; 156 | } 157 | .col-xl-10 { 158 | width: 83.33333333%; 159 | } 160 | .col-xl-9 { 161 | width: 75%; 162 | } 163 | .col-xl-8 { 164 | width: 66.66666667%; 165 | } 166 | .col-xl-7 { 167 | width: 58.33333333%; 168 | } 169 | .col-xl-6 { 170 | width: 50%; 171 | } 172 | .col-xl-5 { 173 | width: 41.66666667%; 174 | } 175 | .col-xl-4 { 176 | width: 33.33333333%; 177 | } 178 | .col-xl-3 { 179 | width: 25%; 180 | } 181 | .col-xl-2 { 182 | width: 16.66666667%; 183 | } 184 | .col-xl-1 { 185 | width: 8.33333333%; 186 | } 187 | .col-xl-auto { 188 | width: auto; 189 | } 190 | .hide-xl { 191 | display: none !important; 192 | } 193 | .show-xl { 194 | display: block !important; 195 | } 196 | } 197 | @media (max-width: $size-lg) { 198 | .col-lg-12, 199 | .col-lg-11, 200 | .col-lg-10, 201 | .col-lg-9, 202 | .col-lg-8, 203 | .col-lg-7, 204 | .col-lg-6, 205 | .col-lg-5, 206 | .col-lg-4, 207 | .col-lg-3, 208 | .col-lg-2, 209 | .col-lg-1, 210 | .col-lg-auto { 211 | flex: none; 212 | } 213 | .col-lg-12 { 214 | width: 100%; 215 | } 216 | .col-lg-11 { 217 | width: 91.66666667%; 218 | } 219 | .col-lg-10 { 220 | width: 83.33333333%; 221 | } 222 | .col-lg-9 { 223 | width: 75%; 224 | } 225 | .col-lg-8 { 226 | width: 66.66666667%; 227 | } 228 | .col-lg-7 { 229 | width: 58.33333333%; 230 | } 231 | .col-lg-6 { 232 | width: 50%; 233 | } 234 | .col-lg-5 { 235 | width: 41.66666667%; 236 | } 237 | .col-lg-4 { 238 | width: 33.33333333%; 239 | } 240 | .col-lg-3 { 241 | width: 25%; 242 | } 243 | .col-lg-2 { 244 | width: 16.66666667%; 245 | } 246 | .col-lg-1 { 247 | width: 8.33333333%; 248 | } 249 | .col-lg-auto { 250 | width: auto; 251 | } 252 | .hide-lg { 253 | display: none !important; 254 | } 255 | .show-lg { 256 | display: block !important; 257 | } 258 | } 259 | @media (max-width: $size-md) { 260 | .col-md-12, 261 | .col-md-11, 262 | .col-md-10, 263 | .col-md-9, 264 | .col-md-8, 265 | .col-md-7, 266 | .col-md-6, 267 | .col-md-5, 268 | .col-md-4, 269 | .col-md-3, 270 | .col-md-2, 271 | .col-md-1, 272 | .col-md-auto { 273 | flex: none; 274 | } 275 | .col-md-12 { 276 | width: 100%; 277 | } 278 | .col-md-11 { 279 | width: 91.66666667%; 280 | } 281 | .col-md-10 { 282 | width: 83.33333333%; 283 | } 284 | .col-md-9 { 285 | width: 75%; 286 | } 287 | .col-md-8 { 288 | width: 66.66666667%; 289 | } 290 | .col-md-7 { 291 | width: 58.33333333%; 292 | } 293 | .col-md-6 { 294 | width: 50%; 295 | } 296 | .col-md-5 { 297 | width: 41.66666667%; 298 | } 299 | .col-md-4 { 300 | width: 33.33333333%; 301 | } 302 | .col-md-3 { 303 | width: 25%; 304 | } 305 | .col-md-2 { 306 | width: 16.66666667%; 307 | } 308 | .col-md-1 { 309 | width: 8.33333333%; 310 | } 311 | .col-md-auto { 312 | width: auto; 313 | } 314 | .hide-md { 315 | display: none !important; 316 | } 317 | .show-md { 318 | display: block !important; 319 | } 320 | } 321 | @media (max-width: $size-sm) { 322 | .col-sm-12, 323 | .col-sm-11, 324 | .col-sm-10, 325 | .col-sm-9, 326 | .col-sm-8, 327 | .col-sm-7, 328 | .col-sm-6, 329 | .col-sm-5, 330 | .col-sm-4, 331 | .col-sm-3, 332 | .col-sm-2, 333 | .col-sm-1, 334 | .col-sm-auto { 335 | flex: none; 336 | } 337 | .col-sm-12 { 338 | width: 100%; 339 | } 340 | .col-sm-11 { 341 | width: 91.66666667%; 342 | } 343 | .col-sm-10 { 344 | width: 83.33333333%; 345 | } 346 | .col-sm-9 { 347 | width: 75%; 348 | } 349 | .col-sm-8 { 350 | width: 66.66666667%; 351 | } 352 | .col-sm-7 { 353 | width: 58.33333333%; 354 | } 355 | .col-sm-6 { 356 | width: 50%; 357 | } 358 | .col-sm-5 { 359 | width: 41.66666667%; 360 | } 361 | .col-sm-4 { 362 | width: 33.33333333%; 363 | } 364 | .col-sm-3 { 365 | width: 25%; 366 | } 367 | .col-sm-2 { 368 | width: 16.66666667%; 369 | } 370 | .col-sm-1 { 371 | width: 8.33333333%; 372 | } 373 | .col-sm-auto { 374 | width: auto; 375 | } 376 | .hide-sm { 377 | display: none !important; 378 | } 379 | .show-sm { 380 | display: block !important; 381 | } 382 | } 383 | @media (max-width: $size-xs) { 384 | .col-xs-12, 385 | .col-xs-11, 386 | .col-xs-10, 387 | .col-xs-9, 388 | .col-xs-8, 389 | .col-xs-7, 390 | .col-xs-6, 391 | .col-xs-5, 392 | .col-xs-4, 393 | .col-xs-3, 394 | .col-xs-2, 395 | .col-xs-1, 396 | .col-xs-auto { 397 | flex: none; 398 | } 399 | .col-xs-12 { 400 | width: 100%; 401 | } 402 | .col-xs-11 { 403 | width: 91.66666667%; 404 | } 405 | .col-xs-10 { 406 | width: 83.33333333%; 407 | } 408 | .col-xs-9 { 409 | width: 75%; 410 | } 411 | .col-xs-8 { 412 | width: 66.66666667%; 413 | } 414 | .col-xs-7 { 415 | width: 58.33333333%; 416 | } 417 | .col-xs-6 { 418 | width: 50%; 419 | } 420 | .col-xs-5 { 421 | width: 41.66666667%; 422 | } 423 | .col-xs-4 { 424 | width: 33.33333333%; 425 | } 426 | .col-xs-3 { 427 | width: 25%; 428 | } 429 | .col-xs-2 { 430 | width: 16.66666667%; 431 | } 432 | .col-xs-1 { 433 | width: 8.33333333%; 434 | } 435 | .col-xs-auto { 436 | width: auto; 437 | } 438 | .hide-xs { 439 | display: none !important; 440 | } 441 | .show-xs { 442 | display: block !important; 443 | } 444 | } 445 | -------------------------------------------------------------------------------- /src/addfocus/events.cljs: -------------------------------------------------------------------------------- 1 | (ns addfocus.events 2 | (:require 3 | [re-frame.core :as rf] 4 | [tools.time :as time] 5 | [addfocus.helpers :refer [get-task exp->lvl lvl->exp]])) 6 | 7 | ; ----------------------------- Default Database ----------------------------- ; 8 | 9 | (rf/reg-event-db 10 | :initialize 11 | (constantly 12 | {:tasks [] 13 | :history [] 14 | :player {:level 1 15 | :exp 13300 16 | :coins 5} 17 | :active-task {:id 0 18 | :state :ready 19 | :start-time (time/now) 20 | :paused-at (time/now) 21 | :pause-duration 0 22 | :paused-times 0 23 | :end-time (+ (time/now) 1500000)}})) 24 | 25 | (rf/dispatch [:timer-completed]) 26 | 27 | ; --------------------------------- Load data -------------------------------- ; 28 | 29 | (rf/reg-event-db 30 | :load-data 31 | (fn [db [_ context data]] 32 | (assoc db context data))) 33 | 34 | ;(for [x [["a" "b"] ["x" "y"]]] (first x)) 35 | ;(.log js/console [["a" "b"] ["x" "y"]]) 36 | (for [x [["aa" {:wtf "xx"}] ["vv" {:s "ucks"}]]] x) 37 | 38 | (rf/reg-fx 39 | :save-to-cloud 40 | (fn [updates] 41 | (doall (for [x updates] 42 | (.saveRemoteData js/window (first x) (clj->js (second x))))))) 43 | 44 | ; ------------------------------- Add new task ------------------------------- ; 45 | 46 | (rf/reg-event-fx 47 | :new-task 48 | (fn [{:keys [db]} [_ task start-now]] 49 | (let 50 | [id (time/now) 51 | newdb (assoc db :tasks (conj (:tasks db) (assoc task :id id)))] 52 | {:db newdb 53 | :save-to-cloud {"tasks" (:tasks newdb)} 54 | :dispatch-later [(if start-now {:ms 10 :dispatch [:active-task id]}) 55 | (if start-now {:ms 500 :dispatch [:run-active-task]})]}))) 56 | 57 | ; ------------------------------- Delete a task ------------------------------ ; 58 | 59 | (rf/reg-event-fx 60 | :delete-task 61 | (fn [{:keys [db]} [_ id]] 62 | (let 63 | [newdb (assoc db :tasks (filter #(not= id (:id %)) (:tasks db)))] 64 | {:db newdb 65 | :save-to-cloud {"tasks" (:tasks newdb)}}))) 66 | 67 | ; --------------------------- Start the break timer -------------------------- ; 68 | 69 | (rf/reg-event-fx 70 | :break-timer 71 | (fn [{:keys [db]} [_ timer]] 72 | (let [id (if (< 0 timer 100) timer 5)] 73 | {:dispatch-later [{:ms 10 :dispatch [:active-task id]} 74 | {:ms 500 :dispatch [:run-active-task]}]}))) 75 | 76 | ; --------------------------- Choose an active task -------------------------- ; 77 | 78 | (rf/reg-event-db 79 | :active-task 80 | (fn [db [_ task-id]] 81 | (do 82 | (.stopTimerBar js/window) 83 | (.clearTimerBar js/window) 84 | (assoc db :active-task 85 | {:id task-id 86 | :state :ready 87 | :start-time (time/now) 88 | :paused-at (time/now) 89 | :pause-duration 0 90 | :paused-times 0 91 | :end-time (+ (time/now) 92 | (* 60000 (:time (get-task task-id (:tasks db)))))})))) 93 | 94 | ; ---------------------- Start timer for the active task --------------------- ; 95 | 96 | (rf/reg-event-db 97 | :run-active-task 98 | (fn [db _] 99 | (let 100 | [task (get-task (:id (:active-task db)) (:tasks db))] 101 | (do 102 | (.timerBar js/window 103 | (:time task) 0 104 | (if (:break task) 105 | #(rf/dispatch [:break-completed]) 106 | #(rf/dispatch [:timer-completed]))) 107 | (-> 108 | db 109 | (assoc-in [:active-task :state] :running) 110 | (assoc-in [:active-task :start-time] (time/now)) 111 | (assoc-in [:active-task :end-time] 112 | (+ (time/now) 113 | (:pause-duration (:active-task db)) 114 | (* 60000 115 | (:time (get-task (:id (:active-task db)) 116 | (:tasks db))))))))))) 117 | 118 | ; --------------------------- Pause the active task -------------------------- ; 119 | 120 | (rf/reg-event-db 121 | :pause-active-task 122 | (fn [db _] 123 | (do 124 | (.stopTimerBar js/window) 125 | (-> 126 | db 127 | (assoc-in [:active-task :state] :paused) 128 | (assoc-in [:active-task :paused-at] (time/now)))))) 129 | 130 | ; -------------------------- Resume the active task -------------------------- ; 131 | 132 | (rf/reg-event-db 133 | :resume-active-task 134 | (fn [db _] 135 | (let [active (:active-task db) 136 | task (get-task (:id active) (:tasks db)) 137 | paused-total (+ (:pause-duration active) 138 | (- (time/now) (:paused-at active))) 139 | worked-total (- (- (time/now) (:start-time active)) 140 | paused-total) 141 | start-minute (/ worked-total 60000) 142 | end-time (+ (+ (:start-time active) paused-total) 143 | (* 60000 (:time task)))] 144 | (do 145 | (.timerBar js/window 146 | (:time task) start-minute 147 | #(rf/dispatch [:timer-completed])) 148 | (-> 149 | db 150 | (assoc-in [:active-task :state] :running) 151 | (assoc-in [:active-task :pause-duration] paused-total) 152 | (assoc-in [:active-task :end-time] end-time) 153 | (update-in [:active-task :paused-times] inc)))))) 154 | 155 | ; ------------------------- Task completion callback ------------------------- ; 156 | 157 | (defn calculate-bonus 158 | [] 159 | (let [at @(rf/subscribe [:active-task]) 160 | bonus-data @(rf/subscribe [:bonus-data]) 161 | task-point (* (:time (:task at)) 162 | (case [(:important (:task at)) (:urgent (:task at))] 163 | [true true] 4 164 | [true false] 3.5 165 | [false true] 2 166 | 1)) 167 | hour (.getHours (time/obj (:start-time at)))] 168 | {:point task-point 169 | :exp (int (* task-point (get (:hour-bonus bonus-data) hour)))})) 170 | 171 | (rf/reg-event-fx 172 | :timer-completed 173 | (fn [{:keys [db]} _] 174 | (let 175 | [bonus (calculate-bonus) 176 | history-item {:date (:start-time (:active-task db)) 177 | :task-id (:id (:active-task db)) 178 | :exp (:exp bonus) 179 | :point (:point bonus) 180 | :duration (:time (get-task 181 | (:id (:active-task db)) 182 | (:tasks db)))} 183 | newdb (-> db 184 | (update-in [:player :exp] #(+ (:exp bonus) %)) 185 | (update-in [:player :coins] #(+ (:point bonus) %)) 186 | (assoc-in [:active-task :state] :completed) 187 | (assoc :history (conj (:history db) history-item)))] 188 | {:db newdb 189 | :dispatch [:calculate-level] 190 | :save-to-cloud {"history" (:history newdb) 191 | "player" (:player newdb)}}))) 192 | 193 | (rf/reg-event-fx 194 | :calculate-level 195 | (fn [{:keys [db]} _] 196 | (let [level (exp->lvl (:exp (:player db)))] 197 | (if (> level (:level (:player db))) 198 | {:db (assoc-in db [:player :level] level)} 199 | {})))) 200 | 201 | ; ------------------------- Break completion callback ------------------------ ; 202 | 203 | (rf/reg-event-db 204 | :break-completed 205 | (fn [db _] 206 | (assoc-in db [:active-task :state] :break-completed))) 207 | 208 | (rf/reg-event-fx 209 | :cancel-session 210 | (fn [{:keys [db]} _] 211 | (let 212 | [bonus (calculate-bonus) 213 | newdb (-> db 214 | (assoc :history 215 | (filter 216 | #(not= (:start-time (:active-task db)) (:date %)) 217 | (:history db))) 218 | (update-in [:player :exp] #(- % (:exp bonus))) 219 | (update-in [:player :coins] #(- % (:point bonus))))] 220 | {:db newdb 221 | :save-to-cloud {"history" (:history newdb) 222 | "player" (:player newdb)} 223 | :dispatch [:active-task (:id (:active-task db))]}))) 224 | 225 | ; ---------------------------------------------------------------------------- ; 226 | ; Temporary development related functions ; 227 | ; ---------------------------------------------------------------------------- ; 228 | 229 | (defn random-history-last-week [] 230 | (let [start-time (time/midnight (- (time/now) 231 | (* 7 time/d-ms)))] 232 | (into [] 233 | (for [x (range 100)] 234 | (let [date (+ start-time 235 | (* x (/ (* 7 time/d-ms) 100)) 236 | (rand-int (/ (* 7 time/d-ms) 100)))] 237 | {:date date 238 | :task-id 1581010679462 239 | :duration (rand-int 20)}))))) 240 | 241 | (rf/reg-event-fx 242 | :save-temp-history 243 | (fn [{:keys [db]} _] 244 | (let 245 | [history (random-history-last-week) 246 | newdb (-> db (assoc :history history))] 247 | {:db newdb 248 | :save-to-cloud ["history" (:history newdb)]}))) -------------------------------------------------------------------------------- /assets/scss/addr/spectre/_normalize.scss: -------------------------------------------------------------------------------- 1 | /* Manually forked from Normalize.css */ 2 | /* normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */ 3 | 4 | /** 5 | * 1. Change the default font family in all browsers (opinionated). 6 | * 2. Correct the line height in all browsers. 7 | * 3. Prevent adjustments of font size after orientation changes in 8 | * IE on Windows Phone and in iOS. 9 | */ 10 | 11 | /* Document 12 | ========================================================================== */ 13 | 14 | html { 15 | font-family: sans-serif; /* 1 */ 16 | -ms-text-size-adjust: 100%; /* 3 */ 17 | -webkit-text-size-adjust: 100%; /* 3 */ 18 | } 19 | 20 | /* Sections 21 | ========================================================================== */ 22 | 23 | /** 24 | * Remove the margin in all browsers (opinionated). 25 | */ 26 | 27 | body { 28 | margin: 0; 29 | } 30 | 31 | /** 32 | * Add the correct display in IE 9-. 33 | */ 34 | 35 | article, 36 | aside, 37 | footer, 38 | header, 39 | nav, 40 | section { 41 | display: block; 42 | } 43 | 44 | /** 45 | * Correct the font size and margin on `h1` elements within `section` and 46 | * `article` contexts in Chrome, Firefox, and Safari. 47 | */ 48 | 49 | h1 { 50 | font-size: 2em; 51 | margin: 0.67em 0; 52 | } 53 | 54 | /* Grouping content 55 | ========================================================================== */ 56 | 57 | /** 58 | * Add the correct display in IE 9-. 59 | * 1. Add the correct display in IE. 60 | */ 61 | 62 | figcaption, 63 | figure, 64 | main { /* 1 */ 65 | display: block; 66 | } 67 | 68 | /** 69 | * Add the correct margin in IE 8 (removed). 70 | */ 71 | 72 | /** 73 | * 1. Add the correct box sizing in Firefox. 74 | * 2. Show the overflow in Edge and IE. 75 | */ 76 | 77 | hr { 78 | box-sizing: content-box; /* 1 */ 79 | height: 0; /* 1 */ 80 | overflow: visible; /* 2 */ 81 | } 82 | 83 | /** 84 | * 1. Correct the inheritance and scaling of font size in all browsers. (removed) 85 | * 2. Correct the odd `em` font sizing in all browsers. 86 | */ 87 | 88 | /* Text-level semantics 89 | ========================================================================== */ 90 | 91 | /** 92 | * 1. Remove the gray background on active links in IE 10. 93 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. 94 | */ 95 | 96 | a { 97 | background-color: transparent; /* 1 */ 98 | -webkit-text-decoration-skip: objects; /* 2 */ 99 | } 100 | 101 | /** 102 | * Remove the outline on focused links when they are also active or hovered 103 | * in all browsers (opinionated). 104 | */ 105 | 106 | a:active, 107 | a:hover { 108 | outline-width: 0; 109 | } 110 | 111 | /** 112 | * Modify default styling of address. 113 | */ 114 | 115 | address { 116 | font-style: normal; 117 | } 118 | 119 | /** 120 | * 1. Remove the bottom border in Firefox 39-. 121 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. (removed) 122 | */ 123 | 124 | /** 125 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6. 126 | */ 127 | 128 | b, 129 | strong { 130 | font-weight: inherit; 131 | } 132 | 133 | /** 134 | * Add the correct font weight in Chrome, Edge, and Safari. 135 | */ 136 | 137 | b, 138 | strong { 139 | font-weight: bolder; 140 | } 141 | 142 | /** 143 | * 1. Correct the inheritance and scaling of font size in all browsers. 144 | * 2. Correct the odd `em` font sizing in all browsers. 145 | */ 146 | 147 | code, 148 | kbd, 149 | pre, 150 | samp { 151 | font-family: $mono-font-family; /* 1 (changed) */ 152 | font-size: 1em; /* 2 */ 153 | } 154 | 155 | /** 156 | * Add the correct font style in Android 4.3-. 157 | */ 158 | 159 | dfn { 160 | font-style: italic; 161 | } 162 | 163 | /** 164 | * Add the correct background and color in IE 9-. (Removed) 165 | */ 166 | 167 | /** 168 | * Add the correct font size in all browsers. 169 | */ 170 | 171 | small { 172 | font-size: 80%; 173 | font-weight: 400; /* (added) */ 174 | } 175 | 176 | /** 177 | * Prevent `sub` and `sup` elements from affecting the line height in 178 | * all browsers. 179 | */ 180 | 181 | sub, 182 | sup { 183 | font-size: 75%; 184 | line-height: 0; 185 | position: relative; 186 | vertical-align: baseline; 187 | } 188 | 189 | sub { 190 | bottom: -0.25em; 191 | } 192 | 193 | sup { 194 | top: -0.5em; 195 | } 196 | 197 | /* Embedded content 198 | ========================================================================== */ 199 | 200 | /** 201 | * Add the correct display in IE 9-. 202 | */ 203 | 204 | audio, 205 | video { 206 | display: inline-block; 207 | } 208 | 209 | /** 210 | * Add the correct display in iOS 4-7. 211 | */ 212 | 213 | audio:not([controls]) { 214 | display: none; 215 | height: 0; 216 | } 217 | 218 | /** 219 | * Remove the border on images inside links in IE 10-. 220 | */ 221 | 222 | img { 223 | border-style: none; 224 | } 225 | 226 | /** 227 | * Hide the overflow in IE. 228 | */ 229 | 230 | svg:not(:root) { 231 | overflow: hidden; 232 | } 233 | 234 | /* Forms 235 | ========================================================================== */ 236 | 237 | /** 238 | * 1. Change the font styles in all browsers (opinionated). 239 | * 2. Remove the margin in Firefox and Safari. 240 | */ 241 | 242 | button, 243 | input, 244 | optgroup, 245 | select, 246 | textarea { 247 | font-family: inherit; /* 1 (changed) */ 248 | font-size: inherit; /* 1 (changed) */ 249 | line-height: inherit; /* 1 (changed) */ 250 | margin: 0; /* 2 */ 251 | } 252 | 253 | /** 254 | * Show the overflow in IE. 255 | * 1. Show the overflow in Edge. 256 | */ 257 | 258 | button, 259 | input { /* 1 */ 260 | overflow: visible; 261 | } 262 | 263 | /** 264 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 265 | * 1. Remove the inheritance of text transform in Firefox. 266 | */ 267 | 268 | button, 269 | select { /* 1 */ 270 | text-transform: none; 271 | } 272 | 273 | /** 274 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` 275 | * controls in Android 4. 276 | * 2. Correct the inability to style clickable types in iOS and Safari. 277 | */ 278 | 279 | button, 280 | html [type="button"], /* 1 */ 281 | [type="reset"], 282 | [type="submit"] { 283 | -webkit-appearance: button; /* 2 */ 284 | } 285 | 286 | /** 287 | * Remove the inner border and padding in Firefox. 288 | */ 289 | 290 | button::-moz-focus-inner, 291 | [type="button"]::-moz-focus-inner, 292 | [type="reset"]::-moz-focus-inner, 293 | [type="submit"]::-moz-focus-inner { 294 | border-style: none; 295 | padding: 0; 296 | } 297 | 298 | /** 299 | * Restore the focus styles unset by the previous rule (removed). 300 | */ 301 | 302 | 303 | /** 304 | * Change the border, margin, and padding in all browsers (opinionated) (changed). 305 | */ 306 | 307 | fieldset { 308 | border: 0; 309 | margin: 0; 310 | padding: 0; 311 | } 312 | 313 | /** 314 | * 1. Correct the text wrapping in Edge and IE. 315 | * 2. Correct the color inheritance from `fieldset` elements in IE. 316 | * 3. Remove the padding so developers are not caught out when they zero out 317 | * `fieldset` elements in all browsers. 318 | */ 319 | 320 | legend { 321 | box-sizing: border-box; /* 1 */ 322 | color: inherit; /* 2 */ 323 | display: table; /* 1 */ 324 | max-width: 100%; /* 1 */ 325 | padding: 0; /* 3 */ 326 | white-space: normal; /* 1 */ 327 | } 328 | 329 | /** 330 | * 1. Add the correct display in IE 9-. 331 | * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. 332 | */ 333 | 334 | progress { 335 | display: inline-block; /* 1 */ 336 | vertical-align: baseline; /* 2 */ 337 | } 338 | 339 | /** 340 | * Remove the default vertical scrollbar in IE. 341 | */ 342 | 343 | textarea { 344 | overflow: auto; 345 | } 346 | 347 | /** 348 | * 1. Add the correct box sizing in IE 10-. 349 | * 2. Remove the padding in IE 10-. 350 | */ 351 | 352 | [type="checkbox"], 353 | [type="radio"] { 354 | box-sizing: border-box; /* 1 */ 355 | padding: 0; /* 2 */ 356 | } 357 | 358 | /** 359 | * Correct the cursor style of increment and decrement buttons in Chrome. 360 | */ 361 | 362 | [type="number"]::-webkit-inner-spin-button, 363 | [type="number"]::-webkit-outer-spin-button { 364 | height: auto; 365 | } 366 | 367 | /** 368 | * 1. Correct the odd appearance in Chrome and Safari. 369 | * 2. Correct the outline style in Safari. 370 | */ 371 | 372 | [type="search"] { 373 | -webkit-appearance: textfield; /* 1 */ 374 | outline-offset: -2px; /* 2 */ 375 | } 376 | 377 | /** 378 | * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. 379 | */ 380 | 381 | [type="search"]::-webkit-search-cancel-button, 382 | [type="search"]::-webkit-search-decoration { 383 | -webkit-appearance: none; 384 | } 385 | 386 | /** 387 | * 1. Correct the inability to style clickable types in iOS and Safari. 388 | * 2. Change font properties to `inherit` in Safari. 389 | */ 390 | 391 | ::-webkit-file-upload-button { 392 | -webkit-appearance: button; /* 1 */ 393 | font: inherit; /* 2 */ 394 | } 395 | 396 | /* Interactive 397 | ========================================================================== */ 398 | 399 | /* 400 | * Add the correct display in IE 9-. 401 | * 1. Add the correct display in Edge, IE, and Firefox. 402 | */ 403 | 404 | details, /* 1 */ 405 | menu { 406 | display: block; 407 | } 408 | 409 | /* 410 | * Add the correct display in all browsers. 411 | */ 412 | 413 | summary { 414 | display: list-item; 415 | outline: none; 416 | } 417 | 418 | /* Scripting 419 | ========================================================================== */ 420 | 421 | /** 422 | * Add the correct display in IE 9-. 423 | */ 424 | 425 | canvas { 426 | display: inline-block; 427 | } 428 | 429 | /** 430 | * Add the correct display in IE. 431 | */ 432 | 433 | template { 434 | display: none; 435 | } 436 | 437 | /* Hidden 438 | ========================================================================== */ 439 | 440 | /** 441 | * Add the correct display in IE 10-. 442 | */ 443 | 444 | [hidden] { 445 | display: none; 446 | } 447 | -------------------------------------------------------------------------------- /assets/scss/addr/_form.scss: -------------------------------------------------------------------------------- 1 | .form-holder { 2 | label { 3 | font-weight: 400; 4 | color: $m-color; 5 | background-color: white; 6 | } 7 | 8 | .form-group { 9 | position: relative; 10 | margin-top: 40px; 11 | 12 | .tooltip { 13 | visibility: hidden; 14 | background: hsl(226, 73%, 63%); 15 | border-radius: $border-radius; 16 | color: $light-color; 17 | font-size: $unit-3; 18 | padding: $unit-2; 19 | position: absolute; 20 | min-height: 50px; 21 | width: 100%; 22 | z-index: 2; 23 | bottom: calc(100% + 20px); 24 | text-align: center; 25 | 26 | &:after { 27 | position: absolute; 28 | top: 50px; 29 | left: calc(50% - 10px); 30 | width: 0; 31 | border-top: 10px solid hsl(226, 73%, 63%); 32 | border-right: 10px solid transparent; 33 | border-left: 10px solid transparent; 34 | content: " "; 35 | font-size: 0; 36 | line-height: 0; 37 | } 38 | } 39 | 40 | .input-error { 41 | visibility: hidden; 42 | background: hsl(14, 77%, 54%); 43 | border-radius: $border-radius $border-radius 0 0; 44 | color: $light-color; 45 | font-size: 11px; 46 | padding: $unit-1; 47 | max-width: 70%; 48 | position: absolute; 49 | z-index: 1; 50 | bottom: 100%; 51 | margin-bottom: -1px; 52 | right: 0; 53 | } 54 | 55 | &:hover .tooltip { 56 | visibility: visible; 57 | animation: fadein 0.5s; 58 | } 59 | 60 | &.has-error .input-error { 61 | visibility: visible; 62 | animation: fadein 1s; 63 | } 64 | 65 | &.has-error { 66 | input, 67 | textarea, 68 | select { 69 | font-weight: 500; 70 | color: hsl(14, 77%, 54%); 71 | border: none; 72 | box-shadow: 0 1px 3px hsl(14, 77%, 54%); 73 | } 74 | } 75 | 76 | .form-label { 77 | border: hsl(201, 62%, 93%) solid 1px; 78 | border-bottom: none; 79 | border-radius: $border-radius $border-radius 0 0; 80 | color: $dark-color; 81 | font-size: 14px; 82 | padding: $unit-o $unit-1; 83 | position: absolute; 84 | bottom: calc(-4px + 100%); 85 | left: -1px; 86 | 87 | &.toggle-label { 88 | font-weight: 500; 89 | text-align: center; 90 | min-width: 70%; 91 | left: 15%; 92 | border: hsl(202, 57%, 86%) solid 1px; 93 | border-bottom: none; 94 | } 95 | } 96 | 97 | &.compact { 98 | margin-top: 0px; 99 | .form-label {display: none;} 100 | } 101 | } 102 | 103 | input, 104 | .form-input, 105 | .picker, 106 | textarea, 107 | select { 108 | font-weight: 500; 109 | color: hsl(200, 65%, 27%); 110 | border: none; 111 | box-shadow: 0 1px 2px hsl(200, 64%, 77%); 112 | transition: box-shadow 0.5s ease; 113 | margin: 2px 0; 114 | 115 | &:focus { 116 | box-shadow: 0 0 6px hsl(200, 55%, 60%); 117 | } 118 | } 119 | 120 | .merged-inputs { 121 | display: flex; 122 | position: relative; 123 | 124 | .left { 125 | margin-right: 2px; 126 | } 127 | 128 | .middle { 129 | margin: auto 2px; 130 | } 131 | 132 | .right { 133 | margin-left: 2px; 134 | } 135 | 136 | .wide { 137 | flex-basis: 160%; 138 | } 139 | .narrow { 140 | flex-basis: 60%; 141 | } 142 | 143 | .auto-show { 144 | display: none; 145 | } 146 | 147 | &:hover { 148 | .auto-show { 149 | display: initial; 150 | } 151 | .auto-hide { 152 | display: none; 153 | } 154 | } 155 | 156 | .auto-show:focus { 157 | display: block; 158 | 159 | ~ .picker { 160 | display: block; 161 | } 162 | 163 | ~ .auto-hide { 164 | display: none; 165 | } 166 | } 167 | 168 | .picker { 169 | position: absolute; 170 | border-radius: $border-radius; 171 | left: 0px; 172 | top: 96%; 173 | width: 100%; 174 | background-color: white; 175 | z-index: 8; 176 | display: none; 177 | max-height: 200px; 178 | overflow: auto; 179 | 180 | &:hover { 181 | display: block; 182 | } 183 | 184 | .item { 185 | padding: 3px; 186 | margin: 3px; 187 | border-radius: 2px; 188 | cursor: pointer; 189 | 190 | &:nth-of-type(odd) { 191 | background: #ececec; 192 | } 193 | 194 | &:hover { 195 | background-color: bisque; 196 | } 197 | } 198 | } 199 | } 200 | 201 | input.currency { 202 | padding-right: 32px; 203 | } 204 | .input-currency { 205 | //background-color: white; 206 | user-select: none; 207 | font-size: 12px; 208 | font-weight: 600; 209 | position: absolute; 210 | z-index: 1; 211 | margin: 10px; 212 | top: 0; 213 | right: 0; 214 | } 215 | 216 | .btn { 217 | float: right; 218 | border-radius: 4px; 219 | } 220 | 221 | .bottom { 222 | text-align: center; 223 | font-size: $unit-3; 224 | } 225 | 226 | .amount-buttons { 227 | margin-top: -4px; 228 | text-align: center; 229 | button { 230 | border-radius: 0 0 $border-radius $border-radius; 231 | background-color: hsl(203, 67%, 98%); 232 | border: hsl(202, 71%, 77%) solid 1px; 233 | font-weight: 500; 234 | border-top: none; 235 | margin: 0 2px; 236 | } 237 | } 238 | 239 | .readonly { 240 | user-select: none; 241 | background-color: rgb(246, 246, 246); 242 | &.blocked { 243 | cursor: not-allowed; 244 | } 245 | } 246 | 247 | ////////////// 248 | // SELECTOR // 249 | ////////////// 250 | .smart-selector { 251 | input:hover + .selector { 252 | input, 253 | .list { 254 | visibility: visible; 255 | } 256 | } 257 | 258 | .selector { 259 | position: relative; 260 | top: -50px; 261 | width: 100%; 262 | height: 0px; 263 | 264 | label { 265 | display: block; 266 | width: 100%; 267 | position: relative; 268 | top: -36px; 269 | background-color: #ffffff01; 270 | padding-top: 52px; 271 | height: 34px; 272 | 273 | &:hover { 274 | height: initial; 275 | } 276 | &:hover input { 277 | box-shadow: none; 278 | } 279 | &:hover input, 280 | &:hover .list { 281 | visibility: visible; 282 | } 283 | input, 284 | input:focus { 285 | box-shadow: none; 286 | border: 1px solid lightblue; 287 | } 288 | } 289 | 290 | input, 291 | .list { 292 | margin: 0; 293 | visibility: hidden; 294 | z-index: 5; 295 | } 296 | 297 | input:focus, 298 | input:focus + .list { 299 | visibility: visible; 300 | } 301 | 302 | .list { 303 | border-radius: 0 0 $border-radius $border-radius; 304 | background-color: white; 305 | width: 100%; 306 | position: relative; 307 | top: -3px; 308 | z-index: 222; 309 | //box-shadow: 0px -1px 1px inset rgb(20, 103, 172); 310 | border: 1px solid lightblue; 311 | border-top: none; 312 | overflow: auto; 313 | max-height: 560px; 314 | 315 | .item { 316 | padding: 3px; 317 | margin: 3px; 318 | border-radius: 2px; 319 | cursor: pointer; 320 | 321 | &:nth-of-type(odd) { 322 | background: #ececec; 323 | } 324 | 325 | &:hover { 326 | background-color: bisque; 327 | } 328 | 329 | span { 330 | display: block; 331 | } 332 | .name { 333 | font-weight: 500; 334 | } 335 | .address { 336 | font-size: smaller; 337 | } 338 | } 339 | } 340 | } 341 | } 342 | 343 | ////////////// 344 | // TOGGLE // 345 | ////////////// 346 | .ftoggle { 347 | font-weight: 600; 348 | text-align: center; 349 | border-radius: 4px; 350 | height: 2.2em; 351 | margin: 2px; 352 | background-color: #00000011; 353 | position: relative; 354 | cursor: pointer; 355 | box-shadow: 0 1px 2px hsl(200, 64%, 77%); 356 | user-select: none; 357 | 358 | &:hover { 359 | box-shadow: 0 0 5px hsl(200, 64%, 77%); 360 | } 361 | 362 | .true, 363 | .false { 364 | position: absolute; 365 | width: 50%; 366 | left: 0; 367 | top: 0; 368 | height: 2.2em; 369 | padding: 0.2em 0; 370 | transition: 0.4s; 371 | border-radius: 4px; 372 | color: grey; 373 | } 374 | 375 | // ON 376 | &.on .true { 377 | color: black; 378 | &.yesno { 379 | background-color: hsl(100, 70%, 64%); 380 | } 381 | &.neutral { 382 | background-color: hsl(285, 77%, 80%); 383 | } 384 | } 385 | 386 | &.on .false { 387 | left: 50%; 388 | } 389 | 390 | // OFF 391 | &.off .false { 392 | color: black; 393 | &.yesno { 394 | background-color: hsl(0, 90%, 74%); 395 | } 396 | &.neutral { 397 | background-color: hsl(195, 65%, 67%); 398 | } 399 | } 400 | &.off .true { 401 | left: 50%; 402 | } 403 | } 404 | 405 | ////////////// 406 | // LOCATION // 407 | ////////////// 408 | 409 | .flocation { 410 | .form-input { 411 | border-bottom: none; 412 | border-radius: $border-radius $border-radius 0 0; 413 | 414 | &:focus + .location-picker { 415 | box-shadow: 0 0 6px hsl(200, 55%, 60%); 416 | } 417 | } 418 | 419 | .location-picker { 420 | box-shadow: 0 1px 2px hsl(200, 64%, 77%); 421 | transition: box-shadow 0.5s ease; 422 | border-radius: 0 0 $border-radius $border-radius; 423 | padding: 2px; 424 | width: 100%; 425 | height: 240px; 426 | &.tall { 427 | height: 480px; 428 | } 429 | 430 | .ol-attribution { 431 | transform: matrix(0.6, 0, 0, 0.6, 45, 3); 432 | } 433 | .ol-zoom { 434 | transform: matrix(0.6, 0, 0, 0.6, -3, -8); 435 | } 436 | } 437 | } 438 | } 439 | 440 | // DATE TIME // 441 | 442 | .date-input { 443 | &:hover { 444 | .fdatetime { 445 | display: block; 446 | } 447 | } 448 | } 449 | 450 | .fdatetime { 451 | z-index: 9; 452 | user-select: none; 453 | display: none; 454 | top: 0px; 455 | position: absolute; 456 | background-color: white; 457 | box-shadow: 0 1px 2px hsl(200, 64%, 77%); 458 | border-radius: 0 0 $border-radius $border-radius; 459 | padding: 2px; 460 | width: 100%; 461 | max-width: 340px; 462 | 463 | .month { 464 | display: flex; 465 | justify-content: space-between; 466 | flex-wrap: wrap; 467 | text-align: center; 468 | font-size: 12px; 469 | 470 | .controls, 471 | .time { 472 | width: 100%; 473 | display: flex; 474 | justify-content: space-between; 475 | 476 | div { 477 | flex-grow: 1; 478 | height: 22px; 479 | margin: 1px 0.2%; 480 | border-radius: 4px; 481 | background-color: rgb(236, 235, 227); 482 | box-shadow: inset 1px 1px 1px rgba(212, 211, 211, 0.6); 483 | 484 | &.txt { 485 | font-weight: bold; 486 | min-width: 60px; 487 | &:hover { 488 | box-shadow: 0 0 6px hsl(200, 55%, 60%); 489 | cursor: pointer; 490 | } 491 | } 492 | } 493 | } 494 | 495 | .time { 496 | margin-top: 3px; 497 | border-top: rgb(231, 228, 228) 1px dashed; 498 | padding-top: 3px; 499 | .txt { 500 | padding: 4px; 501 | font-size: 16px; 502 | height: 32px; 503 | background: linear-gradient( 504 | to bottom, 505 | rgba(236, 235, 227, 1) 0%, 506 | rgba(209, 207, 209, 1) 49%, 507 | rgba(217, 217, 217, 1) 50%, 508 | rgba(201, 199, 201, 1) 100% 509 | ); 510 | } 511 | 512 | .pick { 513 | background-color: rgb(233, 230, 230); 514 | align-self: flex-end; 515 | width: 13%; 516 | } 517 | } 518 | 519 | .day { 520 | width: 13%; 521 | height: 22px; 522 | margin: 1px 0.2%; 523 | border-radius: 4px; 524 | background-color: rgb(236, 235, 227); 525 | box-shadow: inset 1px 1px 1px rgba(212, 211, 211, 0.6); 526 | cursor: default; 527 | } 528 | 529 | .pick { 530 | &:hover { 531 | box-shadow: 0 0 6px hsl(200, 55%, 60%); 532 | background-color: rgb(255, 255, 255); 533 | color: black; 534 | font-weight: bolder; 535 | } 536 | cursor: pointer; 537 | } 538 | 539 | .off { 540 | color: rgb(68, 47, 13); 541 | background-color: rgb(219, 218, 210); 542 | font-weight: bold; 543 | } 544 | 545 | .selected { 546 | background-color: hsl(200, 55%, 60%); 547 | color: white; 548 | font-weight: bolder; 549 | } 550 | 551 | .na { 552 | background-color: rgb(245, 243, 243); 553 | color: rgb(155, 155, 155); 554 | } 555 | } 556 | } 557 | --------------------------------------------------------------------------------