')
373 | .append(i.clone())
374 | .remove()
375 | .html()
376 | .replace(/type="password"/i, 'type="text"')
377 | .replace(/type=password/i, 'type=text')
378 | );
379 |
380 | if (i.attr('id') != '')
381 | x.attr('id', i.attr('id') + '-polyfill-field');
382 |
383 | if (i.attr('name') != '')
384 | x.attr('name', i.attr('name') + '-polyfill-field');
385 |
386 | x.addClass('polyfill-placeholder')
387 | .val(x.attr('placeholder')).insertAfter(i);
388 |
389 | if (i.val() == '')
390 | i.hide();
391 | else
392 | x.hide();
393 |
394 | i
395 | .on('blur', function(event) {
396 |
397 | event.preventDefault();
398 |
399 | var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
400 |
401 | if (i.val() == '') {
402 |
403 | i.hide();
404 | x.show();
405 |
406 | }
407 |
408 | });
409 |
410 | x
411 | .on('focus', function(event) {
412 |
413 | event.preventDefault();
414 |
415 | var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');
416 |
417 | x.hide();
418 |
419 | i
420 | .show()
421 | .focus();
422 |
423 | })
424 | .on('keypress', function(event) {
425 |
426 | event.preventDefault();
427 | x.val('');
428 |
429 | });
430 |
431 | });
432 |
433 | // Events.
434 | $this
435 | .on('submit', function() {
436 |
437 | $this.find('input[type=text],input[type=password],textarea')
438 | .each(function(event) {
439 |
440 | var i = $(this);
441 |
442 | if (i.attr('name').match(/-polyfill-field$/))
443 | i.attr('name', '');
444 |
445 | if (i.val() == i.attr('placeholder')) {
446 |
447 | i.removeClass('polyfill-placeholder');
448 | i.val('');
449 |
450 | }
451 |
452 | });
453 |
454 | })
455 | .on('reset', function(event) {
456 |
457 | event.preventDefault();
458 |
459 | $this.find('select')
460 | .val($('option:first').val());
461 |
462 | $this.find('input,textarea')
463 | .each(function() {
464 |
465 | var i = $(this),
466 | x;
467 |
468 | i.removeClass('polyfill-placeholder');
469 |
470 | switch (this.type) {
471 |
472 | case 'submit':
473 | case 'reset':
474 | break;
475 |
476 | case 'password':
477 | i.val(i.attr('defaultValue'));
478 |
479 | x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
480 |
481 | if (i.val() == '') {
482 | i.hide();
483 | x.show();
484 | }
485 | else {
486 | i.show();
487 | x.hide();
488 | }
489 |
490 | break;
491 |
492 | case 'checkbox':
493 | case 'radio':
494 | i.attr('checked', i.attr('defaultValue'));
495 | break;
496 |
497 | case 'text':
498 | case 'textarea':
499 | i.val(i.attr('defaultValue'));
500 |
501 | if (i.val() == '') {
502 | i.addClass('polyfill-placeholder');
503 | i.val(i.attr('placeholder'));
504 | }
505 |
506 | break;
507 |
508 | default:
509 | i.val(i.attr('defaultValue'));
510 | break;
511 |
512 | }
513 | });
514 |
515 | });
516 |
517 | return $this;
518 |
519 | };
520 |
521 | /**
522 | * Moves elements to/from the first positions of their respective parents.
523 | * @param {jQuery} $elements Elements (or selector) to move.
524 | * @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
525 | */
526 | $.prioritize = function($elements, condition) {
527 |
528 | var key = '__prioritize';
529 |
530 | // Expand $elements if it's not already a jQuery object.
531 | if (typeof $elements != 'jQuery')
532 | $elements = $($elements);
533 |
534 | // Step through elements.
535 | $elements.each(function() {
536 |
537 | var $e = $(this), $p,
538 | $parent = $e.parent();
539 |
540 | // No parent? Bail.
541 | if ($parent.length == 0)
542 | return;
543 |
544 | // Not moved? Move it.
545 | if (!$e.data(key)) {
546 |
547 | // Condition is false? Bail.
548 | if (!condition)
549 | return;
550 |
551 | // Get placeholder (which will serve as our point of reference for when this element needs to move back).
552 | $p = $e.prev();
553 |
554 | // Couldn't find anything? Means this element's already at the top, so bail.
555 | if ($p.length == 0)
556 | return;
557 |
558 | // Move element to top of parent.
559 | $e.prependTo($parent);
560 |
561 | // Mark element as moved.
562 | $e.data(key, $p);
563 |
564 | }
565 |
566 | // Moved already?
567 | else {
568 |
569 | // Condition is true? Bail.
570 | if (condition)
571 | return;
572 |
573 | $p = $e.data(key);
574 |
575 | // Move element back to its original location (using our placeholder).
576 | $e.insertAfter($p);
577 |
578 | // Unmark element as moved.
579 | $e.removeData(key);
580 |
581 | }
582 |
583 | });
584 |
585 | };
586 |
587 | })(jQuery);
--------------------------------------------------------------------------------
/static/sass/base/_page.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Basic */
8 |
9 | // MSIE: Required for IEMobile.
10 | @-ms-viewport {
11 | width: device-width;
12 | }
13 |
14 | // MSIE: Prevents scrollbar from overlapping content.
15 | body {
16 | -ms-overflow-style: scrollbar;
17 | }
18 |
19 | // Ensures page width is always >=320px.
20 | @include breakpoint('<=xsmall') {
21 | html, body {
22 | min-width: 320px;
23 | }
24 | }
25 |
26 | // Set box model to border-box.
27 | // Based on css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice
28 | html {
29 | box-sizing: border-box;
30 | }
31 |
32 | *, *:before, *:after {
33 | box-sizing: inherit;
34 | }
35 |
36 | body {
37 | background: _palette(bg);
38 |
39 | // Stops initial animations until page loads.
40 | &.is-preload {
41 | *, *:before, *:after {
42 | @include vendor('animation', 'none !important');
43 | @include vendor('transition', 'none !important');
44 | }
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/static/sass/base/_reset.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | // Reset.
8 | // Based on meyerweb.com/eric/tools/css/reset (v2.0 | 20110126 | License: public domain)
9 |
10 | html, body, div, span, applet, object,
11 | iframe, h1, h2, h3, h4, h5, h6, p, blockquote,
12 | pre, a, abbr, acronym, address, big, cite,
13 | code, del, dfn, em, img, ins, kbd, q, s, samp,
14 | small, strike, strong, sub, sup, tt, var, b,
15 | u, i, center, dl, dt, dd, ol, ul, li, fieldset,
16 | form, label, legend, table, caption, tbody,
17 | tfoot, thead, tr, th, td, article, aside,
18 | canvas, details, embed, figure, figcaption,
19 | footer, header, hgroup, menu, nav, output, ruby,
20 | section, summary, time, mark, audio, video {
21 | margin: 0;
22 | padding: 0;
23 | border: 0;
24 | font-size: 100%;
25 | font: inherit;
26 | vertical-align: baseline;
27 | }
28 |
29 | article, aside, details, figcaption, figure,
30 | footer, header, hgroup, menu, nav, section {
31 | display: block;
32 | }
33 |
34 | body {
35 | line-height: 1;
36 | }
37 |
38 | ol, ul {
39 | list-style:none;
40 | }
41 |
42 | blockquote, q {
43 | quotes: none;
44 |
45 | &:before,
46 | &:after {
47 | content: '';
48 | content: none;
49 | }
50 | }
51 |
52 | table {
53 | border-collapse: collapse;
54 | border-spacing: 0;
55 | }
56 |
57 | body {
58 | -webkit-text-size-adjust: none;
59 | }
60 |
61 | mark {
62 | background-color: transparent;
63 | color: inherit;
64 | }
65 |
66 | input::-moz-focus-inner {
67 | border: 0;
68 | padding: 0;
69 | }
70 |
71 | input, select, textarea {
72 | -moz-appearance: none;
73 | -webkit-appearance: none;
74 | -ms-appearance: none;
75 | appearance: none;
76 | }
--------------------------------------------------------------------------------
/static/sass/base/_typography.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Type */
8 |
9 | body, input, select, textarea {
10 | color: _palette(fg);
11 | font-family: _font(family);
12 | font-size: 16pt;
13 | font-weight: _font(weight);
14 | line-height: 1.75;
15 |
16 | @include breakpoint('<=xlarge') {
17 | font-size: 14pt;
18 | }
19 |
20 | @include breakpoint('<=large') {
21 | font-size: 12pt;
22 | }
23 | }
24 |
25 | a {
26 | @include vendor('transition', (
27 | 'border-bottom-color #{_duration(transition)} ease',
28 | 'color #{_duration(transition)} ease'
29 | ));
30 | text-decoration: none;
31 | color: _palette(fg);
32 | border-bottom: dotted 1px transparentize(_palette(fg), 0.5);
33 |
34 | &:hover {
35 | border-bottom-color: transparent;
36 | color: _palette(accent1) !important;
37 | }
38 | }
39 |
40 | strong, b {
41 | color: _palette(fg-bold);
42 | font-weight: _font(weight-bold);
43 | }
44 |
45 | em, i {
46 | font-style: italic;
47 | }
48 |
49 | p {
50 | margin: 0 0 _size(element-margin) 0;
51 | }
52 |
53 | h1 {
54 | font-size: 2.75em;
55 | color: _palette(fg-bold);
56 | font-weight: _font(weight-bold-alt);
57 | line-height: 1.3;
58 | margin: 0 0 (_size(element-margin) * 0.5) 0;
59 | letter-spacing: _font(letter-spacing-alt);
60 |
61 | a {
62 | color: inherit;
63 | }
64 |
65 | @include breakpoint('<=small') {
66 | font-size: 2em;
67 | margin: 0 0 (_size(element-margin) * 0.5) 0;
68 | }
69 |
70 | @include breakpoint('<=xxsmall') {
71 | font-size: 1.75em;
72 | }
73 | }
74 |
75 | h2, h3, h4, h5, h6 {
76 | color: _palette(fg-bold);
77 | font-weight: _font(weight-bold);
78 | line-height: 1.5;
79 | margin: 0 0 (_size(element-margin) * 1) 0;
80 | text-transform: uppercase;
81 | letter-spacing: _font(letter-spacing);
82 |
83 | a {
84 | color: inherit;
85 | }
86 | }
87 |
88 | h2 {
89 | font-size: 1.1em;
90 | }
91 |
92 | h3 {
93 | font-size: 1em;
94 | }
95 |
96 | h4 {
97 | font-size: 0.8em;
98 | }
99 |
100 | h5 {
101 | font-size: 0.8em;
102 | }
103 |
104 | h6 {
105 | font-size: 0.8em;
106 | }
107 |
108 | @include breakpoint('<=medium') {
109 | h1, h2, h3, h4, h5, h6 {
110 | br {
111 | display: none;
112 | }
113 | }
114 | }
115 |
116 | @include breakpoint('<=small') {
117 | h2 {
118 | font-size: 1em;
119 | }
120 |
121 | h3 {
122 | font-size: 0.8em;
123 | }
124 | }
125 |
126 | sub {
127 | font-size: 0.8em;
128 | position: relative;
129 | top: 0.5em;
130 | }
131 |
132 | sup {
133 | font-size: 0.8em;
134 | position: relative;
135 | top: -0.5em;
136 | }
137 |
138 | blockquote {
139 | border-left: solid (_size(border-width) * 4) _palette(border);
140 | font-style: italic;
141 | margin: 0 0 _size(element-margin) 0;
142 | padding: (_size(element-margin) / 4) 0 (_size(element-margin) / 4) _size(element-margin);
143 | }
144 |
145 | code {
146 | background: _palette(border-bg);
147 | border-radius: _size(border-radius);
148 | border: solid _size(border-width) _palette(border);
149 | font-family: _font(family-fixed);
150 | font-size: 0.9em;
151 | margin: 0 0.25em;
152 | padding: 0.25em 0.65em;
153 | }
154 |
155 | pre {
156 | -webkit-overflow-scrolling: touch;
157 | font-family: _font(family-fixed);
158 | font-size: 0.9em;
159 | margin: 0 0 _size(element-margin) 0;
160 |
161 | code {
162 | display: block;
163 | line-height: 1.75;
164 | padding: 1em 1.5em;
165 | overflow-x: auto;
166 | }
167 | }
168 |
169 | hr {
170 | border: 0;
171 | border-bottom: solid _size(border-width) _palette(border);
172 | margin: _size(element-margin) 0;
173 |
174 | &.major {
175 | margin: (_size(element-margin) * 1.5) 0;
176 | }
177 | }
178 |
179 | .align-left {
180 | text-align: left;
181 | }
182 |
183 | .align-center {
184 | text-align: center;
185 | }
186 |
187 | .align-right {
188 | text-align: right;
189 | }
--------------------------------------------------------------------------------
/static/sass/components/_actions.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Actions */
8 |
9 | ul.actions {
10 | @include vendor('display', 'flex');
11 | cursor: default;
12 | list-style: none;
13 | margin-left: (_size(element-margin) * -0.5);
14 | padding-left: 0;
15 |
16 | li {
17 | padding: 0 0 0 (_size(element-margin) * 0.5);
18 | vertical-align: middle;
19 | }
20 |
21 | &.special {
22 | @include vendor('justify-content', 'center');
23 | width: 100%;
24 | margin-left: 0;
25 |
26 | li {
27 | &:first-child {
28 | padding-left: 0;
29 | }
30 | }
31 | }
32 |
33 | &.stacked {
34 | @include vendor('flex-direction', 'column');
35 | margin-left: 0;
36 |
37 | li {
38 | padding: (_size(element-margin) * 0.65) 0 0 0;
39 |
40 | &:first-child {
41 | padding-top: 0;
42 | }
43 | }
44 | }
45 |
46 | &.fit {
47 | width: calc(100% + #{_size(element-margin) * 0.5});
48 |
49 | li {
50 | @include vendor('flex-grow', '1');
51 | @include vendor('flex-shrink', '1');
52 | width: 100%;
53 |
54 | > * {
55 | width: 100%;
56 | }
57 | }
58 |
59 | &.stacked {
60 | width: 100%;
61 | }
62 | }
63 |
64 | @include breakpoint('<=xsmall') {
65 | &:not(.fixed) {
66 | @include vendor('flex-direction', 'column');
67 | margin-left: 0;
68 | width: 100% !important;
69 |
70 | li {
71 | @include vendor('flex-grow', '1');
72 | @include vendor('flex-shrink', '1');
73 | padding: (_size(element-margin) * 0.5) 0 0 0;
74 | text-align: center;
75 | width: 100%;
76 |
77 | > * {
78 | width: 100%;
79 | }
80 |
81 | &:first-child {
82 | padding-top: 0;
83 | }
84 |
85 | input[type="submit"],
86 | input[type="reset"],
87 | input[type="button"],
88 | button,
89 | .button {
90 | width: 100%;
91 |
92 | &.icon {
93 | &:before {
94 | margin-left: -0.5rem;
95 | }
96 | }
97 | }
98 | }
99 | }
100 | }
101 | }
--------------------------------------------------------------------------------
/static/sass/components/_box.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Box */
8 |
9 | .box {
10 | border-radius: _size(border-radius);
11 | border: solid _size(border-width) _palette(border);
12 | margin-bottom: _size(element-margin);
13 | padding: 1.5em;
14 |
15 | > :last-child,
16 | > :last-child > :last-child,
17 | > :last-child > :last-child > :last-child {
18 | margin-bottom: 0;
19 | }
20 |
21 | &.alt {
22 | border: 0;
23 | border-radius: 0;
24 | padding: 0;
25 | }
26 | }
--------------------------------------------------------------------------------
/static/sass/components/_button.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Button */
8 |
9 | input[type="submit"],
10 | input[type="reset"],
11 | input[type="button"],
12 | button,
13 | .button {
14 | @include vendor('appearance', 'none');
15 | @include vendor('transition', (
16 | 'background-color #{_duration(transition)} ease-in-out',
17 | 'color #{_duration(transition)} ease-in-out',
18 | 'box-shadow #{_duration(transition)} ease-in-out'
19 | ));
20 | background-color: transparent;
21 | border-radius: _size(border-radius);
22 | border: 0;
23 | box-shadow: inset 0 0 0 (_size(border-width) * 2) _palette(fg);
24 | color: _palette(fg) !important;
25 | cursor: pointer;
26 | display: inline-block;
27 | font-size: 0.8em;
28 | font-weight: _font(weight-bold);
29 | height: 3.5em;
30 | letter-spacing: _font(letter-spacing);
31 | line-height: 3.45em;
32 | overflow: hidden;
33 | padding: 0 1.25em 0 #{1.25em + _font(letter-spacing)};
34 | text-align: center;
35 | text-decoration: none;
36 | text-overflow: ellipsis;
37 | text-transform: uppercase;
38 | white-space: nowrap;
39 |
40 | &.icon {
41 | &:before {
42 | margin-right: 0.5em;
43 | }
44 | }
45 |
46 | &.fit {
47 | width: 100%;
48 | }
49 |
50 | &:hover {
51 | color: _palette(accent1) !important;
52 | box-shadow: inset 0 0 0 (_size(border-width) * 2) _palette(accent1);
53 | }
54 |
55 | &:active {
56 | background-color: transparentize(_palette(accent1), 0.9);
57 | }
58 |
59 | &.small {
60 | font-size: 0.6em;
61 | }
62 |
63 | &.large {
64 | font-size: 1em;
65 | }
66 |
67 | &.primary {
68 | box-shadow: none;
69 | background-color: _palette(fg);
70 | color: _palette(bg) !important;
71 |
72 | &:hover {
73 | background-color: _palette(accent1);
74 | }
75 |
76 | &:active {
77 | background-color: darken(_palette(accent1), 8);
78 | }
79 | }
80 |
81 | &.disabled,
82 | &:disabled {
83 | @include vendor('pointer-events', 'none');
84 | opacity: 0.25;
85 | }
86 | }
--------------------------------------------------------------------------------
/static/sass/components/_form.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Form */
8 |
9 | form {
10 | margin: 0 0 _size(element-margin) 0;
11 | overflow-x: hidden;
12 |
13 | > :last-child {
14 | margin-bottom: 0;
15 | }
16 |
17 | > .fields {
18 | $gutter: (_size(element-margin) * 0.75);
19 |
20 | @include vendor('display', 'flex');
21 | @include vendor('flex-wrap', 'wrap');
22 | width: calc(100% + #{$gutter * 2});
23 | margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1);
24 |
25 | > .field {
26 | @include vendor('flex-grow', '0');
27 | @include vendor('flex-shrink', '0');
28 | padding: $gutter 0 0 $gutter;
29 | width: calc(100% - #{$gutter * 1});
30 |
31 | &.half {
32 | width: calc(50% - #{$gutter * 0.5});
33 | }
34 |
35 | &.third {
36 | width: calc(#{100% / 3} - #{$gutter * (1 / 3)});
37 | }
38 |
39 | &.quarter {
40 | width: calc(25% - #{$gutter * 0.25});
41 | }
42 | }
43 | }
44 |
45 | @include breakpoint('<=xsmall') {
46 | > .fields {
47 | $gutter: (_size(element-margin) * 0.75);
48 |
49 | width: calc(100% + #{$gutter * 2});
50 | margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1);
51 |
52 | > .field {
53 | padding: $gutter 0 0 $gutter;
54 | width: calc(100% - #{$gutter * 1});
55 |
56 | &.half {
57 | width: calc(100% - #{$gutter * 1});
58 | }
59 |
60 | &.third {
61 | width: calc(100% - #{$gutter * 1});
62 | }
63 |
64 | &.quarter {
65 | width: calc(100% - #{$gutter * 1});
66 | }
67 | }
68 | }
69 | }
70 | }
71 |
72 | label {
73 | display: block;
74 | font-size: 0.9em;
75 | font-weight: _font(weight-bold);
76 | margin: 0 0 (_size(element-margin) * 0.5) 0;
77 | }
78 |
79 | input[type="text"],
80 | input[type="password"],
81 | input[type="email"],
82 | input[type="tel"],
83 | select,
84 | textarea {
85 | @include vendor('appearance', 'none');
86 | background-color: transparent;
87 | border: none;
88 | border-radius: 0;
89 | border-bottom: solid _size(border-width) _palette(border);
90 | color: inherit;
91 | display: block;
92 | outline: 0;
93 | padding: 0;
94 | text-decoration: none;
95 | width: 100%;
96 |
97 | &:invalid {
98 | box-shadow: none;
99 | }
100 |
101 | &:focus {
102 | border-bottom-color: _palette(accent1);
103 | box-shadow: inset 0 -1px 0 0 _palette(accent1);
104 | }
105 | }
106 |
107 | select {
108 | background-image: svg-url("
");
109 | background-size: 1.25rem;
110 | background-repeat: no-repeat;
111 | background-position: calc(100% - 1rem) center;
112 | height: _size(element-height);
113 | padding-right: _size(element-height);
114 | text-overflow: ellipsis;
115 |
116 | option {
117 | color: _palette(fg-bold);
118 | background: _palette(bg);
119 | }
120 |
121 | &:focus {
122 | &::-ms-value {
123 | background-color: transparent;
124 | }
125 | }
126 |
127 | &::-ms-expand {
128 | display: none;
129 | }
130 | }
131 |
132 | input[type="text"],
133 | input[type="password"],
134 | input[type="email"],
135 | select {
136 | height: _size(element-height);
137 | }
138 |
139 | textarea {
140 | padding: 0;
141 | min-height: (_size(element-height) * 1.25);
142 | }
143 |
144 | input[type="checkbox"],
145 | input[type="radio"], {
146 | @include vendor('appearance', 'none');
147 | display: block;
148 | float: left;
149 | margin-right: -2em;
150 | opacity: 0;
151 | width: 1em;
152 | z-index: -1;
153 |
154 | & + label {
155 | @include icon(false, solid);
156 | color: _palette(fg);
157 | cursor: pointer;
158 | display: inline-block;
159 | font-size: 1em;
160 | font-weight: _font(weight);
161 | padding-left: (_size(element-height) * 0.6) + 0.75em;
162 | padding-right: 0.75em;
163 | position: relative;
164 |
165 | &:before {
166 | border-radius: _size(border-radius);
167 | border: solid _size(border-width) _palette(border);
168 | content: '';
169 | display: inline-block;
170 | font-size: 0.8em;
171 | height: (_size(element-height) * 0.75);
172 | left: 0;
173 | line-height: (_size(element-height) * 0.75);
174 | position: absolute;
175 | text-align: center;
176 | top: 0;
177 | width: (_size(element-height) * 0.75);
178 | }
179 | }
180 |
181 | &:checked + label {
182 | &:before {
183 | background: _palette(fg);
184 | border-color: _palette(fg);
185 | color: _palette(bg);
186 | content: '\f00c';
187 | }
188 | }
189 |
190 | &:focus + label {
191 | &:before {
192 | border-color: _palette(accent1);
193 | box-shadow: 0 0 0 _size(border-width) _palette(accent1);
194 | }
195 | }
196 | }
197 |
198 | input[type="checkbox"] {
199 | & + label {
200 | &:before {
201 | border-radius: _size(border-radius);
202 | }
203 | }
204 | }
205 |
206 | input[type="radio"] {
207 | & + label {
208 | &:before {
209 | border-radius: 100%;
210 | }
211 | }
212 | }
--------------------------------------------------------------------------------
/static/sass/components/_icon.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Icon */
8 |
9 | .icon {
10 | @include icon;
11 | border-bottom: none;
12 | position: relative;
13 |
14 | > .label {
15 | display: none;
16 | }
17 |
18 | &:before {
19 | line-height: inherit;
20 | }
21 |
22 | &.solid {
23 | &:before {
24 | font-weight: 900;
25 | }
26 | }
27 |
28 | &.brands {
29 | &:before {
30 | font-family: 'Font Awesome 5 Brands';
31 | }
32 | }
33 |
34 | &.style1 {
35 | }
36 |
37 | &.style2 {
38 | @include vendor('transition', (
39 | 'background-color #{_duration(transition)} ease-in-out',
40 | 'color #{_duration(transition)} ease-in-out',
41 | 'border-color #{_duration(transition)} ease-in-out'
42 | ));
43 | background-color: transparent;
44 | border: solid 1px _palette(border);
45 | border-radius: _size(border-radius);
46 | width: 2.65em;
47 | height: 2.65em;
48 | display: inline-block;
49 | text-align: center;
50 | line-height: 2.65em;
51 | color: inherit;
52 |
53 | &:before {
54 | font-size: 1.1em;
55 | }
56 |
57 | &:hover {
58 | color: _palette(accent1);
59 | border-color: _palette(accent1);
60 | }
61 |
62 | &:active {
63 | background-color: transparentize(_palette(accent1), 0.9);
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/static/sass/components/_icons.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Icons */
8 |
9 | ul.icons {
10 | cursor: default;
11 | list-style: none;
12 | padding-left: 0;
13 | margin: -1em 0 _size(element-margin) -1em;
14 |
15 | li {
16 | display: inline-block;
17 | padding: 1em 0 0 1em;
18 | }
19 | }
--------------------------------------------------------------------------------
/static/sass/components/_image.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Image */
8 |
9 | .image {
10 | border-radius: _size(border-radius);
11 | border: 0;
12 | display: inline-block;
13 | position: relative;
14 |
15 | img {
16 | border-radius: _size(border-radius);
17 | display: block;
18 | }
19 |
20 | &.left,
21 | &.right {
22 | max-width: 40%;
23 |
24 | img {
25 | width: 100%;
26 | }
27 | }
28 |
29 | &.left {
30 | float: left;
31 | padding: 0 1.5em 1em 0;
32 | top: 0.25em;
33 | }
34 |
35 | &.right {
36 | float: right;
37 | padding: 0 0 1em 1.5em;
38 | top: 0.25em;
39 | }
40 |
41 | &.fit {
42 | display: block;
43 | margin: 0 0 _size(element-margin) 0;
44 | width: 100%;
45 |
46 | img {
47 | width: 100%;
48 | }
49 | }
50 |
51 | &.main {
52 | display: block;
53 | margin: 0 0 (_size(element-margin) * 1.5) 0;
54 | width: 100%;
55 |
56 | img {
57 | width: 100%;
58 | }
59 |
60 | @include breakpoint('<=small') {
61 | margin: 0 0 _size(element-margin) 0;
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/static/sass/components/_list.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* List */
8 |
9 | ol {
10 | list-style: decimal;
11 | margin: 0 0 _size(element-margin) 0;
12 | padding-left: 1.25em;
13 |
14 | li {
15 | padding-left: 0.25em;
16 | }
17 | }
18 |
19 | ul {
20 | list-style: disc;
21 | margin: 0 0 _size(element-margin) 0;
22 | padding-left: 1em;
23 |
24 | li {
25 | padding-left: 0.5em;
26 | }
27 |
28 | &.alt {
29 | list-style: none;
30 | padding-left: 0;
31 |
32 | li {
33 | border-top: solid _size(border-width) _palette(border);
34 | padding: 0.5em 0;
35 |
36 | &:first-child {
37 | border-top: 0;
38 | padding-top: 0;
39 | }
40 | }
41 | }
42 | }
43 |
44 | dl {
45 | margin: 0 0 _size(element-margin) 0;
46 |
47 | dt {
48 | display: block;
49 | font-weight: _font(weight-bold);
50 | margin: 0 0 (_size(element-margin) * 0.5) 0;
51 | }
52 |
53 | dd {
54 | margin-left: _size(element-margin);
55 | }
56 | }
--------------------------------------------------------------------------------
/static/sass/components/_row.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Row */
8 |
9 | .row {
10 | @include html-grid(2em);
11 |
12 | @include breakpoint('<=xlarge') {
13 | @include html-grid(2em, 'xlarge');
14 | }
15 |
16 | @include breakpoint('<=large') {
17 | @include html-grid(2em, 'large');
18 | }
19 |
20 | @include breakpoint('<=medium') {
21 | @include html-grid(1.5em, 'medium');
22 | }
23 |
24 | @include breakpoint('<=small') {
25 | @include html-grid(1em, 'small');
26 | }
27 |
28 | @include breakpoint('<=xsmall') {
29 | @include html-grid(1em, 'xsmall');
30 | }
31 | }
--------------------------------------------------------------------------------
/static/sass/components/_section.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Section/Article */
8 |
9 | section, article {
10 | &.special {
11 | text-align: center;
12 | }
13 | }
14 |
15 | header {
16 | p {
17 | margin-top: _size(element-margin) * -0.5;
18 | }
19 |
20 | @include breakpoint('<=small') {
21 | p {
22 | margin-top: 0;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/static/sass/components/_table.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Table */
8 |
9 | .table-wrapper {
10 | -webkit-overflow-scrolling: touch;
11 | overflow-x: auto;
12 | }
13 |
14 | table {
15 | margin: 0 0 _size(element-margin) 0;
16 | width: 100%;
17 |
18 | tbody {
19 | tr {
20 | border: solid _size(border-width) _palette(border);
21 | border-left: 0;
22 | border-right: 0;
23 |
24 | &:nth-child(2n + 1) {
25 | background-color: _palette(border-bg);
26 | }
27 | }
28 | }
29 |
30 | td {
31 | padding: 0.75em 0.75em;
32 | }
33 |
34 | th {
35 | color: _palette(fg-bold);
36 | font-size: 0.9em;
37 | font-weight: _font(weight-bold);
38 | padding: 0 0.75em 0.75em 0.75em;
39 | text-align: left;
40 | }
41 |
42 | thead {
43 | border-bottom: solid (_size(border-width) * 2) _palette(border);
44 | }
45 |
46 | tfoot {
47 | border-top: solid (_size(border-width) * 2) _palette(border);
48 | }
49 |
50 | &.alt {
51 | border-collapse: separate;
52 |
53 | tbody {
54 | tr {
55 | td {
56 | border: solid _size(border-width) _palette(border);
57 | border-left-width: 0;
58 | border-top-width: 0;
59 |
60 | &:first-child {
61 | border-left-width: _size(border-width);
62 | }
63 | }
64 |
65 | &:first-child {
66 | td {
67 | border-top-width: _size(border-width);
68 | }
69 | }
70 | }
71 | }
72 |
73 | thead {
74 | border-bottom: 0;
75 | }
76 |
77 | tfoot {
78 | border-top: 0;
79 | }
80 | }
81 | }
--------------------------------------------------------------------------------
/static/sass/components/_tiles.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Tiles */
8 |
9 | .tiles {
10 | $gutter: _size(gutter);
11 | $duration: 0.5s;
12 | $ease: 'ease';
13 |
14 | @include vendor('display', 'flex');
15 | @include vendor('flex-wrap', 'wrap');
16 | postiion: relative;
17 | margin: ($gutter * -1) 0 0 ($gutter * -1);
18 |
19 | article {
20 | @include vendor('transition', (
21 | 'transform #{$duration} #{$ease}',
22 | 'opacity #{$duration} #{$ease}'
23 | ));
24 | position: relative;
25 | width: calc(#{(100% / 3)} - #{$gutter * 1});
26 | margin: $gutter 0 0 $gutter;
27 |
28 | > .image {
29 | @include vendor('transition', 'transform #{$duration} #{$ease}');
30 | position: relative;
31 | display: block;
32 | width: 100%;
33 | border-radius: _size(border-radius);
34 | overflow: hidden;
35 |
36 | img {
37 | display: block;
38 | width: 100%;
39 | }
40 |
41 | &:before {
42 | @include vendor('pointer-events', 'none');
43 | @include vendor('transition', (
44 | 'background-color #{$duration} #{$ease}',
45 | 'opacity #{$duration} #{$ease}'
46 | ));
47 | content: '';
48 | display: block;
49 | position: absolute;
50 | top: 0;
51 | left: 0;
52 | width: 100%;
53 | height: 100%;
54 | opacity: 1.0;
55 | z-index: 1;
56 | opacity: 0.8;
57 | }
58 |
59 | &:after {
60 | @include vendor('pointer-events', 'none');
61 | @include vendor('transition', 'opacity #{$duration} #{$ease}');
62 | content: '';
63 | display: block;
64 | position: absolute;
65 | top: 0;
66 | left: 0;
67 | width: 100%;
68 | height: 100%;
69 | background-image: svg-url('
');
70 | background-position: center;
71 | background-repeat: no-repeat;
72 | background-size: 100% 100%;
73 | opacity: 0.25;
74 | z-index: 2;
75 | }
76 | }
77 |
78 | > a {
79 | @include vendor('display', 'flex');
80 | @include vendor('flex-direction', 'column');
81 | @include vendor('align-items', 'center');
82 | @include vendor('justify-content', 'center');
83 | @include vendor('transition', (
84 | 'background-color #{$duration} #{$ease}',
85 | 'transform #{$duration} #{$ease}'
86 | ));
87 | position: absolute;
88 | top: 0;
89 | left: 0;
90 | width: 100%;
91 | height: 100%;
92 | padding: 1em;
93 | border-radius: _size(border-radius);
94 | border-bottom: 0;
95 | color: _palette(fg-accent);
96 | text-align: center;
97 | text-decoration: none;
98 | z-index: 3;
99 |
100 | > :last-child {
101 | margin: 0;
102 | }
103 |
104 | &:hover {
105 | color: _palette(fg-accent) !important;
106 | }
107 |
108 | h2 {
109 | margin: 0;
110 | }
111 |
112 | .content {
113 | @include vendor('transition', (
114 | 'max-height #{$duration} #{$ease}',
115 | 'opacity #{$duration} #{$ease}'
116 | ));
117 | width: 100%;
118 | max-height: 0;
119 | line-height: 1.5;
120 | margin-top: 0.35em;
121 | opacity: 0;
122 |
123 | > :last-child {
124 | margin-bottom: 0;
125 | }
126 | }
127 | }
128 |
129 | &.style1 {
130 | > .image:before {
131 | background-color: _palette(accent1);
132 | }
133 | }
134 |
135 | &.style2 {
136 | > .image:before {
137 | background-color: _palette(accent2);
138 | }
139 | }
140 |
141 | &.style3 {
142 | > .image:before {
143 | background-color: _palette(accent3);
144 | }
145 | }
146 |
147 | &.style4 {
148 | > .image:before {
149 | background-color: _palette(accent4);
150 | }
151 | }
152 |
153 | &.style5 {
154 | > .image:before {
155 | background-color: _palette(accent5);
156 | }
157 | }
158 |
159 | &.style6 {
160 | > .image:before {
161 | background-color: _palette(accent6);
162 | }
163 | }
164 |
165 | body:not(.is-touch) & {
166 | &:hover {
167 | > .image {
168 | @include vendor('transform', 'scale(1.1)');
169 |
170 | &:before {
171 | background-color: _palette(bg-accent);
172 | opacity: 0.35;
173 | }
174 |
175 | &:after {
176 | opacity: 0;
177 | }
178 | }
179 |
180 | .content {
181 | max-height: 15em;
182 | opacity: 1;
183 | }
184 | }
185 | }
186 | }
187 |
188 | * + & {
189 | margin-top: _size(element-margin);
190 | }
191 |
192 | body.is-preload & {
193 | article {
194 | @include vendor('transform', 'scale(0.9)');
195 | opacity: 0;
196 | }
197 | }
198 |
199 | body.is-touch & {
200 | article {
201 | .content {
202 | max-height: 15em;
203 | opacity: 1;
204 | }
205 | }
206 | }
207 |
208 | @include breakpoint('<=large') {
209 | $gutter: _size(gutter) * 0.5;
210 |
211 | margin: ($gutter * -1) 0 0 ($gutter * -1);
212 |
213 | article {
214 | width: calc(#{(100% / 3)} - #{$gutter * 1});
215 | margin: $gutter 0 0 $gutter;
216 | }
217 | }
218 |
219 | @include breakpoint('<=medium') {
220 | $gutter: _size(gutter);
221 |
222 | margin: ($gutter * -1) 0 0 ($gutter * -1);
223 |
224 | article {
225 | width: calc(#{(100% / 2)} - #{$gutter * 1});
226 | margin: $gutter 0 0 $gutter;
227 | }
228 | }
229 |
230 | @include breakpoint('<=small') {
231 | $gutter: _size(gutter) * 0.5;
232 |
233 | margin: ($gutter * -1) 0 0 ($gutter * -1);
234 |
235 | article {
236 | width: calc(#{(100% / 2)} - #{$gutter * 1});
237 | margin: $gutter 0 0 $gutter;
238 |
239 | &:hover {
240 | > .image {
241 | @include vendor('transform', 'scale(1.0)');
242 | }
243 | }
244 | }
245 | }
246 |
247 | @include breakpoint('<=xsmall') {
248 | $gutter: _size(gutter) * 0.5;
249 |
250 | margin: 0;
251 |
252 | article {
253 | width: 100%;
254 | margin: $gutter 0 0 0;
255 | }
256 | }
257 | }
258 |
259 |
--------------------------------------------------------------------------------
/static/sass/layout/_footer.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Footer */
8 |
9 | #footer {
10 | $gutter: _size(gutter);
11 |
12 | @include padding(5em, 0, (0, 0, 3em, 0));
13 | background-color: _palette(bg-alt);
14 |
15 | > .inner {
16 | @include vendor('display', 'flex');
17 | @include vendor('flex-wrap', 'wrap');
18 | @include vendor('flex-direction', 'row');
19 |
20 | > * > :last-child {
21 | margin-bottom: 0;
22 | }
23 |
24 | section:nth-child(1) {
25 | width: calc(66% - #{$gutter});
26 | margin-right: $gutter;
27 | }
28 |
29 | section:nth-child(2) {
30 | width: calc(33% - #{$gutter});
31 | margin-left: $gutter;
32 | }
33 |
34 | .copyright {
35 | width: 100%;
36 | padding: 0;
37 | margin-top: 5em;
38 | list-style: none;
39 | font-size: 0.8em;
40 | color: transparentize(_palette(fg), 0.5);
41 |
42 | a {
43 | color: inherit;
44 | }
45 |
46 | li {
47 | display: inline-block;
48 | border-left: solid 1px transparentize(_palette(fg), 0.85);
49 | line-height: 1;
50 | padding: 0 0 0 1em;
51 | margin: 0 0 0 1em;
52 |
53 | &:first-child {
54 | border-left: 0;
55 | padding-left: 0;
56 | margin-left: 0;
57 | }
58 | }
59 | }
60 | }
61 |
62 | @include breakpoint('<=large') {
63 | $gutter: _size(gutter) * 0.5;
64 |
65 | @include padding(5em, 0);
66 |
67 | > .inner {
68 | section:nth-child(1) {
69 | width: calc(66% - #{$gutter});
70 | margin-right: $gutter;
71 | }
72 |
73 | section:nth-child(2) {
74 | width: calc(33% - #{$gutter});
75 | margin-left: $gutter;
76 | }
77 | }
78 | }
79 |
80 | @include breakpoint('<=medium') {
81 | $gutter: _size(gutter);
82 |
83 | > .inner {
84 | section:nth-child(1) {
85 | width: 66%;
86 | margin-right: 0;
87 | }
88 |
89 | section:nth-child(2) {
90 | width: calc(33% - #{$gutter});
91 | margin-left: $gutter;
92 | }
93 | }
94 | }
95 |
96 | @include breakpoint('<=small') {
97 | @include padding(3em, 0);
98 |
99 | > .inner {
100 | @include vendor('flex-direction', 'column');
101 |
102 | section:nth-child(1) {
103 | width: 100%;
104 | margin-right: 0;
105 | margin: 3em 0 0 0;
106 | }
107 |
108 | section:nth-child(2) {
109 | @include vendor('order', '-1');
110 | width: 100%;
111 | margin-left: 0;
112 | }
113 |
114 | .copyright {
115 | margin-top: 3em;
116 | }
117 | }
118 | }
119 |
120 | @include breakpoint('<=xsmall') {
121 | > .inner {
122 | .copyright {
123 | margin-top: 3em;
124 |
125 | li {
126 | border-left: 0;
127 | padding-left: 0;
128 | margin: 0.75em 0 0 0;
129 | display: block;
130 | line-height: inherit;
131 |
132 | &:first-child {
133 | margin-top: 0;
134 | }
135 | }
136 | }
137 | }
138 | }
139 | }
--------------------------------------------------------------------------------
/static/sass/layout/_header.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Header */
8 |
9 | #header {
10 | @include padding(5em, 0, (3em, 0, -5em, 0));
11 |
12 | .logo {
13 | display: block;
14 | border-bottom: 0;
15 | color: inherit;
16 | font-weight: _font(weight-bold);
17 | letter-spacing: _font(letter-spacing);
18 | margin: 0 0 (_size(element-margin) * 1.25) 0;
19 | text-decoration: none;
20 | text-transform: uppercase;
21 | display: inline-block;
22 |
23 | > * {
24 | display: inline-block;
25 | vertical-align: middle;
26 | }
27 |
28 | .symbol {
29 | margin-right: 0.65em;
30 |
31 | img {
32 | display: block;
33 | width: 2em;
34 | height: 2em;
35 | }
36 | }
37 | }
38 |
39 | nav {
40 | position: fixed;
41 | right: 2em;
42 | top: 2em;
43 | z-index: _misc(z-index-base);
44 |
45 | ul {
46 | @include vendor('display', 'flex');
47 | @include vendor('align-items', 'center');
48 | list-style: none;
49 | margin: 0;
50 | padding: 0;
51 |
52 | li {
53 | display: block;
54 | padding: 0;
55 |
56 | a {
57 | display: block;
58 | position: relative;
59 | height: 3em;
60 | line-height: 3em;
61 | padding: 0 1.5em;
62 | background-color: transparentize(_palette(bg), 0.5);
63 | border-radius: _size(border-radius);
64 | border: 0;
65 | font-size: 0.8em;
66 | font-weight: _font(weight-bold);
67 | letter-spacing: _font(letter-spacing);
68 | text-transform: uppercase;
69 | }
70 |
71 | a[href="#menu"] {
72 | -webkit-tap-highlight-color: transparent;
73 | width: 4em;
74 | text-indent: 4em;
75 | font-size: 1em;
76 | overflow: hidden;
77 | padding: 0;
78 | white-space: nowrap;
79 |
80 | &:before, &:after {
81 | @include vendor('transition', 'opacity #{_duration(transition)} ease');
82 | content: '';
83 | display: block;
84 | position: absolute;
85 | top: 0;
86 | left: 0;
87 | width: 100%;
88 | height: 100%;
89 | background-position: center;
90 | background-repeat: no-repeat;
91 | background-size: 2em 2em;
92 | }
93 |
94 | &:before {
95 | background-image: svg-url('
');
96 | opacity: 0;
97 | }
98 |
99 | &:after {
100 | background-image: svg-url('
');
101 | opacity: 1;
102 | }
103 |
104 | &:hover {
105 | &:before {
106 | opacity: 1;
107 | }
108 |
109 | &:after {
110 | opacity: 0;
111 | }
112 | }
113 | }
114 | }
115 | }
116 | }
117 |
118 | @include breakpoint('<=small') {
119 | @include padding(3em, 0, (1em, 0, -3em, 0));
120 |
121 | nav {
122 | right: 0.5em;
123 | top: 0.5em;
124 |
125 | ul {
126 | li {
127 | a[href="#menu"] {
128 | &:before, &:after {
129 | background-size: 1.5em 1.5em;
130 | }
131 | }
132 | }
133 | }
134 | }
135 | }
136 | }
--------------------------------------------------------------------------------
/static/sass/layout/_main.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Main */
8 |
9 | #main {
10 | @include padding(5em, 0, (-5em, 0, 3em, 0));
11 |
12 | @include breakpoint('<=small') {
13 | @include padding(3em, 0, (-3em, 0, 3em, 0));
14 | }
15 | }
--------------------------------------------------------------------------------
/static/sass/layout/_menu.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Menu */
8 |
9 | #wrapper {
10 | @include vendor('transition', 'opacity #{_duration(menu)} ease');
11 | opacity: 1;
12 | }
13 |
14 | #menu {
15 | @include vendor('transform', 'translateX(#{_size(menu)})');
16 | @include vendor('transition', ('transform #{_duration(menu)} ease', 'visibility #{_duration(menu)}'));
17 | position: fixed;
18 | top: 0;
19 | right: 0;
20 | width: _size(menu);
21 | max-width: 80%;
22 | height: 100%;
23 | -webkit-overflow-scrolling: touch;
24 | background: _palette(fg);
25 | color: _palette(bg);
26 | cursor: default;
27 | visibility: hidden;
28 | z-index: _misc(z-index-base) + 2;
29 |
30 | > .inner {
31 | @include vendor('transition', 'opacity #{_duration(menu)} ease');
32 | -webkit-overflow-scrolling: touch;
33 | position: absolute;
34 | top: 0;
35 | left: 0;
36 | width: 100%;
37 | height: 100%;
38 | padding: 2.75em;
39 | opacity: 0;
40 | overflow-y: auto;
41 |
42 | > ul {
43 | list-style: none;
44 | margin: 0 0 (_size(element-margin) * 0.5) 0;
45 | padding: 0;
46 |
47 | > li {
48 | padding: 0;
49 | border-top: solid 1px transparentize(_palette(bg), 0.85);
50 |
51 | a {
52 | display: block;
53 | padding: 1em 0;
54 | line-height: 1.5;
55 | border: 0;
56 | color: inherit;
57 | }
58 |
59 | &:first-child {
60 | border-top: 0;
61 | margin-top: -1em;
62 | }
63 | }
64 | }
65 | }
66 |
67 | > .close {
68 | @include vendor('transition', (
69 | 'opacity #{_duration(menu)} ease',
70 | 'transform #{_duration(menu)} ease'
71 | ));
72 | @include vendor('transform', 'scale(0.25) rotate(180deg)');
73 | -webkit-tap-highlight-color: transparent;
74 | display: block;
75 | position: absolute;
76 | top: 2em;
77 | left: -6em;
78 | width: 6em;
79 | text-indent: 6em;
80 | height: 3em;
81 | border: 0;
82 | font-size: 1em;
83 | opacity: 0;
84 | overflow: hidden;
85 | padding: 0;
86 | white-space: nowrap;
87 |
88 | &:before, &:after {
89 | @include vendor('transition', 'opacity #{_duration(transition)} ease');
90 | content: '';
91 | display: block;
92 | position: absolute;
93 | top: 0;
94 | left: 0;
95 | width: 100%;
96 | height: 100%;
97 | background-position: center;
98 | background-repeat: no-repeat;
99 | background-size: 2em 2em;
100 | }
101 |
102 | &:before {
103 | background-image: svg-url('
');
104 | opacity: 0;
105 | }
106 |
107 | &:after {
108 | background-image: svg-url('
');
109 | opacity: 1;
110 | }
111 |
112 | &:hover {
113 | &:before {
114 | opacity: 1;
115 | }
116 |
117 | &:after {
118 | opacity: 0;
119 | }
120 | }
121 | }
122 |
123 | @include breakpoint('<=small') {
124 | @include vendor('transform', 'translateX(#{_size(menu) * 0.75})');
125 | width: (_size(menu) * 0.75);
126 |
127 | > .inner {
128 | padding: 2.75em 1.5em;
129 | }
130 |
131 | > .close {
132 | top: 0.5em;
133 | left: -4.25em;
134 | width: 4.25em;
135 | text-indent: 4.25em;
136 |
137 | &:before, &:after {
138 | background-size: 1.5em 1.5em;
139 | }
140 | }
141 | }
142 | }
143 |
144 | body.is-menu-visible {
145 | #wrapper {
146 | @include vendor('pointer-events', 'none');
147 | cursor: default;
148 | opacity: 0.25;
149 | }
150 |
151 | #menu {
152 | @include vendor('transform', 'translateX(0)');
153 | visibility: visible;
154 |
155 | > * {
156 | opacity: 1;
157 | }
158 |
159 | .close {
160 | @include vendor('transform', 'scale(1.0) rotate(0deg)');
161 | opacity: 1;
162 | }
163 | }
164 | }
--------------------------------------------------------------------------------
/static/sass/layout/_wrapper.scss:
--------------------------------------------------------------------------------
1 | ///
2 | /// Phantom by HTML5 UP
3 | /// html5up.net | @ajlkn
4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
5 | ///
6 |
7 | /* Wrapper */
8 |
9 | #wrapper {
10 | > * {
11 | > .inner {
12 | $gutter: _size(gutter);
13 |
14 | width: 100%;
15 | max-width: _size(inner);
16 | margin: 0 auto;
17 | padding: 0 $gutter;
18 |
19 | @include breakpoint('<=small') {
20 | $gutter: _size(gutter) * 0.5;
21 |
22 | padding: 0 $gutter;
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/static/sass/libs/_breakpoints.scss:
--------------------------------------------------------------------------------
1 | // breakpoints.scss v1.0 | @ajlkn | MIT licensed */
2 |
3 | // Vars.
4 |
5 | /// Breakpoints.
6 | /// @var {list}
7 | $breakpoints: () !global;
8 |
9 | // Mixins.
10 |
11 | /// Sets breakpoints.
12 | /// @param {map} $x Breakpoints.
13 | @mixin breakpoints($x: ()) {
14 | $breakpoints: $x !global;
15 | }
16 |
17 | /// Wraps @content in a @media block targeting a specific orientation.
18 | /// @param {string} $orientation Orientation.
19 | @mixin orientation($orientation) {
20 | @media screen and (orientation: #{$orientation}) {
21 | @content;
22 | }
23 | }
24 |
25 | /// Wraps @content in a @media block using a given query.
26 | /// @param {string} $query Query.
27 | @mixin breakpoint($query: null) {
28 |
29 | $breakpoint: null;
30 | $op: null;
31 | $media: null;
32 |
33 | // Determine operator, breakpoint.
34 |
35 | // Greater than or equal.
36 | @if (str-slice($query, 0, 2) == '>=') {
37 |
38 | $op: 'gte';
39 | $breakpoint: str-slice($query, 3);
40 |
41 | }
42 |
43 | // Less than or equal.
44 | @elseif (str-slice($query, 0, 2) == '<=') {
45 |
46 | $op: 'lte';
47 | $breakpoint: str-slice($query, 3);
48 |
49 | }
50 |
51 | // Greater than.
52 | @elseif (str-slice($query, 0, 1) == '>') {
53 |
54 | $op: 'gt';
55 | $breakpoint: str-slice($query, 2);
56 |
57 | }
58 |
59 | // Less than.
60 | @elseif (str-slice($query, 0, 1) == '<') {
61 |
62 | $op: 'lt';
63 | $breakpoint: str-slice($query, 2);
64 |
65 | }
66 |
67 | // Not.
68 | @elseif (str-slice($query, 0, 1) == '!') {
69 |
70 | $op: 'not';
71 | $breakpoint: str-slice($query, 2);
72 |
73 | }
74 |
75 | // Equal.
76 | @else {
77 |
78 | $op: 'eq';
79 | $breakpoint: $query;
80 |
81 | }
82 |
83 | // Build media.
84 | @if ($breakpoint and map-has-key($breakpoints, $breakpoint)) {
85 |
86 | $a: map-get($breakpoints, $breakpoint);
87 |
88 | // Range.
89 | @if (type-of($a) == 'list') {
90 |
91 | $x: nth($a, 1);
92 | $y: nth($a, 2);
93 |
94 | // Max only.
95 | @if ($x == null) {
96 |
97 | // Greater than or equal (>= 0 / anything)
98 | @if ($op == 'gte') {
99 | $media: 'screen';
100 | }
101 |
102 | // Less than or equal (<= y)
103 | @elseif ($op == 'lte') {
104 | $media: 'screen and (max-width: ' + $y + ')';
105 | }
106 |
107 | // Greater than (> y)
108 | @elseif ($op == 'gt') {
109 | $media: 'screen and (min-width: ' + ($y + 1) + ')';
110 | }
111 |
112 | // Less than (< 0 / invalid)
113 | @elseif ($op == 'lt') {
114 | $media: 'screen and (max-width: -1px)';
115 | }
116 |
117 | // Not (> y)
118 | @elseif ($op == 'not') {
119 | $media: 'screen and (min-width: ' + ($y + 1) + ')';
120 | }
121 |
122 | // Equal (<= y)
123 | @else {
124 | $media: 'screen and (max-width: ' + $y + ')';
125 | }
126 |
127 | }
128 |
129 | // Min only.
130 | @else if ($y == null) {
131 |
132 | // Greater than or equal (>= x)
133 | @if ($op == 'gte') {
134 | $media: 'screen and (min-width: ' + $x + ')';
135 | }
136 |
137 | // Less than or equal (<= inf / anything)
138 | @elseif ($op == 'lte') {
139 | $media: 'screen';
140 | }
141 |
142 | // Greater than (> inf / invalid)
143 | @elseif ($op == 'gt') {
144 | $media: 'screen and (max-width: -1px)';
145 | }
146 |
147 | // Less than (< x)
148 | @elseif ($op == 'lt') {
149 | $media: 'screen and (max-width: ' + ($x - 1) + ')';
150 | }
151 |
152 | // Not (< x)
153 | @elseif ($op == 'not') {
154 | $media: 'screen and (max-width: ' + ($x - 1) + ')';
155 | }
156 |
157 | // Equal (>= x)
158 | @else {
159 | $media: 'screen and (min-width: ' + $x + ')';
160 | }
161 |
162 | }
163 |
164 | // Min and max.
165 | @else {
166 |
167 | // Greater than or equal (>= x)
168 | @if ($op == 'gte') {
169 | $media: 'screen and (min-width: ' + $x + ')';
170 | }
171 |
172 | // Less than or equal (<= y)
173 | @elseif ($op == 'lte') {
174 | $media: 'screen and (max-width: ' + $y + ')';
175 | }
176 |
177 | // Greater than (> y)
178 | @elseif ($op == 'gt') {
179 | $media: 'screen and (min-width: ' + ($y + 1) + ')';
180 | }
181 |
182 | // Less than (< x)
183 | @elseif ($op == 'lt') {
184 | $media: 'screen and (max-width: ' + ($x - 1) + ')';
185 | }
186 |
187 | // Not (< x and > y)
188 | @elseif ($op == 'not') {
189 | $media: 'screen and (max-width: ' + ($x - 1) + '), screen and (min-width: ' + ($y + 1) + ')';
190 | }
191 |
192 | // Equal (>= x and <= y)
193 | @else {
194 | $media: 'screen and (min-width: ' + $x + ') and (max-width: ' + $y + ')';
195 | }
196 |
197 | }
198 |
199 | }
200 |
201 | // String.
202 | @else {
203 |
204 | // Missing a media type? Prefix with "screen".
205 | @if (str-slice($a, 0, 1) == '(') {
206 | $media: 'screen and ' + $a;
207 | }
208 |
209 | // Otherwise, use as-is.
210 | @else {
211 | $media: $a;
212 | }
213 |
214 | }
215 |
216 | }
217 |
218 | // Output.
219 | @media #{$media} {
220 | @content;
221 | }
222 |
223 | }
--------------------------------------------------------------------------------
/static/sass/libs/_functions.scss:
--------------------------------------------------------------------------------
1 | /// Removes a specific item from a list.
2 | /// @author Hugo Giraudel
3 | /// @param {list} $list List.
4 | /// @param {integer} $index Index.
5 | /// @return {list} Updated list.
6 | @function remove-nth($list, $index) {
7 |
8 | $result: null;
9 |
10 | @if type-of($index) != number {
11 | @warn "$index: #{quote($index)} is not a number for `remove-nth`.";
12 | }
13 | @else if $index == 0 {
14 | @warn "List index 0 must be a non-zero integer for `remove-nth`.";
15 | }
16 | @else if abs($index) > length($list) {
17 | @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
18 | }
19 | @else {
20 |
21 | $result: ();
22 | $index: if($index < 0, length($list) + $index + 1, $index);
23 |
24 | @for $i from 1 through length($list) {
25 |
26 | @if $i != $index {
27 | $result: append($result, nth($list, $i));
28 | }
29 |
30 | }
31 |
32 | }
33 |
34 | @return $result;
35 |
36 | }
37 |
38 | /// Gets a value from a map.
39 | /// @author Hugo Giraudel
40 | /// @param {map} $map Map.
41 | /// @param {string} $keys Key(s).
42 | /// @return {string} Value.
43 | @function val($map, $keys...) {
44 |
45 | @if nth($keys, 1) == null {
46 | $keys: remove-nth($keys, 1);
47 | }
48 |
49 | @each $key in $keys {
50 | $map: map-get($map, $key);
51 | }
52 |
53 | @return $map;
54 |
55 | }
56 |
57 | /// Gets a duration value.
58 | /// @param {string} $keys Key(s).
59 | /// @return {string} Value.
60 | @function _duration($keys...) {
61 | @return val($duration, $keys...);
62 | }
63 |
64 | /// Gets a font value.
65 | /// @param {string} $keys Key(s).
66 | /// @return {string} Value.
67 | @function _font($keys...) {
68 | @return val($font, $keys...);
69 | }
70 |
71 | /// Gets a misc value.
72 | /// @param {string} $keys Key(s).
73 | /// @return {string} Value.
74 | @function _misc($keys...) {
75 | @return val($misc, $keys...);
76 | }
77 |
78 | /// Gets a palette value.
79 | /// @param {string} $keys Key(s).
80 | /// @return {string} Value.
81 | @function _palette($keys...) {
82 | @return val($palette, $keys...);
83 | }
84 |
85 | /// Gets a size value.
86 | /// @param {string} $keys Key(s).
87 | /// @return {string} Value.
88 | @function _size($keys...) {
89 | @return val($size, $keys...);
90 | }
--------------------------------------------------------------------------------
/static/sass/libs/_html-grid.scss:
--------------------------------------------------------------------------------
1 | // html-grid.scss v1.0 | @ajlkn | MIT licensed */
2 |
3 | // Mixins.
4 |
5 | /// Initializes the current element as an HTML grid.
6 | /// @param {mixed} $gutters Gutters (either a single number to set both column/row gutters, or a list to set them individually).
7 | /// @param {mixed} $suffix Column class suffix (optional; either a single suffix or a list).
8 | @mixin html-grid($gutters: 1.5em, $suffix: '') {
9 |
10 | // Initialize.
11 | $cols: 12;
12 | $multipliers: 0, 0.25, 0.5, 1, 1.50, 2.00;
13 | $unit: 100% / $cols;
14 |
15 | // Suffixes.
16 | $suffixes: null;
17 |
18 | @if (type-of($suffix) == 'list') {
19 | $suffixes: $suffix;
20 | }
21 | @else {
22 | $suffixes: ($suffix);
23 | }
24 |
25 | // Gutters.
26 | $guttersCols: null;
27 | $guttersRows: null;
28 |
29 | @if (type-of($gutters) == 'list') {
30 |
31 | $guttersCols: nth($gutters, 1);
32 | $guttersRows: nth($gutters, 2);
33 |
34 | }
35 | @else {
36 |
37 | $guttersCols: $gutters;
38 | $guttersRows: 0;
39 |
40 | }
41 |
42 | // Row.
43 | display: flex;
44 | flex-wrap: wrap;
45 | box-sizing: border-box;
46 | align-items: stretch;
47 |
48 | // Columns.
49 | > * {
50 | box-sizing: border-box;
51 | }
52 |
53 | // Gutters.
54 | &.gtr-uniform {
55 | > * {
56 | > :last-child {
57 | margin-bottom: 0;
58 | }
59 | }
60 | }
61 |
62 | // Alignment.
63 | &.aln-left {
64 | justify-content: flex-start;
65 | }
66 |
67 | &.aln-center {
68 | justify-content: center;
69 | }
70 |
71 | &.aln-right {
72 | justify-content: flex-end;
73 | }
74 |
75 | &.aln-top {
76 | align-items: flex-start;
77 | }
78 |
79 | &.aln-middle {
80 | align-items: center;
81 | }
82 |
83 | &.aln-bottom {
84 | align-items: flex-end;
85 | }
86 |
87 | // Step through suffixes.
88 | @each $suffix in $suffixes {
89 |
90 | // Suffix.
91 | @if ($suffix != '') {
92 | $suffix: '-' + $suffix;
93 | }
94 | @else {
95 | $suffix: '';
96 | }
97 |
98 | // Row.
99 |
100 | // Important.
101 | > .imp#{$suffix} {
102 | order: -1;
103 | }
104 |
105 | // Columns, offsets.
106 | @for $i from 1 through $cols {
107 | > .col-#{$i}#{$suffix} {
108 | width: $unit * $i;
109 | }
110 |
111 | > .off-#{$i}#{$suffix} {
112 | margin-left: $unit * $i;
113 | }
114 | }
115 |
116 | // Step through multipliers.
117 | @each $multiplier in $multipliers {
118 |
119 | // Gutters.
120 | $class: null;
121 |
122 | @if ($multiplier != 1) {
123 | $class: '.gtr-' + ($multiplier * 100);
124 | }
125 |
126 | {$class} {
127 | margin-top: ($guttersRows * $multiplier * -1);
128 | margin-left: ($guttersCols * $multiplier * -1);
129 |
130 | > * {
131 | padding: ($guttersRows * $multiplier) 0 0 ($guttersCols * $multiplier);
132 | }
133 |
134 | // Uniform.
135 | &.gtr-uniform {
136 | margin-top: $guttersCols * $multiplier * -1;
137 |
138 | > * {
139 | padding-top: $guttersCols * $multiplier;
140 | }
141 | }
142 |
143 | }
144 |
145 | }
146 |
147 | }
148 |
149 | }
--------------------------------------------------------------------------------
/static/sass/libs/_mixins.scss:
--------------------------------------------------------------------------------
1 | /// Makes an element's :before pseudoelement a FontAwesome icon.
2 | /// @param {string} $content Optional content value to use.
3 | /// @param {string} $category Optional category to use.
4 | /// @param {string} $where Optional pseudoelement to target (before or after).
5 | @mixin icon($content: false, $category: regular, $where: before) {
6 |
7 | text-decoration: none;
8 |
9 | &:#{$where} {
10 |
11 | @if $content {
12 | content: $content;
13 | }
14 |
15 | -moz-osx-font-smoothing: grayscale;
16 | -webkit-font-smoothing: antialiased;
17 | display: inline-block;
18 | font-style: normal;
19 | font-variant: normal;
20 | text-rendering: auto;
21 | line-height: 1;
22 | text-transform: none !important;
23 |
24 | @if ($category == brands) {
25 | font-family: 'Font Awesome 5 Brands';
26 | }
27 | @elseif ($category == solid) {
28 | font-family: 'Font Awesome 5 Free';
29 | font-weight: 900;
30 | }
31 | @else {
32 | font-family: 'Font Awesome 5 Free';
33 | font-weight: 400;
34 | }
35 |
36 | }
37 |
38 | }
39 |
40 | /// Applies padding to an element, taking the current element-margin value into account.
41 | /// @param {mixed} $tb Top/bottom padding.
42 | /// @param {mixed} $lr Left/right padding.
43 | /// @param {list} $pad Optional extra padding (in the following order top, right, bottom, left)
44 | /// @param {bool} $important If true, adds !important.
45 | @mixin padding($tb, $lr, $pad: (0,0,0,0), $important: null) {
46 |
47 | @if $important {
48 | $important: '!important';
49 | }
50 |
51 | $x: 0.1em;
52 |
53 | @if unit(_size(element-margin)) == 'rem' {
54 | $x: 0.1rem;
55 | }
56 |
57 | padding: ($tb + nth($pad,1)) ($lr + nth($pad,2)) max($x, $tb - _size(element-margin) + nth($pad,3)) ($lr + nth($pad,4)) #{$important};
58 |
59 | }
60 |
61 | /// Encodes a SVG data URL so IE doesn't choke (via codepen.io/jakob-e/pen/YXXBrp).
62 | /// @param {string} $svg SVG data URL.
63 | /// @return {string} Encoded SVG data URL.
64 | @function svg-url($svg) {
65 |
66 | $svg: str-replace($svg, '"', '\'');
67 | $svg: str-replace($svg, '%', '%25');
68 | $svg: str-replace($svg, '<', '%3C');
69 | $svg: str-replace($svg, '>', '%3E');
70 | $svg: str-replace($svg, '&', '%26');
71 | $svg: str-replace($svg, '#', '%23');
72 | $svg: str-replace($svg, '{', '%7B');
73 | $svg: str-replace($svg, '}', '%7D');
74 | $svg: str-replace($svg, ';', '%3B');
75 |
76 | @return url("data:image/svg+xml;charset=utf8,#{$svg}");
77 |
78 | }
--------------------------------------------------------------------------------
/static/sass/libs/_vars.scss:
--------------------------------------------------------------------------------
1 | // Misc.
2 | $misc: (
3 | z-index-base: 10000
4 | );
5 |
6 | // Duration.
7 | $duration: (
8 | menu: 0.45s,
9 | transition: 0.2s
10 | );
11 |
12 | // Size.
13 | $size: (
14 | border-radius: 4px,
15 | border-width: 1px,
16 | element-height: 3em,
17 | element-margin: 2em,
18 | gutter: 2.5em,
19 | field-gutter: 2em,
20 | inner: 68em,
21 | menu: 22em
22 | );
23 |
24 | // Font.
25 | $font: (
26 | family: ('Source Sans Pro', Helvetica, sans-serif),
27 | family-fixed: ('Courier New', monospace),
28 | weight: 300,
29 | weight-bold: 900,
30 | weight-bold-alt: 700,
31 | letter-spacing: 0.35em,
32 | letter-spacing-alt: -0.035em
33 | );
34 |
35 | // Palette.
36 | $palette: (
37 | bg: #ffffff,
38 | bg-accent: #333333,
39 | bg-alt: #f6f6f6,
40 | fg: #585858,
41 | fg-accent: #ffffff,
42 | border: #c9c9c9,
43 | border-bg: rgba(144,144,144,0.075),
44 | accent1: #f2849e,
45 | accent2: #7ecaf6,
46 | accent3: #7bd0c1,
47 | accent4: #c75b9b,
48 | accent5: #ae85ca,
49 | accent6: #8499e7,
50 | );
--------------------------------------------------------------------------------
/static/sass/libs/_vendor.scss:
--------------------------------------------------------------------------------
1 | // vendor.scss v1.0 | @ajlkn | MIT licensed */
2 |
3 | // Vars.
4 |
5 | /// Vendor prefixes.
6 | /// @var {list}
7 | $vendor-prefixes: (
8 | '-moz-',
9 | '-webkit-',
10 | '-ms-',
11 | ''
12 | );
13 |
14 | /// Properties that should be vendorized.
15 | /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org
16 | /// @var {list}
17 | $vendor-properties: (
18 |
19 | // Animation.
20 | 'animation',
21 | 'animation-delay',
22 | 'animation-direction',
23 | 'animation-duration',
24 | 'animation-fill-mode',
25 | 'animation-iteration-count',
26 | 'animation-name',
27 | 'animation-play-state',
28 | 'animation-timing-function',
29 |
30 | // Appearance.
31 | 'appearance',
32 |
33 | // Backdrop filter.
34 | 'backdrop-filter',
35 |
36 | // Background image options.
37 | 'background-clip',
38 | 'background-origin',
39 | 'background-size',
40 |
41 | // Box sizing.
42 | 'box-sizing',
43 |
44 | // Clip path.
45 | 'clip-path',
46 |
47 | // Filter effects.
48 | 'filter',
49 |
50 | // Flexbox.
51 | 'align-content',
52 | 'align-items',
53 | 'align-self',
54 | 'flex',
55 | 'flex-basis',
56 | 'flex-direction',
57 | 'flex-flow',
58 | 'flex-grow',
59 | 'flex-shrink',
60 | 'flex-wrap',
61 | 'justify-content',
62 | 'order',
63 |
64 | // Font feature.
65 | 'font-feature-settings',
66 | 'font-language-override',
67 | 'font-variant-ligatures',
68 |
69 | // Font kerning.
70 | 'font-kerning',
71 |
72 | // Fragmented borders and backgrounds.
73 | 'box-decoration-break',
74 |
75 | // Grid layout.
76 | 'grid-column',
77 | 'grid-column-align',
78 | 'grid-column-end',
79 | 'grid-column-start',
80 | 'grid-row',
81 | 'grid-row-align',
82 | 'grid-row-end',
83 | 'grid-row-start',
84 | 'grid-template-columns',
85 | 'grid-template-rows',
86 |
87 | // Hyphens.
88 | 'hyphens',
89 | 'word-break',
90 |
91 | // Masks.
92 | 'mask',
93 | 'mask-border',
94 | 'mask-border-outset',
95 | 'mask-border-repeat',
96 | 'mask-border-slice',
97 | 'mask-border-source',
98 | 'mask-border-width',
99 | 'mask-clip',
100 | 'mask-composite',
101 | 'mask-image',
102 | 'mask-origin',
103 | 'mask-position',
104 | 'mask-repeat',
105 | 'mask-size',
106 |
107 | // Multicolumn.
108 | 'break-after',
109 | 'break-before',
110 | 'break-inside',
111 | 'column-count',
112 | 'column-fill',
113 | 'column-gap',
114 | 'column-rule',
115 | 'column-rule-color',
116 | 'column-rule-style',
117 | 'column-rule-width',
118 | 'column-span',
119 | 'column-width',
120 | 'columns',
121 |
122 | // Object fit.
123 | 'object-fit',
124 | 'object-position',
125 |
126 | // Regions.
127 | 'flow-from',
128 | 'flow-into',
129 | 'region-fragment',
130 |
131 | // Scroll snap points.
132 | 'scroll-snap-coordinate',
133 | 'scroll-snap-destination',
134 | 'scroll-snap-points-x',
135 | 'scroll-snap-points-y',
136 | 'scroll-snap-type',
137 |
138 | // Shapes.
139 | 'shape-image-threshold',
140 | 'shape-margin',
141 | 'shape-outside',
142 |
143 | // Tab size.
144 | 'tab-size',
145 |
146 | // Text align last.
147 | 'text-align-last',
148 |
149 | // Text decoration.
150 | 'text-decoration-color',
151 | 'text-decoration-line',
152 | 'text-decoration-skip',
153 | 'text-decoration-style',
154 |
155 | // Text emphasis.
156 | 'text-emphasis',
157 | 'text-emphasis-color',
158 | 'text-emphasis-position',
159 | 'text-emphasis-style',
160 |
161 | // Text size adjust.
162 | 'text-size-adjust',
163 |
164 | // Text spacing.
165 | 'text-spacing',
166 |
167 | // Transform.
168 | 'transform',
169 | 'transform-origin',
170 |
171 | // Transform 3D.
172 | 'backface-visibility',
173 | 'perspective',
174 | 'perspective-origin',
175 | 'transform-style',
176 |
177 | // Transition.
178 | 'transition',
179 | 'transition-delay',
180 | 'transition-duration',
181 | 'transition-property',
182 | 'transition-timing-function',
183 |
184 | // Unicode bidi.
185 | 'unicode-bidi',
186 |
187 | // User select.
188 | 'user-select',
189 |
190 | // Writing mode.
191 | 'writing-mode',
192 |
193 | );
194 |
195 | /// Values that should be vendorized.
196 | /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org
197 | /// @var {list}
198 | $vendor-values: (
199 |
200 | // Cross fade.
201 | 'cross-fade',
202 |
203 | // Element function.
204 | 'element',
205 |
206 | // Filter function.
207 | 'filter',
208 |
209 | // Flexbox.
210 | 'flex',
211 | 'inline-flex',
212 |
213 | // Grab cursors.
214 | 'grab',
215 | 'grabbing',
216 |
217 | // Gradients.
218 | 'linear-gradient',
219 | 'repeating-linear-gradient',
220 | 'radial-gradient',
221 | 'repeating-radial-gradient',
222 |
223 | // Grid layout.
224 | 'grid',
225 | 'inline-grid',
226 |
227 | // Image set.
228 | 'image-set',
229 |
230 | // Intrinsic width.
231 | 'max-content',
232 | 'min-content',
233 | 'fit-content',
234 | 'fill',
235 | 'fill-available',
236 | 'stretch',
237 |
238 | // Sticky position.
239 | 'sticky',
240 |
241 | // Transform.
242 | 'transform',
243 |
244 | // Zoom cursors.
245 | 'zoom-in',
246 | 'zoom-out',
247 |
248 | );
249 |
250 | // Functions.
251 |
252 | /// Removes a specific item from a list.
253 | /// @author Hugo Giraudel
254 | /// @param {list} $list List.
255 | /// @param {integer} $index Index.
256 | /// @return {list} Updated list.
257 | @function remove-nth($list, $index) {
258 |
259 | $result: null;
260 |
261 | @if type-of($index) != number {
262 | @warn "$index: #{quote($index)} is not a number for `remove-nth`.";
263 | }
264 | @else if $index == 0 {
265 | @warn "List index 0 must be a non-zero integer for `remove-nth`.";
266 | }
267 | @else if abs($index) > length($list) {
268 | @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
269 | }
270 | @else {
271 |
272 | $result: ();
273 | $index: if($index < 0, length($list) + $index + 1, $index);
274 |
275 | @for $i from 1 through length($list) {
276 |
277 | @if $i != $index {
278 | $result: append($result, nth($list, $i));
279 | }
280 |
281 | }
282 |
283 | }
284 |
285 | @return $result;
286 |
287 | }
288 |
289 | /// Replaces a substring within another string.
290 | /// @author Hugo Giraudel
291 | /// @param {string} $string String.
292 | /// @param {string} $search Substring.
293 | /// @param {string} $replace Replacement.
294 | /// @return {string} Updated string.
295 | @function str-replace($string, $search, $replace: '') {
296 |
297 | $index: str-index($string, $search);
298 |
299 | @if $index {
300 | @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
301 | }
302 |
303 | @return $string;
304 |
305 | }
306 |
307 | /// Replaces a substring within each string in a list.
308 | /// @param {list} $strings List of strings.
309 | /// @param {string} $search Substring.
310 | /// @param {string} $replace Replacement.
311 | /// @return {list} Updated list of strings.
312 | @function str-replace-all($strings, $search, $replace: '') {
313 |
314 | @each $string in $strings {
315 | $strings: set-nth($strings, index($strings, $string), str-replace($string, $search, $replace));
316 | }
317 |
318 | @return $strings;
319 |
320 | }
321 |
322 | // Mixins.
323 |
324 | /// Wraps @content in vendorized keyframe blocks.
325 | /// @param {string} $name Name.
326 | @mixin keyframes($name) {
327 |
328 | @-moz-keyframes #{$name} { @content; }
329 | @-webkit-keyframes #{$name} { @content; }
330 | @-ms-keyframes #{$name} { @content; }
331 | @keyframes #{$name} { @content; }
332 |
333 | }
334 |
335 | /// Vendorizes a declaration's property and/or value(s).
336 | /// @param {string} $property Property.
337 | /// @param {mixed} $value String/list of value(s).
338 | @mixin vendor($property, $value) {
339 |
340 | // Determine if property should expand.
341 | $expandProperty: index($vendor-properties, $property);
342 |
343 | // Determine if value should expand (and if so, add '-prefix-' placeholder).
344 | $expandValue: false;
345 |
346 | @each $x in $value {
347 | @each $y in $vendor-values {
348 | @if $y == str-slice($x, 1, str-length($y)) {
349 |
350 | $value: set-nth($value, index($value, $x), '-prefix-' + $x);
351 | $expandValue: true;
352 |
353 | }
354 | }
355 | }
356 |
357 | // Expand property?
358 | @if $expandProperty {
359 | @each $vendor in $vendor-prefixes {
360 | #{$vendor}#{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
361 | }
362 | }
363 |
364 | // Expand just the value?
365 | @elseif $expandValue {
366 | @each $vendor in $vendor-prefixes {
367 | #{$property}: #{str-replace-all($value, '-prefix-', $vendor)};
368 | }
369 | }
370 |
371 | // Neither? Treat them as a normal declaration.
372 | @else {
373 | #{$property}: #{$value};
374 | }
375 |
376 | }
--------------------------------------------------------------------------------
/static/sass/main.scss:
--------------------------------------------------------------------------------
1 | @import 'libs/vars';
2 | @import 'libs/functions';
3 | @import 'libs/mixins';
4 | @import 'libs/vendor';
5 | @import 'libs/breakpoints';
6 | @import 'libs/html-grid';
7 | @import 'fontawesome-all.min.css';
8 | @import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,700,900');
9 |
10 | /*
11 | Phantom by HTML5 UP
12 | html5up.net | @ajlkn
13 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
14 | */
15 |
16 | // Breakpoints.
17 |
18 | @include breakpoints((
19 | xlarge: ( 1281px, 1680px ),
20 | large: ( 981px, 1280px ),
21 | medium: ( 737px, 980px ),
22 | small: ( 481px, 736px ),
23 | xsmall: ( 361px, 480px ),
24 | xxsmall: ( null, 360px )
25 | ));
26 |
27 | // Base.
28 |
29 | @import 'base/reset';
30 | @import 'base/page';
31 | @import 'base/typography';
32 |
33 | // Component.
34 |
35 | @import 'components/row';
36 | @import 'components/section';
37 | @import 'components/icon';
38 | @import 'components/list';
39 | @import 'components/actions';
40 | @import 'components/icons';
41 | @import 'components/form';
42 | @import 'components/box';
43 | @import 'components/image';
44 | @import 'components/table';
45 | @import 'components/button';
46 | @import 'components/tiles';
47 |
48 | // Layout.
49 |
50 | @import 'layout/header';
51 | @import 'layout/menu';
52 | @import 'layout/main';
53 | @import 'layout/footer';
54 | @import 'layout/wrapper';
--------------------------------------------------------------------------------
/static/sass/noscript.scss:
--------------------------------------------------------------------------------
1 | @import 'libs/vars';
2 | @import 'libs/functions';
3 | @import 'libs/mixins';
4 | @import 'libs/vendor';
5 | @import 'libs/breakpoints';
6 | @import 'libs/html-grid';
7 |
8 | /*
9 | Phantom by HTML5 UP
10 | html5up.net | @ajlkn
11 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
12 | */
13 |
14 | /* Tiles */
15 |
16 | .tiles {
17 | body.is-preload & {
18 | article {
19 | @include vendor('transform', 'none');
20 | opacity: 1;
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/static/webfonts/fa-brands-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-brands-400.eot
--------------------------------------------------------------------------------
/static/webfonts/fa-brands-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-brands-400.ttf
--------------------------------------------------------------------------------
/static/webfonts/fa-brands-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-brands-400.woff
--------------------------------------------------------------------------------
/static/webfonts/fa-brands-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-brands-400.woff2
--------------------------------------------------------------------------------
/static/webfonts/fa-regular-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-regular-400.eot
--------------------------------------------------------------------------------
/static/webfonts/fa-regular-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-regular-400.ttf
--------------------------------------------------------------------------------
/static/webfonts/fa-regular-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-regular-400.woff
--------------------------------------------------------------------------------
/static/webfonts/fa-regular-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-regular-400.woff2
--------------------------------------------------------------------------------
/static/webfonts/fa-solid-900.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-solid-900.eot
--------------------------------------------------------------------------------
/static/webfonts/fa-solid-900.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-solid-900.ttf
--------------------------------------------------------------------------------
/static/webfonts/fa-solid-900.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-solid-900.woff
--------------------------------------------------------------------------------
/static/webfonts/fa-solid-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/static/webfonts/fa-solid-900.woff2
--------------------------------------------------------------------------------
/templates/comic.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{ name }}
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
29 |
30 |
31 |
37 |
38 |
39 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/templates/detail.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
漫画阅
11 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
52 |
53 |
54 |
62 |
63 | {% for url in urls %}
64 |
65 |
 }})
66 | {% endfor %}
67 |
68 |
69 |
70 |
73 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
124 |
125 |
--------------------------------------------------------------------------------
/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
漫画阅读
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
36 |
37 |
38 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | {% for x,y in content.items() %}
51 |
52 |
53 |
54 |
55 |
56 | {{x}}
57 |
60 |
61 |
62 | {% endfor %}
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/templates/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Login
7 |
186 |
187 |
188 |
189 |
190 |
191 |
206 |
207 |
208 |
209 |
210 |
--------------------------------------------------------------------------------
/图片/预览.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d8349565/comic/a2d69c98c8cfdaf5f67fadd64e12f4b78edec03b/图片/预览.gif
--------------------------------------------------------------------------------