├── 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 | [](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 |
--------------------------------------------------------------------------------