' + title + '
';
24 | let body = '';
25 | let footer = '';
26 |
27 | if (text) {
28 | text = options.noHtmlEscape ? text : escapeHtml(text);
29 | body += '
' + text + '
';
30 | }
31 |
32 | switch (type) {
33 | case 'alert':
34 | footer += '
' + (options && options.buttonLabelOk ? options.buttonLabelOk : 'OK') + ' ';
35 | break;
36 | case 'confirm':
37 | footer += '
' + (options && options.buttonLabelOk ? options.buttonLabelOk : 'OK') + ' Cancel ';
38 | break;
39 | case 'prompt':
40 | body += '
';
41 | footer += '
' + (options && options.buttonLabelOk ? options.buttonLabelOk : 'OK') + ' Cancel ';
42 | break;
43 | default:
44 | console.log('Modal type must be alert, confirm or prompt. ' + type + ' isn\'t recognized.');
45 | return;
46 | }
47 |
48 | html += '
' + body + '
';
49 | html += '
';
50 |
51 | overlay.addContent('modal', html);
52 | overlay.show();
53 |
54 | if (type === 'prompt') {
55 | $('.input-new-tag').focus();
56 | }
57 |
58 | overlay.addListener('modal', function (event) {
59 | const target = $(event.target);
60 |
61 | if (target.hasClass('modal-ok')) {
62 | if (typeof callback === 'function') {
63 | const userInput = $('#modal-container input.input-new-tag').val();
64 | callback(true, userInput);
65 | }
66 | overlay.hide();
67 | } else if (target.hasClass('modal-cancel') || target.hasClass('container') || target.attr('id') === 'modal-container' || target.attr('id') === 'overlay-modal') {
68 | if (typeof callback === 'function') {
69 | callback(false);
70 | }
71 | overlay.hide();
72 | }
73 | });
74 |
75 | ripple.init();
76 | };
77 |
78 | export default displayModal;
79 |
--------------------------------------------------------------------------------
/src/js/components/notification.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 |
3 | const notification = {
4 | init: function () {
5 | $('.notification-close').on('click', function () {
6 | const $el = $(this);
7 | const $notification = $el.closest('.notification');
8 |
9 | $notification.addClass('animate-fade-out');
10 | setTimeout(function () {
11 | $notification.remove();
12 | }, 250);
13 | });
14 | }
15 | };
16 |
17 | export default notification;
18 |
--------------------------------------------------------------------------------
/src/js/components/overlay.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 | import animations from './animations';
3 |
4 | const overlay = {
5 | listeners: {},
6 | element: undefined,
7 | init: function () {
8 | const _this = this;
9 | this.get().on('click', function (event) {
10 | if (event.target.id === 'overlay') {
11 | _this.hide();
12 | }
13 |
14 | _this.triggerEvent(event);
15 | });
16 | },
17 | get: function () {
18 | if (!this.element) {
19 | this.element = $('#overlay').eq(0);
20 | }
21 | return this.element;
22 | },
23 | show: function () {
24 | animations.fadeIn(this.get());
25 | },
26 | hide: function () {
27 | animations.fadeOut(this.get());
28 | },
29 | addContent: function (id, html) {
30 | if (this.get().find('#overlay-content-' + id).length === 0) {
31 | this.get().html('
' + html + '
');
32 | } else {
33 | this.get().find('#overlay-content-' + id).html(html);
34 | }
35 | },
36 | addListener: function (id, callback) {
37 | this.listeners[id] = callback;
38 | },
39 | triggerEvent: function (event) {
40 | for (const listener in this.listeners) {
41 | if (typeof this.listeners[listener] === 'function') {
42 | this.listeners[listener](event);
43 | }
44 | }
45 | }
46 | };
47 |
48 | export default overlay;
49 |
--------------------------------------------------------------------------------
/src/js/components/popup.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 |
3 | import animations from './animations';
4 | import batchEdit from './batch-edit';
5 |
6 | const popup = {
7 | init: function () {
8 | const _this = this;
9 |
10 | $('html').on('click', function (event) {
11 | // If the click occurs in a popup, in a child of a popup or in a popup trigger, nothing happens.
12 | if ($.inArray('popup-trigger', event.target.classList) > -1 || $(event.target).parents('.popup-trigger').length >= 1 ||
13 | $.inArray('popup', event.target.classList) > -1 || $(event.target).parents('.popup').length >= 1) {
14 | // Nothing to do.
15 | } else {
16 | _this.hideAll();
17 | }
18 |
19 | if ($.inArray('actionbar-selectall-link', event.target.classList) > -1) {
20 | event.preventDefault();
21 | $('.link-outer').each(function () {
22 | batchEdit.toggleLink($(this), true);
23 | });
24 | }
25 | });
26 |
27 | $('.popup-trigger').on('click', function () {
28 | _this.hideAll();
29 |
30 | const $popup = $('#' + $(this).data('popup'));
31 |
32 | if ($popup.is(':visible')) {
33 | animations.fadeOut($popup);
34 | } else {
35 | animations.slideFromTop($popup);
36 | }
37 | });
38 |
39 | $('.popup-close').on('click', function () {
40 | _this.hideAll();
41 | });
42 |
43 | // Closes filters popup when changing number of links per page
44 | // because it feels more natural and gives user a feedback.
45 | $('.filters-links-per-page a').on('click', function (event) {
46 | _this.hideAll();
47 | });
48 |
49 | $('.popup-filter .switch label').on('click', function () {
50 | const url = $(this).data('url');
51 |
52 | window.location.href = url;
53 | });
54 | },
55 |
56 | hideAll: function () {
57 | $('.popup:visible').each(function () {
58 | animations.fadeOut($(this));
59 | });
60 | }
61 | };
62 |
63 | export default popup;
64 |
--------------------------------------------------------------------------------
/src/js/components/ripple.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 |
3 | const ripple = {
4 | init: function () {
5 | $('.ripple, .button, .button-raised, .button-inverse')
6 | .off('mousedown.tinymaterialripple')
7 | .not('[disabled]')
8 | .on('mousedown.tinymaterialripple', function (event) {
9 | const el = this;
10 |
11 | let offsetX = (event.pageX - $(event.target).offset().left);
12 | let offsetY = (event.pageY - $(event.target).offset().top);
13 |
14 | // Compensate the offset shift when the click is done on an element within the element we want the ripple to be displayed on.
15 | const getRealValues = function (element) {
16 | if (element === el || !element) {
17 | return;
18 | }
19 |
20 | offsetX += element.offsetLeft;
21 | offsetY += element.offsetTop;
22 |
23 | getRealValues(element.offsetParent);
24 | };
25 | getRealValues(event.target);
26 |
27 | const $el = $(el);
28 | const rippleDefaultDiameter = 20;
29 | const $div = $('
');
30 |
31 | $div.addClass('ripple-effect');
32 | $div.css({
33 | top: offsetY - (rippleDefaultDiameter / 2) + 'px', // - ($ripple.height() / 2),
34 | left: offsetX - (rippleDefaultDiameter / 2) + 'px', // - ($ripple.width() / 2),
35 | background: $el.data('ripple-color')
36 | }).appendTo($el);
37 |
38 | window.setTimeout(function () {
39 | $div.remove();
40 | }, 2000);
41 | });
42 | }
43 | };
44 |
45 | export default ripple;
46 |
--------------------------------------------------------------------------------
/src/js/components/search.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 |
3 | import animations from './animations';
4 |
5 | const search = {
6 | init: function () {
7 | const displaySearch = function () {
8 | const overlayElement = $('#search-overlay');
9 | animations.fadeIn(overlayElement);
10 | overlayElement
11 | .find('#searchform_value')
12 | .focus()
13 | .select();
14 |
15 | animations.slideFromTop(overlayElement.find('.content-fullscreen'));
16 | };
17 |
18 | $('#button-search').on('click', displaySearch);
19 | $('#search-overlay').on('click', function (event) {
20 | if ($(event.target).parents('#form-search').length === 0 && event.target.nodeName.toLowerCase() !== 'form') {
21 | animations.fadeOut($(this));
22 | }
23 | });
24 | $(document).on('keyup', function (event) {
25 | const key = event.which || event.keyCode;
26 | if (key === 27) {
27 | // Closes search field when key "ESC" is pressed.
28 | const overlayElement = $('#search-overlay');
29 | animations.fadeOut(overlayElement);
30 | } else if (key === 83 && event.target.nodeName !== 'INPUT' && event.target.nodeName !== 'TEXTAREA' && event.target.nodeName !== 'SELECT') {
31 | // Displays search field when key "S" is pressed.
32 | displaySearch();
33 | }
34 | });
35 |
36 | // Validation for tags search field.
37 | $('#button-filter').on('click', function () {
38 | const val = $('#searchform_value').val().trim();
39 | $('#tagfilter_value').val(val);
40 | $('#hidden-tag-form').trigger('submit');
41 |
42 | return false;
43 | });
44 | }
45 | };
46 |
47 | export default search;
48 |
--------------------------------------------------------------------------------
/src/js/components/tag.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 |
3 | import modal from './modal';
4 | import animations from './animations';
5 | import http from './http';
6 |
7 | const tag = {
8 | init: function () {
9 | // Delete button on manage tag page.
10 | $('#button-delete').on('click', function (event) {
11 | event.preventDefault();
12 |
13 | const tag = $('#fromtag').val();
14 | const form = $(this).closest('form');
15 |
16 | modal('Delete the tag "' + tag + '"', 'Are you sure you want to delete the tag "' + tag + '" from all links?', 'confirm', function (accepts) {
17 | if (accepts) {
18 | form.append('
');
19 | form.submit();
20 | }
21 | });
22 | return false;
23 | });
24 |
25 | // Delete a tag on tag list page.
26 | $('.delete-tag').on('click', function (event) {
27 | event.preventDefault();
28 |
29 | const el = $(this);
30 | const tag = el.data('tag');
31 | const token = $('#token').val();
32 |
33 | modal('Delete the tag "' + tag + '"', 'Are you sure you want to delete the tag "' + tag + '" from all links ?', 'confirm', function (accepts) {
34 | if (accepts) {
35 | $.ajax({
36 | url: shaarli.basePath + '/admin/tags',
37 | method: 'post',
38 | contentType: 'application/x-www-form-urlencoded',
39 | data: {
40 | deletetag: 1,
41 | fromtag: tag,
42 | token
43 | },
44 | success: function () {
45 | const $toBeRemoved = el.closest('.list-item-flex');
46 | animations.compressHeight($toBeRemoved, null, function () {
47 | $toBeRemoved.remove();
48 | });
49 | },
50 | error: function () {
51 | modal('Error', 'Oops! something went wrong...', 'alert');
52 | },
53 | complete: function () {
54 | http.refreshToken();
55 | }
56 | });
57 | }
58 | });
59 | });
60 |
61 | // Rename a tag on tag list page.
62 | $('.rename-tag').on('click', function (event) {
63 | event.preventDefault();
64 |
65 | const el = $(this);
66 | const listItem = el.closest('.list-item-flex');
67 | const tag = el.data('tag');
68 | const token = $('#token').val();
69 |
70 | const feedback = $('
')
71 | .addClass('text-feedback')
72 | .text('renaming...');
73 |
74 | modal('Rename tag ' + tag, 'Please write the new name of this tag below.', 'prompt', function (accepts, newTag) {
75 | if (accepts) {
76 | listItem.find('.list-item-middle').append(feedback);
77 |
78 | $.ajax({
79 | url: shaarli.basePath + '/admin/tags',
80 | method: 'post',
81 | contentType: 'application/x-www-form-urlencoded',
82 | data: {
83 | fromtag: tag,
84 | totag: newTag,
85 | token,
86 | renametag: 'Rename tag'
87 | },
88 | success: function () {
89 | listItem.find('.tag-link').attr('href', shaarli.basePath + '/?searchtags=' + encodeURIComponent(newTag)).text(newTag);
90 | listItem.find('[data-tag]').data('tag', newTag);
91 | listItem.find('.count').attr('href', shaarli.basePath + '/add-tag/' + encodeURIComponent(newTag));
92 | listItem.find('.rename-tag').attr('href', shaarli.basePath + '/admin/tags?fromtag=' + encodeURIComponent(newTag));
93 |
94 | feedback.addClass('text-success')
95 | .text('renamed successfully!');
96 | },
97 | error: function () {
98 | feedback.addClass('text-error')
99 | .text('something went wrong');
100 | },
101 | complete: function () {
102 | http.refreshToken();
103 | setTimeout(function () {
104 | feedback.remove();
105 | }, 5000);
106 | }
107 | });
108 | }
109 | }, {
110 | buttonLabelOk: 'Rename',
111 | value: tag
112 | });
113 | });
114 | }
115 | };
116 |
117 | export default tag;
118 |
--------------------------------------------------------------------------------
/src/js/components/thumbnail.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 |
3 | import modal from './modal';
4 |
5 | const thumbnail = {
6 | init: function () {
7 | if ($('.page-thumbnails').length === 0) {
8 | return;
9 | }
10 |
11 | const $thumbnailPlaceholder = $('.thumbnail-placeholder');
12 | const $thumbnailTitle = $('.thumbnail-link-title');
13 | const $progressCurrent = $('.progress-current');
14 | const $progressBarActual = $('.progress-actual');
15 |
16 | let i = 0;
17 | const thumbnailsIdList = $('[name="ids"]').val().split(',');
18 | const total = thumbnailsIdList.length;
19 |
20 | const updateThumbnail = function (id) {
21 | console.log('Updating thunmbnail #' + i + ' with id ' + id);
22 | $.ajax({
23 | url: shaarli.basePath + '/admin/shaare/' + thumbnailsIdList[i] + '/update-thumbnail',
24 | method: 'patch',
25 | dataType: 'json',
26 | success: function (response) {
27 | i++;
28 | $thumbnailTitle.text(response.title);
29 | if (response.thumbnail) {
30 | $thumbnailPlaceholder.html('
');
31 | } else {
32 | $thumbnailPlaceholder.empty();
33 | }
34 | $progressCurrent.text(i);
35 | $progressBarActual.css('width', ((i * 100) / thumbnailsIdList.length) + '%');
36 |
37 | if (i < total) {
38 | updateThumbnail(thumbnailsIdList[i]);
39 | } else {
40 | $thumbnailTitle.text('Thumbnail update done!');
41 | }
42 | },
43 | error: function (xhr) {
44 | console.error('Failed to update thumbnail.');
45 | modal('Error', 'An error occurred while downloading thumbnails. Return code: ' + xhr.status, 'alert');
46 | }
47 | });
48 | };
49 |
50 | updateThumbnail(thumbnailsIdList[i]);
51 | }
52 | };
53 |
54 | export default thumbnail;
55 |
--------------------------------------------------------------------------------
/src/js/components/utils.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 |
3 | export const guid = function () {
4 | function s4 () {
5 | return Math.floor((1 + Math.random()) * 0x10000)
6 | .toString(16)
7 | .substring(1);
8 | }
9 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
10 | s4() + '-' + s4() + s4() + s4();
11 | };
12 |
13 | export const escapeHtml = function (html) {
14 | return $('
').text(html).html();
15 | };
16 |
17 | export const objectSize = function (obj) {
18 | if (typeof obj !== 'object') {
19 | return 0;
20 | }
21 |
22 | return Object.keys(obj).length;
23 | };
24 |
--------------------------------------------------------------------------------
/src/js/lib.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 | import Blazy from 'blazy';
3 | import Awesomplete from 'awesomplete';
4 | import Sortable from 'sortablejs';
5 | // import QRCode from '../../node_modules/qrcode/build/qrcode';
6 | import QRCode from 'qrcode';
7 | import autosize from 'autosize';
8 |
9 | import overlay from './components/overlay';
10 |
11 | const initSortable = function () {
12 | // Sortable plugins in admin.
13 | $('.list-sortable').each(function () {
14 | Sortable.create(this, {
15 | animation: 200,
16 | draggable: '.list-item-sortable',
17 | handle: '.list-sortable-handle',
18 | forceFallback: true,
19 | onEnd: function (event) {
20 | let i = 0;
21 | const list = $(event.target);
22 | list.find('.list-item-sortable').each(function () {
23 | $(this).data('order', i).find('[type=hidden]').val(i);
24 | i++;
25 | });
26 | }
27 | });
28 | });
29 | };
30 |
31 | const initAutocomplete = function () {
32 | if ($('input[data-multiple]').length > 0) {
33 | let awesomplete;
34 |
35 | $('input[data-multiple]').each(function () {
36 | awesomplete = new Awesomplete(this, {
37 | filter: function (text, input) {
38 | return Awesomplete.FILTER_CONTAINS(text, input.match(/[^ ]*$/)[0]);
39 | },
40 | replace: function (text) {
41 | const before = this.input.value.match(/^.+ \s*|/)[0];
42 | this.input.value = before + text + ' ';
43 | },
44 | minChars: 1
45 | });
46 |
47 | $(this).on('click', function () {
48 | awesomplete.close();
49 | });
50 | });
51 |
52 | /**
53 | * Remove already selected items from autocompletion list.
54 | * HTML list is never updated, so removing a tag will add it back to awesomplete.
55 | *
56 | * FIXME: This a workaround waiting for awesomplete to handle this.
57 | * https://github.com/LeaVerou/awesomplete/issues/16749
58 | */
59 | const input = $('#lf_tags');
60 | input.on('input', function () {
61 | const proposedTags = input.data('list').replace(/,/g, '').split(' ');
62 | const reg = /(\w+) /g;
63 | let match;
64 | while ((match = reg.exec(input.val())) !== null) {
65 | const id = proposedTags.indexOf(match[1]);
66 | if (id !== -1) {
67 | proposedTags.splice(id, 1);
68 | }
69 | }
70 | awesomplete.list = proposedTags;
71 | });
72 | }
73 | };
74 |
75 | const initQrCode = function () {
76 | // Removes the onclick attribute to override the Shaarli default qrcode button's behavior.
77 | $('.icon-qrcode, .qrcode').removeAttr('onclick').off('click').on('click', function (event) {
78 | event.preventDefault();
79 |
80 | const url = $(this).data('permalink');
81 |
82 | overlay.addListener('qrcode', function (event) {
83 | overlay.hide();
84 | });
85 | overlay.addContent('qrcode', '
');
86 |
87 | QRCode.toCanvas(document.getElementById('qrcode'), url, {
88 | errorCorrectionLevel: 'H',
89 | width: 250
90 | }, function (error) {
91 | if (error) {
92 | console.error(error); // todo display modal error
93 | }
94 | });
95 |
96 | overlay.show();
97 |
98 | // Disable original click event.
99 | return false;
100 | });
101 | };
102 |
103 | const lib = {
104 | init: function () {
105 | /* eslint-disable no-new */
106 | new Blazy();
107 |
108 | initAutocomplete();
109 | initQrCode();
110 |
111 | if (shaarli.isAuth) {
112 | if (shaarli.pageName === 'pluginsadmin') {
113 | initSortable();
114 | }
115 |
116 | if (['editlink', 'editlinkbatch'].includes(shaarli.pageName)) {
117 | autosize($('[name="lf_description"]'));
118 | }
119 | }
120 | }
121 | };
122 |
123 | export default lib;
124 |
--------------------------------------------------------------------------------
/src/js/main.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 | import 'salvattore';
3 |
4 | import modal from './components/modal';
5 |
6 | import ripple from './components/ripple';
7 | import overlay from './components/overlay';
8 | import batchEdit from './components/batch-edit';
9 | import batchAdd from './components/batch-add';
10 | import linkEditor from './components/link-editor';
11 | import linkList from './components/link-list';
12 | import search from './components/search';
13 | import popup from './components/popup';
14 | import thumbnail from './components/thumbnail';
15 | import tag from './components/tag';
16 | import notification from './components/notification';
17 | import lib from './lib';
18 |
19 | import '../../node_modules/bootstrap/dist/css/bootstrap.css';
20 | import '../../node_modules/awesomplete/awesomplete.css';
21 | import '../scss/styles.scss';
22 |
23 | const init = function () {
24 | // Init menu.
25 | $('.icon-unfold').on('click', function () {
26 | $('.header-main').toggleClass('unfold');
27 | });
28 |
29 | $('[data-href]').on('click', function () {
30 | const url = $(this).data('href');
31 | if (url) {
32 | document.location.href = url;
33 | }
34 | });
35 |
36 | if ($('.filter-on').length > 0) {
37 | $('#input-readlater').prop('checked', true);
38 | $('.header-button-filter').addClass('has-filter-readlater');
39 | }
40 | };
41 |
42 | const initAdmin = function () {
43 | // Bookmarklet warning.
44 | $('.bookmarklet').on('click', function (event) {
45 | event.preventDefault();
46 | modal('Information', 'Drag this link to your bookmarks toolbar, or right-click it and choose Bookmark This Link.', 'alert');
47 | return false;
48 | });
49 | };
50 |
51 | // Initialize components
52 | $(function () {
53 | ripple.init();
54 | overlay.init();
55 | search.init();
56 | popup.init();
57 | notification.init();
58 | init();
59 |
60 | lib.init();
61 |
62 | if (shaarli.isAuth) {
63 | linkList.init();
64 | linkEditor.init();
65 | batchEdit.init();
66 | batchAdd.init();
67 | thumbnail.init();
68 | tag.init();
69 | initAdmin();
70 | }
71 |
72 | // Only autofocus the first element found.
73 | $('.autofocus').each(function (index, element) {
74 | $(element).trigger('focus');
75 | return false;
76 | });
77 | });
78 |
--------------------------------------------------------------------------------
/src/scss/components/_actionbar.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 | @use "shadow";
3 |
4 | .actionbar{
5 | position: fixed;
6 | bottom: 0;
7 | left: 0;
8 | right: 0;
9 | background: #fff;
10 | z-index: 50;
11 |
12 | @extend .shadow-top-1;
13 |
14 | .row{
15 | padding: values.$space-m;
16 | padding-bottom: values.$space-m - values.$space-s;
17 | }
18 | }
19 |
20 | .actionbar-label{
21 | float: left;
22 | padding: 7px;
23 | }
24 |
25 | .actionbar-selectall {
26 | float: left;
27 | padding: 7px 7px 7px 0;
28 | }
29 |
30 | .actionbar-controls{
31 | float: right;
32 |
33 | button{
34 | margin-left: values.$space-s;
35 | margin-bottom: values.$space-s;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/scss/components/_animations.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | /**
4 | * ANIMATIONS
5 | * To perform animations, add the desired class to the desired element.
6 | * To perform the animation again, you'll need to first remove the class through Javascript.
7 | * Otherwise, the animations object in Javascript makes it more easy.
8 | */
9 |
10 | /* Fade in */
11 | .animate-fade-in{
12 | animation: fade-in values.$animation-speed ease;
13 | }
14 | @keyframes fade-in {
15 | 0% {
16 | opacity: 0;
17 | }
18 | 100%{
19 | opacity: 1;
20 | }
21 | }
22 |
23 | /* Fade out */
24 | .animate-fade-out{
25 | animation: fade-out values.$animation-speed ease forwards !important;
26 | }
27 | @keyframes fade-out {
28 | 0% {
29 | opacity: 1;
30 | }
31 | 100%{
32 | opacity: 0;
33 | }
34 | }
35 |
36 | /* From top */
37 | .animate-slide-from-top{
38 | animation: slide-from-top values.$animation-speed ease;
39 | }
40 | @keyframes slide-from-top {
41 | 0% {
42 | opacity: 0;
43 | transform: translateY(-40px);
44 | }
45 | 100%{
46 | opacity: 1;
47 | transform: translateY(0);
48 | }
49 | }
50 |
51 | /* From right */
52 | .animate-slide-from-right{
53 | animation: slide-from-right values.$animation-speed ease forwards;
54 | }
55 | @keyframes slide-from-right {
56 | 0% {
57 | opacity: 0;
58 | transform: translateX(40px);
59 | }
60 | 100%{
61 | opacity: 1;
62 | transform: translateX(0);
63 | }
64 | }
65 |
66 | .animate-hide-slide-to-bottom{
67 | animation: hide-slide-to-bottom values.$animation-speed ease forwards;
68 | }
69 | @keyframes hide-slide-to-bottom {
70 | 0% {
71 | opacity: 1;
72 | transform: translateY(0px);
73 | }
74 | 100%{
75 | opacity: 0;
76 | transform: translateY(300px);
77 | }
78 | }
79 |
80 | .animate-show-slide-from-bottom{
81 | animation: show-slide-from-bottom values.$animation-speed ease;
82 | }
83 | @keyframes show-slide-from-bottom {
84 | 0% {
85 | opacity: 0;
86 | transform: translateY(300px);
87 | }
88 | 100%{
89 | opacity: 1;
90 | transform: translateY(0);
91 | }
92 | }
93 | .animate-compress-height-50 {
94 | animation: compress-height-50 values.$animation-speed-long ease forwards;
95 | overflow: hidden;
96 | }
97 | @keyframes compress-height-50 {
98 | 0% {
99 | opacity: 1;
100 | max-height: 50px;
101 | }
102 | 100%{
103 | opacity: 0;
104 | max-height: 0;
105 | }
106 | }
107 |
108 | .animate-turn-forever {
109 | animation: turn values.$animation-speed-long linear infinite;
110 | }
111 | @keyframes turn {
112 | 0% {
113 | transform: rotate(0deg);
114 | }
115 |
116 | 100% {
117 | transform: rotate(360deg);
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/src/scss/components/_bookmarklet.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | .bookmarklet{
4 | padding: values.$space-t values.$space-s;
5 | background-color: #fff;
6 | border: 1px solid #aaa;
7 | color: values.$color-text;
8 | text-decoration: none;
9 |
10 | &:hover,
11 | &:focus{
12 | box-shadow: 0 -1px 0 values.$color-gray-200,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);
13 | text-decoration: none;
14 | color: inherit;
15 | }
16 |
17 | &:active{
18 | box-shadow: none;
19 | }
20 |
21 | & img{
22 | vertical-align: top;
23 | height: 20px;
24 | }
25 | }
--------------------------------------------------------------------------------
/src/scss/components/_button.scss:
--------------------------------------------------------------------------------
1 | @use "sass:color";
2 |
3 | @use "values";
4 | @use "helpers";
5 | @use "shadow";
6 |
7 | $button-padding: 8px 16px;
8 | $button-height: 36px;
9 |
10 | @mixin button-color($color){
11 | color: #fff;
12 | background-color: $color;
13 |
14 | &:hover,
15 | &:focus{
16 | background-color: color.adjust($color, $lightness: -5%);
17 | color: #fff;
18 | }
19 | &:active{
20 | background-color: color.adjust($color, $lightness: -10%);
21 | color: #fff;
22 | }
23 | &:active:focus{
24 | color: #fff;
25 | }
26 | }
27 |
28 | /* Button reset. */
29 | .button-base{
30 | @extend .nowrap;
31 |
32 | display: inline-block;
33 | position: relative;
34 | overflow: hidden;
35 | height: $button-height;
36 | padding: $button-padding;
37 |
38 | border: none;
39 | border-radius: values.$radius-s;
40 | outline: 0;
41 |
42 | background-color: values.$color-transparent;
43 |
44 | @include values.font-button();
45 | color: values.$color-text;
46 | text-transform: uppercase;
47 | text-decoration: none;
48 | text-align: center;
49 |
50 | cursor: pointer;
51 |
52 | &:hover,
53 | &:focus,
54 | &:active,
55 | &:active:focus{
56 | outline: 0;
57 | border: none;
58 | text-decoration: none;
59 | color: values.$color-text;
60 | }
61 |
62 | &[disabled]{
63 | pointer-events: none;
64 | }
65 |
66 | &::-moz-focus-inner {
67 | border: 0;
68 | padding: 0;
69 | }
70 |
71 | &.pull-right{
72 | margin-left: 10px;
73 | }
74 | }
75 |
76 | .button{
77 | @extend .button-base;
78 |
79 | &:hover,
80 | &:focus{
81 | background-color: values.$color-button-hover;
82 | box-shadow: none;
83 |
84 | color: values.$color-text;
85 | }
86 |
87 | &:active{
88 | box-shadow: none;
89 | }
90 |
91 | &[disabled]{
92 | &,
93 | &:hover,
94 | &:focus,
95 | &:active{
96 | color: values.$color-button-disabled;
97 | background-color: values.$color-transparent;
98 | }
99 | }
100 | }
101 |
102 | .button-raised{
103 | @extend .button-base;
104 | @extend .shadow-button;
105 |
106 | background-color: values.$color-button-raised;
107 |
108 | &:hover,
109 | &:focus{
110 | @extend .shadow-button-hover;
111 |
112 | color: values.$color-text;
113 | }
114 |
115 | &:active{
116 | box-shadow: none;
117 | }
118 |
119 | &[disabled]{
120 | &,
121 | &:hover,
122 | &:focus,
123 | &:active{
124 | @extend .shadow-button;
125 |
126 | color: values.$color-button-raised-disabled-text;
127 | background-color: values.$color-button-raised-disabled;
128 | }
129 | }
130 | }
131 |
132 | .button-inverse{
133 | @extend .button-base;
134 |
135 | color: #fff;
136 | background-color: values.$color-transparent;
137 |
138 | &:hover,
139 | &:focus{
140 | background-color: rgba(204, 204, 204, 0.15);
141 | color: #fff;
142 | }
143 |
144 | &:active,
145 | &:active:focus,
146 | &.active{
147 | background-color: rgba(204, 204, 204, 0.25);
148 | color: #fff;
149 | }
150 |
151 | &[disabled]{
152 | background-color: rgba(255, 255, 255, 0);
153 | color: rgba(255, 255, 255, 0.30);
154 | }
155 | }
156 |
157 | /* Color variations. */
158 | .button-primary{
159 | @include button-color(values.$color-primary);
160 | }
161 | .button-alert{
162 | @include button-color(values.$color-alert);
163 | }
164 | .button-firefox{
165 | @include button-color(values.$color-firefox);
166 | }
167 |
168 | /* Floating action button */
169 | .button-floating{
170 | @extend .shadow-button-floating;
171 |
172 | position: fixed;
173 | display: flex;
174 | align-items: center;
175 | justify-content: center;
176 |
177 | width: 56px;
178 | height: 56px;
179 | bottom: 5%;
180 | right: 5%;
181 |
182 | text-align: center;
183 | line-height: 54px;
184 | font-size: 25px;
185 | color: #fff;
186 |
187 | background-color: values.$color-secondary;
188 |
189 | border-radius: 50%;
190 | transition: box-shadow 150ms cubic-bezier(0,0,.2,1);
191 |
192 | z-index: 100;
193 |
194 | &:hover,
195 | &:focus{
196 | @extend .shadow-button-floating-hover;
197 | color: #fff;
198 | text-decoration: none;
199 | }
200 |
201 | &:active{
202 | box-shadow: none;
203 | }
204 | }
205 |
206 | .large-icon-button{
207 |
208 | display: block;
209 | float: left;
210 | padding: values.$space-m;
211 | color: values.$color-text;
212 | width: 140px;
213 | overflow: hidden;
214 | font-size: 16px;
215 | text-align: center;
216 | border-radius: values.$radius-s;
217 |
218 | &:hover,
219 | &:focus{
220 | text-decoration: none;
221 | background-color: values.$color-gray-light;
222 | color: values.$color-text;
223 | }
224 |
225 | &:active{
226 | background-color: color.adjust(values.$color-gray-light, $lightness: -5%);
227 | }
228 |
229 | i{
230 | display: block;
231 | margin: auto;
232 | font-size: 70px;
233 |
234 | &.mdi-firefox{
235 | color: #e55b0a;
236 | }
237 | &.mdi-apple-ios{
238 | color: #a6a8ab;
239 | }
240 | &.mdi-android{
241 | color: #a4c739;
242 | }
243 | &.mdi-google-chrome{
244 | color: #dd4f43;
245 | }
246 | }
247 | }
248 |
--------------------------------------------------------------------------------
/src/scss/components/_card.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | .card {
4 | position: relative;
5 | height: auto;
6 | background: #fff;
7 | box-shadow: 0 -1px 0 values.$color-gray-200,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);
8 | margin: 15px 0 15px 0;
9 | border-radius: 4px;
10 | transition: all values.$animation-speed ease-in-out;
11 | }
12 |
13 | .card-overlay {
14 | position: absolute;
15 | top: 0;
16 | bottom: 0;
17 | left: 0;
18 | right: 0;
19 | padding: values.$space-m;
20 | background-color: rgba(255, 255, 255, .8);
21 | z-index: 10;
22 | transition: background-color values.$animation-speed ease-in-out;
23 | }
24 |
25 | .card-title,/* DEPRECATED use header instead */
26 | .card-header,
27 | h1.card-header {
28 | position: relative;
29 | margin: 0;
30 | padding: 15px;
31 | border-bottom: 1px solid values.$color-gray-300;
32 | @include values.font-body2();
33 | text-transform: uppercase;
34 | }
35 |
36 | .card-subheader {
37 | text-transform: initial;
38 | font-size: 90%;
39 | font-weight: normal;
40 | font-style: italic;
41 | color: values.$color-subtitle;
42 | }
43 |
44 | .card-body {
45 | padding: values.$space-m;
46 | }
47 |
48 | .card-footer {
49 | padding: 15px;
50 | }
51 |
52 | .card-search {
53 | input[type="search"]{
54 | padding: values.$space-s values.$space-m;
55 | background-color: values.$color-gray-hover;
56 | border-color: transparent;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/scss/components/_fonts.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Roboto';
3 | font-style: normal;
4 | font-weight: 100;
5 | font-display: swap;
6 | src: url('fonts/roboto/Roboto-Thin.ttf') format('truetype');
7 | }
8 | @font-face {
9 | font-family: 'Roboto';
10 | font-style: normal;
11 | font-weight: 200;
12 | font-display: swap;
13 | src: url('fonts/roboto/Roboto-Light.ttf') format('truetype');
14 | }
15 | @font-face {
16 | font-family: 'Roboto';
17 | font-style: normal;
18 | font-weight: 400;
19 | font-display: swap;
20 | src: url('fonts/roboto/Roboto-Regular.ttf') format('truetype');
21 | }
22 | @font-face {
23 | font-family: 'Roboto';
24 | font-style: normal;
25 | font-weight: 500;
26 | font-display: swap;
27 | src: url('fonts/roboto/Roboto-Medium.ttf') format('truetype');
28 | }
29 | @font-face {
30 | font-family: 'Roboto';
31 | font-style: normal;
32 | font-weight: 700;
33 | font-display: swap;
34 | src: url('fonts/roboto/Roboto-Bold.ttf') format('truetype');
35 | }
36 | @font-face {
37 | font-family: 'Roboto Condensed';
38 | font-style: normal;
39 | font-weight: 400;
40 | font-display: swap;
41 | src: url('fonts/roboto/RobotoCondensed-Regular.ttf') format('truetype');
42 | }
43 |
44 | @font-face {
45 | font-family: 'Material';
46 | src: url('fonts/material-icons/materialdesignicons-webfont.eot'); /* IE9 Compat Modes */
47 | src: url('fonts/material-icons/materialdesignicons-webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
48 | url('fonts/material-icons/materialdesignicons-webfont.woff2') format('woff2'), /* Super Modern Browsers */
49 | url('fonts/material-icons/materialdesignicons-webfont.woff') format('woff'), /* Pretty Modern Browsers */
50 | url('fonts/material-icons/materialdesignicons-webfont.ttf') format('truetype'), /* Safari, Android, iOS */
51 | url('fonts/material-icons/materialdesignicons-webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
52 | font-weight: normal;
53 | font-style: normal;
54 | font-display: block;
55 | }
56 |
57 | @font-face {
58 | font-family: 'Old Newspaper Types';
59 | src: url('fonts/oldnewspapertypes/oldnewspapertypes-webfont.woff2') format('woff2'), /* Super Modern Browsers */
60 | url('fonts/oldnewspapertypes/oldnewspapertypes-webfont.woff') format('woff'), /* Pretty Modern Browsers */
61 | url('fonts/oldnewspapertypes/oldnewspapertypes-webfont.ttf') format('truetype'); /* Safari, Android, iOS */
62 | font-weight: normal;
63 | font-style: normal;
64 | font-display: swap;
65 |
66 | }
--------------------------------------------------------------------------------
/src/scss/components/_footer.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | /* Footer */
4 | #footer{
5 | text-align: center;
6 | margin-top: 50px;
7 | margin-bottom: 15px;
8 | color: values.$color-gray-700;
9 | @include values.font-caption();
10 |
11 | .from-bookmarklet &{
12 | margin-top: 10px;
13 | }
14 | }
--------------------------------------------------------------------------------
/src/scss/components/_global.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | *,
4 | *:after,
5 | *:before {
6 | box-sizing: border-box;
7 | }
8 |
9 | html{
10 | background: values.$color-gray-150;
11 | font-size: values.$font-size;
12 | -webkit-tap-highlight-color: rgba(0,0,0,0);
13 | }
14 |
15 | body{
16 | font-family: values.$font-stack;
17 | font-size: values.$font-size;
18 | background: values.$color-gray-150;
19 | color: values.$color-text;
20 | }
21 | h1{
22 | @include values.font-headline();
23 | margin: values.$space-s 0 values.$space-l 0;
24 | }
25 | h2{
26 | @include values.font-subheading();
27 | margin-bottom: values.$space-m;
28 | }
29 | p{
30 | margin-bottom: values.$space-m;
31 | @include values.font-body();
32 | }
33 | a{
34 | color: values.$color-primary;
35 |
36 | &:hover,
37 | &:focus{
38 | color: values.$color-primary-600;
39 | }
40 |
41 | &:active{
42 | color: values.$color-primary-700;
43 | }
44 | }
45 | em{
46 | font-style: italic;
47 | }
48 | strong{
49 | font-weight: bold;
50 | }
51 | small {
52 | font-size: 80%;
53 | }
54 | img {
55 | border: 0;
56 | vertical-align: middle;
57 | }
58 |
59 | ul {
60 | margin-top: 0;
61 | margin-bottom: 10px;
62 | }
63 |
64 | dl {
65 | margin-top: 0;
66 | margin-bottom: 20px;
67 | }
68 |
69 | dt {
70 | font-weight: 700;
71 | }
72 |
73 | pre {
74 | margin: 1em 0;
75 | padding: 20px;
76 | max-width: 100%;
77 | border: 1px solid values.$color-gray-200;
78 | color: values.$color-gray-800;
79 | line-height: 1.2em;
80 | background: values.$color-gray-100;
81 | border-radius: 5px;
82 | box-shadow: none;
83 | }
84 |
85 | code {
86 | padding: 0;
87 | color: values.$color-gray-800;
88 | font-size: .8em;
89 | line-height: 1em;
90 | font-weight: 400!important;
91 | background: values.$color-gray-100;
92 | border-radius: 3px;
93 | }
94 |
95 | :not(pre) code {
96 | padding: 0 5px 2px;
97 | box-shadow: none;
98 | }
99 |
100 | del {
101 | text-decoration: line-through;
102 | }
103 |
104 | @-ms-viewport {
105 | width: device-width;
106 | }
107 |
--------------------------------------------------------------------------------
/src/scss/components/_header.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 | @use "shadow";
3 |
4 | .header-main .popup a{
5 | display: block;
6 | }
7 | .header-main .popup a,
8 | .header-main .popup a:hover{
9 | color: values.$color-text;
10 | }
11 |
12 | /* Toolbar icon buttons */
13 | .icon-login,
14 | .icon-tools,
15 | .icon-rss,
16 | .icon-private,
17 | .icon-private-active,
18 | .icon-filter,
19 | .icon-plugin,
20 | .icon-logout{
21 | width: 30px;
22 | height: 30px;
23 | background-size: 20px;
24 | background-repeat: no-repeat;
25 | background-position: center center;
26 | margin-top: 15px;
27 | margin-left: 7px;
28 | border-radius: 50%;
29 |
30 | &:focus,
31 | &:hover{
32 | background-color: rgba(255, 255, 255, .2);
33 | }
34 | }
35 | .icon-unfold {
36 | width: 2rem;
37 | height: 2rem;
38 | display: flex;
39 | align-items: center;
40 | justify-content: center;
41 | font-size: 1.2rem;
42 | border-radius: 50%;
43 |
44 | &:focus,
45 | &:hover{
46 | background-color: rgba(255, 255, 255, .2);
47 | }
48 |
49 | .unfold & .mdi-chevron-down {
50 | &:before {
51 | content: "\F143";
52 | }
53 | }
54 | }
55 | .icon-edit,
56 | .icon-delete,
57 | .icon-qrcode{
58 | width: 24px;
59 | height: 24px;
60 | background-size: 24px;
61 | background-repeat: no-repeat;
62 | background-position: center center;
63 | display: inline-block;
64 | }
65 |
66 | .icon-header{
67 | position: relative;
68 | width: 30px;
69 | height: 30px;
70 | line-height: 30px;
71 | text-align: center;
72 | margin-top: 15px;
73 | margin-left: 7px;
74 | border-radius: 50%;
75 | font-size: 18px;
76 | color: #fff;
77 |
78 | &:focus,
79 | &:hover{
80 | background-color: rgba(255, 255, 255, .2);
81 | color: #fff;
82 | }
83 |
84 | &.filter-on{
85 | color: values.$color-alert;
86 | }
87 | }
88 |
89 |
90 | .header-button-filter {
91 | &.has-filter-readlater,
92 | &.has-filters {
93 | &::before {
94 | content: '';
95 | position: absolute;
96 | width: 7px;
97 | height: 7px;
98 | top: 4px;
99 | right: 4px;
100 | border-radius: 50%;
101 | background: values.$color-secondary;
102 | z-index: 10;
103 | }
104 | }
105 | }
106 |
107 | // Remove the readlater filter button from the original theme.
108 | a[href="/plugin/readitlater/toggle-filter"] {
109 | display: none;
110 | }
111 |
112 | .header-main{
113 | width: 100%;
114 | min-height: 56px;
115 | background-color: values.$color-primary;
116 | box-shadow: 0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28);
117 | margin-bottom: 15px;
118 |
119 | color: #fff;
120 | max-height: 56px;
121 |
122 | z-index: 10;
123 |
124 | a {
125 | color: #fff;
126 | text-decoration: none;
127 |
128 | &.header-brand{
129 | display: inline-block;
130 | padding: 0 15px;
131 | @include values.font-brand();
132 | color: #fff;
133 | text-decoration: none;
134 | line-height: 56px;
135 | height: 56px;
136 | max-width: 100%;
137 | @include values.truncate-ellipsis();
138 |
139 | &:hover{
140 | background-color: rgba(255,255,255,.15);
141 | }
142 | }
143 | }
144 |
145 | .header-nav{
146 | height: 56px;
147 | }
148 |
149 | .header-buttons{
150 | float: right;
151 | height: 56px;
152 |
153 | button{
154 | display: block;
155 | }
156 |
157 | & > *{
158 | display: block;
159 | float: right;
160 | }
161 | }
162 |
163 | .header-middle{
164 |
165 | a:hover{
166 | background-color: rgba(255, 255, 255, 0.15);
167 | }
168 |
169 |
170 | }
171 |
172 | .toolbar-link{
173 | text-align: center;
174 | margin: auto;
175 |
176 | overflow: hidden;
177 | text-overflow: ellipsis;
178 | white-space: nowrap;
179 |
180 | margin-top: 10px;
181 | margin-bottom: 10px;
182 | display: inline-block;
183 | }
184 |
185 | &.unfold{
186 | overflow: visible;
187 | max-height: none;
188 | }
189 |
190 | .dark-toolbar &{
191 | background-color: #000;
192 | }
193 | }
194 |
195 | @media (max-width: 1199px){
196 | .header-main{
197 | overflow: hidden;
198 | }
199 | }
200 |
201 | .toolbar-button-container{
202 | position: relative;
203 | }
204 |
205 | /* Subheader */
206 | .subheader{
207 | width: 100%;
208 | background-color: values.$color-primary-second;
209 |
210 | @extend .shadow-1;
211 |
212 | margin-top: -15px;
213 | margin-bottom: 15px;
214 |
215 | color: #fff;
216 |
217 | padding: values.$space-s;
218 |
219 | z-index: 5;
220 |
221 | .button,
222 | .button-inverse{
223 | display: block;
224 | float: left;
225 | color: #fff;
226 | margin-right: values.$space-t;
227 | }
228 |
229 | &.is-dark {
230 | background-color: values.$color-gray-800;
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/src/scss/components/_helpers.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | .nowrap{
4 | overflow: hidden;
5 | text-overflow: ellipsis;
6 | white-space: nowrap;
7 | }
8 |
9 | .no-border{
10 | border: none !important;
11 | }
12 |
13 | hr.darker{
14 | border-top-color: values.$color-gray-400;
15 | }
16 | hr.margin{
17 | margin-left: values.$space-xl;
18 | margin-right: values.$space-xl;
19 | }
20 |
21 | .is-bold {
22 | font-weight: bold;
23 | }
24 |
25 | .mts{
26 | margin-top: 5px;
27 | }
28 | .mtm{
29 | margin-top: 15px;
30 | }
31 | .mtl{
32 | margin-top: 30px;
33 | }
34 | .mbs{
35 | margin-bottom: 5px;
36 | }
37 | .mbm{
38 | margin-bottom: 15px;
39 | }
40 | .mbl{
41 | margin-bottom: 30px;
42 | }
43 | .dark{
44 | background-color: #000;
45 | }
46 |
47 | .round-image-container{
48 | width: 60px;
49 | height: 60px;
50 | border-radius: 50%;
51 | background-color: values.$color-gray-200;
52 | text-align: center;
53 |
54 | i{
55 | font-size: 45px;
56 | line-height: 60px;
57 |
58 | &.mdi-settings{
59 | color: #009688;
60 | }
61 | &.mdi-lock{
62 | color: #DB4437;
63 | }
64 | &.mdi-puzzle{
65 | color: #03A9F4;
66 | }
67 | &.mdi-tag-multiple{
68 | color: #FF9800;
69 | }
70 | &.mdi-file-import{
71 | color: #9C27B0;
72 | }
73 | &.mdi-file-export{
74 | color: #795548;
75 | }
76 | &.mdi-image {
77 | color: #9E9E9E;
78 | }
79 | &.mdi-server {
80 | color: #607D8B;
81 | }
82 | }
83 | }
84 | p.highlight{
85 | color: #F44336;
86 | }
87 |
88 | /* Nothing found */
89 | .nothing-found{
90 | text-align: center;
91 | @include values.font-display1();
92 | color: values.$color-gray-600;
93 | margin-bottom: 100px;
94 | }
95 |
96 | .text-left {
97 | text-align: left;
98 | }
99 |
100 | .text-right {
101 | text-align: right;
102 | }
103 |
104 | .text-center {
105 | text-align: center;
106 | }
107 |
108 | .text-warning {
109 | color: #FF9800;
110 | }
111 |
112 | .text-success{
113 | color: #4CAF50;
114 | }
115 |
116 | .text-error{
117 | color: #F44336;
118 | }
119 |
120 | .text-feedback{
121 | display: inline-block;
122 | margin-left: values.$space-s;
123 | margin-right: values.$space-s;
124 | font-style: italic;
125 | font-size: 90%;
126 | }
127 |
128 | .pull-left{
129 | float: left!important;
130 | }
131 | .pull-right {
132 | float: right!important;
133 | }
134 |
135 | .hidden {
136 | display: none!important;
137 | }
138 |
139 | .is-highlighted-hover{
140 | &:hover{
141 | background-color: values.$color-gray-hover-light;
142 | }
143 | }
144 |
145 | ul.is-bordered{
146 | li{
147 | padding: values.$space-t;
148 | border: 1px solid values.$color-gray-light;
149 | border-bottom: none;
150 | background-color: values.$color-gray-hover;
151 | text-overflow: ellipsis;
152 | white-space: nowrap;
153 | overflow: hidden;
154 |
155 | &:last-child{
156 | border-bottom: 1px solid values.$color-gray-light;
157 | }
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/src/scss/components/_icons.scss:
--------------------------------------------------------------------------------
1 | .mdi {
2 | display: inline-block;
3 | font: normal normal normal 24px/1 "Material";
4 | font-size: inherit;
5 | text-rendering: auto;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | transform: translate(0, 0);
9 | }
10 | .mdi-arrow-left:before {
11 | content: "\F04D";
12 | }
13 | .mdi-arrow-right:before {
14 | content: "\F054";
15 | }
16 | .mdi-menu:before {
17 | content: "\F35C";
18 | }
19 | .mdi-pencil:before{
20 | content: "\F3EB";
21 | }
22 | .mdi-delete:before {
23 | content: "\F1C0";
24 | }
25 | .mdi-magnify:before {
26 | content: "\F349";
27 | }
28 | .mdi-magnify-plus-outline:before {
29 | content: "\f6ec";
30 | }
31 | .mdi-tag:before{
32 | content: "\f4f9";
33 | }
34 | .mdi-filter:before{
35 | content: "\f232";
36 | }
37 | .mdi-rss:before{
38 | content: "\f46b";
39 | }
40 | .mdi-key:before{
41 | content: "\f306";
42 | }
43 | .mdi-settings:before{
44 | content: "\f493";
45 | }
46 | .mdi-logout:before{
47 | content: "\f343";
48 | }
49 | .mdi-account:before{
50 | content: "\f004";
51 | }
52 | .mdi-dots-vertical:before{
53 | content: "\f1d9";
54 | }
55 | .mdi-firefox:before{
56 | content: "\f239";
57 | }
58 | .mdi-google-chrome:before{
59 | content: "\f2af";
60 | }
61 | .mdi-android:before{
62 | content: "\f032";
63 | }
64 | .mdi-apple-ios:before{
65 | content: "\f037";
66 | }
67 | .mdi-lock:before{
68 | content: "\f33e";
69 | }
70 | .mdi-puzzle:before{
71 | content: "\f431";
72 | }
73 | .mdi-tag-multiple:before{
74 | content: "\f4fb";
75 | }
76 | .mdi-file-import:before{
77 | content: "\f220";
78 | }
79 | .mdi-file-export:before{
80 | content: "\f21d";
81 | }
82 | .mdi-plus:before{
83 | content: "\f415";
84 | }
85 | .mdi-note:before{
86 | content: "\f39a";
87 | }
88 | .mdi-checkbox-marked-outline:before{
89 | content: "\f135";
90 | }
91 | .mdi-link:before {
92 | content: "\F337";
93 | }
94 | .mdi-pin:before {
95 | content: "\F403";
96 | }
97 | .mdi-qrcode:before {
98 | content: "\F432";
99 | }
100 | .mdi-close:before {
101 | content: "\F156";
102 | }
103 | .mdi-image:before {
104 | content: "\F2E9";
105 | }
106 | .mdi-chevron-down:before {
107 | content: "\F140";
108 | }
109 | .mdi-check:before {
110 | content: "\F12C";
111 | }
112 | .mdi-circle:before {
113 | content:"\F764";
114 | }
115 | .mdi-server:before{
116 | content:"\F48B";
117 | }
118 | .mdi-playlist-plus:before{
119 | content:"\F412";
120 | }
121 |
--------------------------------------------------------------------------------
/src/scss/components/_layout.scss:
--------------------------------------------------------------------------------
1 | .is-flex {
2 | display: flex;
3 | align-items: center;
4 | justify-content: space-between;
5 | }
6 |
7 | .is-flex-grown {
8 | flex-grow: 1;
9 | }
10 |
11 | .is-flex-end {
12 | justify-self: flex-end;
13 | }
14 |
--------------------------------------------------------------------------------
/src/scss/components/_list.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | /* Generic classes */
4 | .list-label{
5 | @include values.font-subheading();
6 | color: values.$color-text;
7 | }
8 | .list-sublabel{
9 | margin-top: values.$space-t;
10 | @include values.font-caption();
11 | color: values.$color-gray-600;
12 | }
13 |
14 | .list-item{
15 | display: block;
16 | padding: values.$space-m;
17 | }
18 |
19 | .list-item-text{
20 | padding: values.$space-m;
21 | }
22 |
23 | // Controls (button with icon) displayed withing list item.
24 | .list-item-controls{
25 |
26 | display: flex;
27 | justify-content: space-around;
28 | align-items: center;
29 |
30 | .list-item-control{
31 | color: values.$color-gray-600;
32 | font-size: 20px;
33 | width: 35px;
34 | height: 35px;
35 | line-height: 35px;
36 | text-align: center;
37 | border-radius: 50%;
38 |
39 | &:hover,
40 | &:focus{
41 | background-color: values.$color-gray-200;
42 | }
43 |
44 | &:active{
45 | background-color: values.$color-gray-300;
46 | }
47 | }
48 |
49 | .is-control-visible-hover &{
50 | display: none;
51 | }
52 | .is-control-visible-hover:hover &{
53 | display: inherit;
54 | }
55 |
56 | .is-control-opaque-hover &{
57 | opacity: .5;
58 | }
59 | .is-control-opaque-hover:hover &{
60 | opacity: 1;
61 | }
62 | }
63 |
64 | .list-item-flex{
65 | display: flex;
66 | justify-content: space-between;
67 | align-items: center;
68 | background: #fff;
69 | border-top: 1px solid values.$color-gray-300;
70 |
71 | .card-header + &:first-child{
72 | border-top: 0;
73 | }
74 |
75 | &:last-child{
76 | border-bottom: 1px solid values.$color-gray-300;
77 | }
78 |
79 | .list-item-start{
80 | padding-left: values.$space-m;
81 | }
82 |
83 | .list-item-middle{
84 | flex-grow: 1;
85 | }
86 |
87 | .list-item-end{
88 | padding-right: values.$space-m;
89 | }
90 | }
91 |
92 | label.list-item-content{
93 | margin: 0;
94 | }
95 |
96 | /* List clickable */
97 | .list-action{
98 | .list-item{
99 | display: block;
100 | cursor: pointer;
101 | color: values.$color-text;
102 |
103 | border-top: 1px solid values.$color-gray-300;
104 |
105 | .card-header + &:first-child{
106 | border-top: 0;
107 | }
108 |
109 | &:last-child{
110 | border-bottom: 1px solid values.$color-gray-300;
111 | }
112 |
113 | &:hover,
114 | &:focus{
115 | background-color: values.$color-gray-200;
116 | text-decoration: none;
117 | }
118 |
119 | .list-item-label{
120 | @extend .list-label;
121 | }
122 |
123 | .list-item-sublabel{
124 | @extend .list-sublabel;
125 | }
126 | }
127 | }
128 |
129 | .list-action.list-big{
130 | .list-item-label{
131 | font-size: 1.2rem;
132 | }
133 |
134 | .list-item-sublabel{
135 | margin-top: values.$space-t;
136 | font-weight: 400;
137 | font-size: 1rem;
138 | color: values.$color-gray-600;
139 | }
140 | }
141 |
142 | /* List with a side content on the right (ex: a list of settings with checkboxes on the right) */
143 | .list-side-right{
144 | .list-item{
145 | display: flex;
146 | justify-content: space-between;
147 | align-items: center;
148 |
149 | padding: values.$space-l values.$space-m;
150 |
151 | border-top: 1px solid values.$color-gray-300;
152 |
153 | &:last-child{
154 | border-bottom: 1px solid values.$color-gray-300;
155 | }
156 | }
157 |
158 | .list-item-label{
159 | @extend .list-label;
160 | }
161 |
162 | .list-item-sublabel{
163 | @extend .list-sublabel;
164 | margin-top: values.$space-t;
165 | }
166 | }
167 |
168 |
169 | .list-sortable{
170 | .list-item{
171 | display: flex;
172 | flex-direction: row;
173 | flex-wrap: nowrap;
174 | justify-content: space-between;
175 | align-items: center;
176 |
177 | .list-item-content{
178 | flex: 1;
179 | }
180 | }
181 |
182 | .list-sortable-handle{
183 | padding: values.$space-s;
184 | cursor: move;
185 | font-size: 2rem;
186 | color: values.$color-gray-600;
187 | }
188 |
189 | .list-item-label{
190 | @extend .list-label;
191 | }
192 |
193 | .list-item-sublabel{
194 | @extend .list-sublabel;
195 | margin-top: values.$space-t;
196 | }
197 |
198 | }
199 |
200 | .list-checkable{
201 | input[type=checkbox]{
202 | display: block;
203 | margin-right: values.$space-m;
204 | }
205 | }
206 |
207 | .key-value-item {
208 | display: flex;
209 | justify-content: space-between;
210 | align-items: center;
211 | padding: values.$space-t 0;
212 | background: #fff;
213 | border: none;
214 |
215 | & > *:first-child {
216 | font-weight: bold;
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/src/scss/components/_markdown.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | .markdown {
4 | h1{
5 | font-size: 2.2em;
6 | }
7 | h2{
8 | font-size: 1.8em;
9 | }
10 | h3{
11 | font-size: 1.5em;
12 | }
13 | h4{
14 | font-size: 1.2em;
15 | }
16 | h5{
17 | font-size: 1em;
18 | }
19 | h6{
20 | font-size: 0.9em;
21 | }
22 |
23 | h1, h2, h3, h4, h5, h6 {
24 | font-weight: normal;
25 | font-style: normal;
26 | line-height: 1em;
27 | margin: .75em 0 .5em 0;
28 | }
29 |
30 | pre {
31 | margin: 1em 0;
32 | padding: 20px;
33 | max-width: 100%;
34 | border: 1px solid values.$color-gray-200;
35 | color: values.$color-gray-800;
36 | line-height: 1.2em;
37 | background: values.$color-gray-100;
38 | border-radius: 5px;
39 | box-shadow: none;
40 | }
41 |
42 | code {
43 | padding: 0;
44 | color: values.$color-gray-800;
45 | font-size: 1em;
46 | line-height: 1em;
47 | font-weight: 400!important;
48 | background: values.$color-gray-100;
49 | border-radius: 3px;
50 | }
51 |
52 | :not(pre) code {
53 | padding: 0 5px 2px;
54 | box-shadow: none;
55 | }
56 |
57 | ul,
58 | ol {
59 | padding-left: 3em;
60 | margin-bottom: 15px;
61 |
62 | li {
63 | list-style: unset;
64 | }
65 | }
66 |
67 | blockquote {
68 | border-left: 5px solid values.$color-gray-500;
69 | padding: 15px 30px;
70 | margin-bottom: 15px;
71 | background-color: values.$color-gray-100;
72 | }
73 |
74 | img {
75 | max-width: 100%;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/scss/components/_modal.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 | @use "animations";
3 | @use "shadow";
4 |
5 | .modal{
6 | // Overrides Bootstrap
7 | position: relative;
8 | display: block;
9 | top: auto;
10 | bottom: auto;
11 | left: auto;
12 | right: auto;
13 | z-index: 1;
14 | // End override Bootstrap
15 | margin-top: 10%;
16 | margin-top: 10vh;
17 | background: #fff;
18 | @extend .shadow-5;
19 | }
20 | .modal-title{
21 | padding: 20px 20px 10px 20px;
22 | line-height: inherit;
23 | @include values.font-title();
24 | }
25 | .modal-body{
26 | padding: 10px 20px 10px 20px;
27 | max-height: 55vh;
28 | overflow: auto;
29 | color: values.$color-gray-700;
30 | }
31 | .modal-footer{
32 | padding: 10px 20px 20px 20px;
33 | border: none;
34 | text-align: left;
35 | }
36 |
--------------------------------------------------------------------------------
/src/scss/components/_notification.scss:
--------------------------------------------------------------------------------
1 | @use "sass:math";
2 |
3 | @use "values";
4 | @use "shadow";
5 | @use "animations";
6 |
7 | .notifications {
8 | position: fixed;
9 | display: flex;
10 | flex-direction: column;
11 | align-items: flex-end;
12 | bottom: values.$space-l;
13 | right: values.$space-l;
14 | max-width: 400px;
15 | z-index: 1000;
16 |
17 | @media (max-width: 450px) {
18 | left: values.$space-s;
19 | right: values.$space-s;
20 | bottom: values.$space-s;
21 | }
22 |
23 | .notification:not(:last-child) {
24 | margin-bottom: values.$space-m;
25 | }
26 | }
27 |
28 | .notification {
29 | @extend .shadow-3;
30 | @extend .animate-slide-from-right;
31 |
32 | position: relative;
33 | padding: values.$space-l;
34 | padding-right: values.$space-xl;
35 |
36 | border-radius: values.$radius;
37 | background-color: values.$color-gray-100;
38 | opacity: 1;
39 |
40 | button.notification-close {
41 | position: absolute;
42 | top: 0;
43 | right: 0;
44 | padding: math.div(values.$space-t, 2) values.$space-t;
45 | color: values.$color-gray-600;
46 |
47 | &:hover,
48 | &:focus {
49 | background-color: rgba(10, 10, 10, .2);
50 | }
51 | }
52 |
53 | &.is-success {
54 | color: values.$color-success-900;
55 | background-color: values.$color-success-50;
56 | }
57 |
58 | &.is-warning {
59 | color: values.$color-warning-900;
60 | background-color: values.$color-warning-50;
61 | }
62 |
63 | &.is-danger {
64 | color: values.$color-danger-900;
65 | background-color: values.$color-danger-50;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/scss/components/_overlay.scss:
--------------------------------------------------------------------------------
1 | /* Search overlay */
2 | .fullscreen{
3 | position: fixed;
4 | left: 0;
5 | top: 0;
6 | right: 0;
7 | bottom: 0;
8 | background-color: rgba(0, 0, 0, .75);
9 | z-index: 200;
10 | }
11 | .fullscreen.visible{
12 | display: block;
13 | }
14 | .content-fullscreen{
15 | position: absolute;
16 | top: 30%;
17 | left: 0;
18 | right: 0;
19 | }
20 |
21 | .button-fullscreen{
22 | display: block;
23 | width: 100%;
24 | }
25 |
26 | /* QR codes overlay */
27 | #qrcode {
28 | img {
29 | margin: auto;
30 | border: 50px solid #fff;
31 | }
32 | }
33 |
34 | /* Generic overlay */
35 | .overlay{
36 | position: fixed;
37 | left: 0;
38 | top: 0;
39 | right: 0;
40 | bottom: 0;
41 | background-color: rgba(0, 0, 0, .75);
42 | z-index: 200;
43 | }
44 |
--------------------------------------------------------------------------------
/src/scss/components/_overrides.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | /* Awesomplete */
4 | .awesomplete ul{
5 | z-index: 400;
6 | border: 1px solid values.$color-gray-500;
7 | border-radius: 2px;
8 | }
9 | div.awesomplete{
10 | display: block;
11 |
12 | mark {
13 | padding: 0;
14 | }
15 | }
16 | div.awesomplete > input{
17 | display: inline-block;
18 | }
19 | div.awesomplete > ul{
20 | border: none;
21 | box-shadow: 0 8px 17px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);
22 | border-radius: 0;
23 | }
24 | div.awesomplete > ul:before{
25 | box-shadow: 0 8px 17px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);
26 | }
27 | div.awesomplete > ul > li{
28 | background-color: #fff;
29 | padding: 5px 10px;
30 | }
31 | div.awesomplete > ul > li:hover{
32 | background-color: values.$color-gray-200;
33 | }
34 | div.awesomplete li:hover mark{
35 | background-color: values.$color-gray-300;
36 | }
37 | div.awesomplete > ul > li[aria-selected=true]{
38 | background-color: values.$color-primary;
39 | color: #fff;
40 | }
41 | div.awesomplete > ul > li[aria-selected=true]:hover{
42 | // background-color: #1E88E5;
43 | background-color: values.$color-primary-700;
44 | }
45 | div.awesomplete li[aria-selected=true]:hover mark{
46 | background: #3c6b00;
47 | color: inherit;
48 | }
49 |
50 | /* Markdown */
51 | .md_help{
52 | color: inherit !important;
53 | }
54 |
55 | /* Sortable */
56 | .sortable-chosen{
57 | background: #fff;
58 | }
59 | .sortable-ghost{
60 | opacity: .5;
61 | background: #C8EBFB;
62 | }
63 |
--------------------------------------------------------------------------------
/src/scss/components/_page-daily.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 | @use "shadow";
3 | @use "icons";
4 |
5 | .daily-grid[data-columns]:before{
6 | content: '4 .column.size-1of4';
7 |
8 | @media screen and (max-width: 1200px) {
9 | content: '2 .column.size-1of2'
10 | }
11 |
12 | @media screen and (max-width: 768px) {
13 | content: '1 .column.size-1of1'
14 | }
15 | }
16 |
17 | .column {
18 | float: left;
19 | padding: 0 values.$space-m;
20 | }
21 |
22 | .size-1of4 {
23 | width: 25%;
24 | }
25 | .size-1of2 {
26 | width: 50%;
27 | }
28 | .size-1of1 {
29 | width: 100%;
30 | }
31 |
32 | .daily-header{
33 | text-align: center;
34 |
35 | h1{
36 | font-family: 'Old Newspaper Types', serif;
37 | font-size: 4rem;
38 | }
39 | }
40 |
41 | .daily-header-subtitle{
42 | color: values.$color-gray-600;
43 | }
44 |
45 | .daily-title{
46 | margin: values.$space-l 0 values.$space-xl 0;
47 | text-align: center;
48 | font-family: 'Old Newspaper Types', serif;
49 | font-size: 1.6rem;
50 | }
51 |
52 | .daily-item{
53 | position: relative;
54 |
55 | &:hover .daily-item-plus{
56 | display: block;
57 | }
58 |
59 | a{
60 | color: auto;
61 |
62 | &:hover{
63 | text-decoration: none;
64 | }
65 | }
66 | }
67 |
68 | .daily-card{
69 | @extend .shadow-1;
70 | display: block;
71 | margin-bottom: values.$space-l;
72 | color: inherit;
73 | border-radius: values.$radius-s;
74 | outline: 3px solid transparent;
75 | transition: all values.$animation-speed ease;
76 |
77 | &:hover,
78 | &:focus{
79 | @extend .shadow-2;
80 | }
81 | }
82 |
83 | .daily-item-header{
84 | display: block;
85 | background-color: values.$color-gray-100;
86 | padding: values.$space-s;
87 | color: values.$color-gray-700;
88 | border-radius: values.$radius-s values.$radius-s 0 0;
89 | transition: background-color values.$animation-speed ease;
90 |
91 | &:hover,
92 | &:focus{
93 | color: values.$color-gray-700;
94 | text-decoration: none;
95 | background-color: values.$color-gray-200;
96 | }
97 | }
98 |
99 | .daily-item-image{
100 | width: 100%;
101 | height: 100px;
102 | background-size: cover;
103 | background-position: center;
104 | }
105 |
106 | .daily-item-body{
107 | background-color: #fff;
108 | padding: values.$space-m;
109 | }
110 |
111 | .daily-item-footer{
112 | background-color: values.$color-gray-100;
113 | padding: values.$space-s;
114 | font-size: 80%;
115 | color: values.$color-gray-700;
116 | border-top: solid 1px rgba(values.$color-gray-700, 0.05);
117 | border-radius: 0 0 values.$radius-s values.$radius-s;
118 | }
119 |
120 | .daily-item-footer-subtitle{
121 | display: block;
122 | float: left;
123 | color: #ccc;
124 |
125 | &:hover{
126 | color: values.$color-gray-700;
127 |
128 | &:after{
129 | @extend .mdi;
130 | content: "\F337";
131 | animation: slide-from-right values.$animation-speed ease;
132 | }
133 | }
134 | }
135 |
136 | .daily-item-tags{
137 | text-align: right;
138 | }
139 |
--------------------------------------------------------------------------------
/src/scss/components/_page-linklist.scss:
--------------------------------------------------------------------------------
1 | @use "card";
2 | @use "values";
3 |
4 | /* Link list */
5 | .link-outer{
6 | @extend .card;
7 | position: relative;
8 | overflow: hidden;
9 |
10 | .links-list.is-selectable &.is-selected{
11 | box-shadow: 0 0 4px 4px values.$color-batch-selection;
12 | }
13 | }
14 | // Used for batch mode (delete).
15 | .link-overlay{
16 | display: none;
17 | position: absolute;
18 | top: 0;
19 | bottom: 0;
20 | left: 0;
21 | right: 0;
22 | cursor: pointer;
23 | z-index: 10;
24 |
25 | .links-list.is-selectable &:hover{
26 | background-color: rgba(values.$color-gray-300, 0.5);
27 | }
28 |
29 | .links-list.is-selectable &{
30 | display: block;
31 | background-color: rgba(#fff, 0);
32 | }
33 |
34 | .links-list.is-selectable .is-selected &{
35 | display: block;
36 | background-color: rgba(values.$color-alert, .5);
37 | }
38 | }
39 | .link-inner{
40 | border-radius: 2px 0 0 2px;
41 | }
42 | .link-header{
43 | @extend .card-header;
44 | border-bottom: none;
45 | padding-bottom: 5px;
46 | text-transform: none;
47 | }
48 | .link-content{
49 | overflow: hidden;
50 | }
51 | .link-footer{
52 | padding: 10px 15px 15px 15px;
53 | }
54 | a.link-title{
55 | display: block;
56 | margin-bottom: values.$space-t;
57 | text-overflow: ellipsis;
58 | color: values.$color-text;
59 | text-decoration: none;
60 | font-weight: bold;
61 | line-height: 1.2;
62 |
63 | &:hover,
64 | &:focus {
65 | color: values.$color-gray-800;
66 | }
67 |
68 | &:active {
69 | color: values.$color-gray-700;
70 | }
71 | }
72 | .private{
73 | &:before {
74 | content: '';
75 | position: absolute;
76 | display: block;
77 | width: 0;
78 | height: 0;
79 | border: 16px solid transparent;
80 | border-right: 16px solid #b71c1c;
81 | top: -16px;
82 | left: -16px;
83 | transform: rotate(45deg);
84 | }
85 |
86 | a.link-title{
87 | color: #b71c1c;
88 | }
89 | }
90 | a.link-url{
91 | display: block;
92 | margin-bottom: values.$space-t;
93 | color: values.$color-gray-600;
94 | text-decoration: none;
95 | line-height: 1em;
96 | overflow: hidden;
97 | text-overflow: ellipsis;
98 | white-space: nowrap;
99 | @include values.font-sub();
100 |
101 | &:hover,
102 | &:focus {
103 | color: values.$color-gray-700;
104 | }
105 |
106 | &:active {
107 | color: values.$color-gray-800;
108 | }
109 | }
110 | .link-date{
111 | @include values.font-sub();
112 | color: values.$color-gray-600;
113 | float: right;
114 |
115 | a,
116 | .link-archive {
117 | color: values.$color-gray-600;
118 | text-decoration: none;
119 |
120 | &:hover,
121 | &:focus {
122 | color: values.$color-text;
123 | }
124 |
125 | &:active {
126 | color: values.$color-gray-800;
127 | }
128 | }
129 | }
130 | .link-description{
131 | padding: 5px 15px;
132 |
133 | p:first-child{
134 | margin-top: 0;
135 | }
136 |
137 | p:last-child{
138 | margin-bottom: 0;
139 | }
140 | }
141 | .thumb img{
142 | margin: 15px;
143 | }
144 | .link-tag-list{
145 | overflow: hidden;
146 | overflow-x: auto;
147 | text-overflow: ellipsis;
148 | }
149 | .link-tag{
150 | display: inline-block;
151 |
152 | a{
153 | display: block;
154 | color: values.$color-gray-800;
155 | text-decoration: none;
156 | padding: 3px 10px;
157 | background-color: values.$color-gray-200;
158 | border-radius: 20px;
159 | font-size: .7rem;
160 |
161 | &:hover,
162 | &:focus {
163 | background-color: values.$color-gray-300;
164 | }
165 |
166 | &:active {
167 | background-color: values.$color-gray-400;
168 | }
169 | }
170 | }
171 |
172 | .link-tag-filter {
173 | display: inline-block;
174 | padding: 3px 3px 3px 10px;
175 | border-radius: 20px;
176 | background-color: values.$color-gray-200;
177 | color: values.$color-gray-800;
178 | text-decoration: none;
179 | border: 1px solid values.$color-gray-300;
180 |
181 | &:hover,
182 | &:focus {
183 | color: values.$color-gray-800;
184 | background-color: values.$color-gray-300;
185 | text-decoration: none;
186 | }
187 |
188 | &:active {
189 | color: values.$color-gray-800;
190 | background-color: values.$color-gray-400;
191 | text-decoration: none;
192 | }
193 |
194 | .remove {
195 | font-style: normal;
196 | background-color: #fff;
197 | border-radius: 50%;
198 | padding: 0 5px;
199 | padding-bottom: 1px;
200 | }
201 | }
202 | .link-actions{
203 | display: flex;
204 | align-items: center;
205 | justify-content: flex-end;
206 |
207 | height: 24px;
208 | text-align: right;
209 |
210 | a,
211 | span {
212 | color: values.$color-gray-700;
213 | font-size: 18px;
214 | }
215 |
216 | a {
217 | &.is-pinned {
218 | color: values.$color-primary;
219 | }
220 |
221 | &:hover,
222 | &:focus {
223 | color: values.$color-gray-800;
224 | }
225 |
226 | &:active {
227 | color: values.$color-gray-900;
228 | }
229 | }
230 |
231 | .is-selectable &{
232 | // Actions are hidden when the list is in batch select mode.
233 | display: none;
234 | }
235 | }
236 | .link-actions > *{
237 | display: block;
238 | width: 24px;
239 | right: 24px;
240 | margin-left: 5px;
241 | }
242 | .link-actions form > *{
243 | display: block;
244 | }
245 | /* Plugins in links */
246 | .link-plugin{
247 | &:not(:last-child){
248 | margin-right: values.$space-t;
249 | }
250 |
251 | &:nth-child(2){
252 | &:before{
253 | content: "-";
254 | margin: 0 values.$space-t;
255 | }
256 | }
257 | }
258 |
259 | .link-counter{
260 | margin-top: 20px;
261 | margin-bottom: 20px;
262 | color: values.$color-gray-700;
263 | }
264 |
265 | .favorite-tag{
266 | display: block;
267 | float: left;
268 | padding: values.$space-s;
269 | margin-right: values.$space-s;
270 | background-color: rgba(0, 0, 0, .05);
271 | color: values.$color-subtitle;
272 |
273 | &:hover,
274 | &:focus{
275 | background-color: rgba(0, 0, 0, .1);
276 | color: inherit;
277 | text-decoration: none;
278 | }
279 |
280 | &:active{
281 | background-color: rgba(0, 0, 0, .2);
282 | }
283 | }
284 |
285 | .search-highlight {
286 | background-color: #ff0;
287 | }
288 |
--------------------------------------------------------------------------------
/src/scss/components/_pager.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | .paging{
4 | .paging-links {
5 | display: flex;
6 | align-items: center;
7 | justify-content: flex-end;
8 | font-size: .9rem;
9 | color: values.$color-gray-600;
10 |
11 | .paging-current {
12 | margin-right: values.$space-m;
13 | }
14 |
15 | a{
16 | display: block;
17 | height: 35px;
18 | width: 35px;
19 | text-align: center;
20 | border-radius: 50%;
21 | line-height: 35px;
22 |
23 | color: values.$color-gray-600;
24 | font-size: 1.6rem;
25 |
26 | &:hover,
27 | &:focus {
28 | background-color: values.$color-gray-300;
29 | }
30 |
31 | &:active {
32 | background-color: values.$color-gray-400;
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/scss/components/_popup.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | .popup{
4 | position: absolute;
5 | top: 48px;
6 | right: 0px;
7 | min-width: 220px;
8 | color: values.$color-text;
9 | box-shadow: 0 2px 30px rgba(0, 0, 0, 0.2);
10 | background: #fff;
11 | line-height: 1.5;
12 | cursor: default;
13 | z-index: 50;
14 |
15 | h2 {
16 | padding: 0 values.$space-s;
17 | margin-top: values.$space-s;
18 | margin-bottom: values.$space-s;
19 | text-transform: uppercase;
20 | font-size: 12px;
21 | color: values.$color-subtitle;
22 | }
23 |
24 | label {
25 | margin-bottom: 0;
26 | font-size: 12px;
27 | color: values.$color-subtitle;
28 | }
29 |
30 | @media (max-width: 600px){
31 | position: fixed;
32 | overflow-x: auto;
33 | height: 100%;
34 | top: 0;
35 | left: 0;
36 | right: 0;
37 | }
38 | }
39 | .popup-title{
40 | font-weight: bold;
41 | background-color: values.$color-gray-200;
42 | padding: 10px;
43 | }
44 | .popup-close {
45 | width: 20px;
46 | height: 20px;
47 | line-height: 20px;
48 | float: right;
49 | border-radius: 50%;
50 |
51 | &:hover {
52 | background-color: #fff;
53 | }
54 | }
55 | .popup-body{
56 | padding: 10px 0 10px 0;
57 |
58 | .list-item {
59 | padding: values.$space-t values.$space-s;
60 | border: none;
61 |
62 | &:last-child {
63 | border-bottom: none;
64 | }
65 | }
66 |
67 | .list-item-label {
68 | font-size: .9rem;
69 | }
70 | }
71 | .popup ul{
72 | list-style: none;
73 | margin-bottom: 0;
74 | }
75 | .popup ul li{
76 | cursor: pointer;
77 | }
78 | .popup ul li a{
79 | display: block;
80 | padding: 5px 10px;
81 | }
82 | .popup ul li a:hover{
83 | background-color: values.$color-gray-200;
84 | }
85 | .popup input[type=text]{
86 | width: 100%;
87 | }
88 | .popup .popup-content-area{
89 | padding: 10px;
90 | }
91 |
--------------------------------------------------------------------------------
/src/scss/components/_progress.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | .progress-bar {
4 | width: 100%;
5 | height: 5px;
6 | margin-bottom: values.$space-m;
7 | float: none;
8 | background-color: rgba(values.$color-primary, .4);
9 | box-shadow: none;
10 |
11 | .is-inverted & {
12 | background-color: #fff;
13 | }
14 | }
15 |
16 | .progress-actual {
17 | background: values.$color-primary;
18 | width: 0%;
19 | height: 100%;
20 | transition: width .3s ease;
21 | }
22 |
23 | .progress-counter {
24 | font-size: 1.4rem;
25 |
26 | .is-inverted & {
27 | color: #fff;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/scss/components/_reset.scss:
--------------------------------------------------------------------------------
1 | html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;}
2 | button{
3 | border: medium none;
4 | margin: 0;
5 | padding: 0;
6 | outline: 0;
7 | background: transparent;
8 | }
--------------------------------------------------------------------------------
/src/scss/components/_ripple.scss:
--------------------------------------------------------------------------------
1 | .ripple .ripple-effect,.ripple-effect {
2 | background: #fff
3 | }
4 | @keyframes ripple-animation {
5 | from {
6 | -webkit-transform: scale(1);
7 | transform: scale(1);
8 | opacity: .25;
9 | visibility: visible
10 | }
11 |
12 | to {
13 | -webkit-transform: scale(50);
14 | transform: scale(50);
15 | opacity: 0;
16 | visibility: visible
17 | }
18 | }
19 | @keyframes ripple-animation-intense {
20 | from {
21 | -webkit-transform: scale(1);
22 | transform: scale(1);
23 | opacity: .5;
24 | visibility: visible
25 | }
26 |
27 | to {
28 | -webkit-transform: scale(50);
29 | transform: scale(50);
30 | opacity: 0;
31 | visibility: visible
32 | }
33 | }
34 |
35 | .ripple, .button, .button-raised{
36 | position: relative;
37 | overflow: hidden;
38 | /* Fixes the bug in Chrome that makes the ripple effect overflowing the container when it's rounded BUT unfortunately it hides box shadows. */
39 | -webkit-transform: translateZ(0);
40 | -moz-transform: translateZ(0);
41 | -ms-transform: translateZ(0);
42 | -o-transform: translateZ(0);
43 | transform: translateZ(0);
44 | }
45 | .ripple-effect {
46 | visibility: hidden;
47 | position: absolute;
48 | border-radius: 50%;
49 | width: 50px;
50 | height: 50px;
51 | pointer-events: none;
52 | -webkit-animation: ripple-animation-intense 2s;
53 | animation: ripple-animation-intense 2s;
54 | }
55 |
56 | .ripple-effect.stop-animation {
57 | -webkit-animation: none!important;
58 | animation: none!important
59 | }
60 |
61 | .ripple-primary .ripple-effect {
62 | background: #2196F3;
63 | }
64 |
--------------------------------------------------------------------------------
/src/scss/components/_shadow.scss:
--------------------------------------------------------------------------------
1 | .shadow-1 {
2 | box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
3 | }
4 |
5 | .shadow-2 {
6 | box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
7 | }
8 |
9 | .shadow-3 {
10 | box-shadow: 0 12px 15px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19);
11 | }
12 |
13 | .shadow-4 {
14 | box-shadow: 0 16px 28px 0 rgba(0, 0, 0, 0.22), 0 25px 55px 0 rgba(0, 0, 0, 0.21);
15 | }
16 |
17 | .shadow-5 {
18 | box-shadow: 0 27px 24px 0 rgba(0, 0, 0, 0.2), 0 40px 77px 0 rgba(0, 0, 0, 0.22);
19 | }
20 |
21 | .shadow-top-1 {
22 | box-shadow: 2px 0 5px 0 rgba(0, 0, 0, 0.16), 2px 0 10px 0 rgba(0, 0, 0, 0.12);
23 | }
24 |
25 | .shadow-button {
26 | box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 4px rgba(0, 0, 0, .24);
27 | }
28 |
29 | .shadow-button-hover {
30 | box-shadow: 0 0 4px rgba(0, 0, 0, .18), 0 2px 8px rgba(0, 0, 0, .36);
31 | }
32 |
33 | .shadow-button-floating {
34 | box-shadow: 0 0 4px rgba(0, 0, 0, .14), 0 4px 8px rgba(0, 0, 0, .28);
35 | }
36 |
37 | .shadow-button-floating-hover {
38 | box-shadow: 0 0 6px rgba(0, 0, 0, .16), 0 6px 12px rgba(0, 0, 0, .32);
39 | }
40 |
--------------------------------------------------------------------------------
/src/scss/components/_structure.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | /* Page specific */
4 | .page-login{
5 | margin-top: 50px;
6 | margin-bottom: 50px;
7 | }
8 | .page-add{
9 | margin-top: 50px;
10 | margin-bottom: 50px;
11 | }
12 | .page-edit{
13 | margin-top: 50px;
14 | margin-bottom: 50px;
15 | }
16 | .from-bookmarklet .page-edit{
17 | margin-top: 10px;
18 | margin-bottom: 10px;
19 | }
20 | .page-tools{
21 | margin-bottom: 50px;
22 | }
23 |
24 | /* Edit link */
25 | .button-header{
26 | position: absolute;
27 | width: 34px;
28 | height: 34px;
29 | top: 7px;
30 | right: 7px;
31 | background: center center no-repeat;
32 |
33 | &:hover,
34 | &:focus{
35 | background-color: values.$color-button-hover;
36 | }
37 |
38 | &:active{
39 | background-color: values.$color-button-active;
40 | }
41 | }
42 | .button-expand{
43 | background-image: url(img/arrow-expand.png);
44 |
45 | .is-expanded &{
46 | background-image: url(img/arrow-compress.png);
47 | }
48 | }
49 | .editlinkform {
50 | transition: margin values.$animation-speed ease-in-out;
51 |
52 | .page-edit-link-batch & {
53 | margin-top: 0;
54 | margin-bottom: 0;
55 | }
56 | }
57 | .is-batch-done {
58 | .card {
59 | max-height: 58px !important;
60 | overflow: hidden;
61 | }
62 |
63 | .card-overlay {
64 | background-color: rgba(255, 255, 255, 1);
65 | }
66 | }
67 |
68 | /* Picture wall */
69 | .picwall-pictureframe{
70 | float: left;
71 | position: relative;
72 | overflow: hidden;
73 | width: 120px;
74 | height: 90px;
75 | text-align: center;
76 | }
77 | .picwall-link{
78 | display: none;
79 | position: absolute;
80 | top: 0;
81 | left: 0;
82 | background-color: values.$color-gray-700;
83 | background-color: rgba(values.$color-gray-700, .7);
84 | color: #fff;
85 | @include values.font-caption();
86 | }
87 | .picwall-pictureframe:hover .picwall-link{
88 | display: block;
89 | text-decoration: none;
90 | }
91 | .picwall-link:hover{
92 | color: #fff;
93 | }
94 |
95 | /* Plugins */
96 | .plugin-actions{
97 | @include values.font-title();
98 | padding: 10px;
99 | line-height: 20px;
100 | }
101 |
102 | /* QRCode */
103 | #overlay-content-qrcode{
104 | z-index: 600;
105 | position: fixed;
106 | top: 20%;
107 | left: 0;
108 | width: 100%;
109 | text-align: center;
110 | }
111 |
112 | @media (min-width: 768px){
113 | .thumb{
114 | float: left;
115 | }
116 |
117 | .thumb:not(.hidden) + .link-description{
118 | padding-left: 150px;
119 | }
120 | }
121 |
122 | /* Plugin administration */
123 | .plugin-param {
124 | label {
125 | margin-bottom: 0;
126 | line-height: 1.2;
127 | }
128 |
129 | .sublabel {
130 | margin-top: 0;
131 | text-align: left;
132 | line-height: 1.5;
133 | }
134 |
135 | &:focus-within {
136 | .plugin-param-key label {
137 | color: values.$color-primary;
138 | }
139 | }
140 | }
141 | .plugin-param-key{
142 | line-height: 33px;
143 | }
144 |
145 | /* Thumbnail page */
146 | .thumbnail-placeholder {
147 | margin: auto;
148 | margin-bottom: values.$space-s;
149 | background-color: values.$color-gray-light;
150 | }
151 | .thumbnail-link-title {
152 | margin-bottom: values.$space-m;
153 | text-align: center;
154 | white-space: nowrap;
155 | text-overflow: ellipsis;
156 | overflow: hidden;
157 | }
158 | .progress-counter {
159 | text-align: right;
160 | }
161 |
162 | /* Search overlay */
163 | .search-overlay-actions {
164 | position: absolute;
165 | right: 20px;
166 | top: 20%;
167 |
168 | button {
169 | padding: 8px;
170 | border-radius: 50px;
171 | font-size: 14px;
172 | text-transform: lowercase;
173 | box-shadow: none;
174 |
175 | i {
176 | vertical-align: middle;
177 | }
178 |
179 | @media (max-width: 767px){
180 | width: 36px;
181 | height: 36px;
182 | text-align: center;
183 | border-radius: 50%;
184 | }
185 | }
186 | }
187 | #button-filter i {
188 | margin-right: 3px;
189 | }
190 |
--------------------------------------------------------------------------------
/src/scss/components/_table.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | table {
4 | width: 100%;
5 | }
6 |
7 | th,
8 | td {
9 | padding: values.$space-t values.$space-s;
10 |
11 | &:first-child {
12 | padding-left: 0;
13 | }
14 |
15 | &:last-child {
16 | padding-right: 0;
17 | }
18 | }
19 |
20 | th {
21 | font-weight: bold;
22 | }
23 |
24 | tr {
25 | border-bottom: 1px solid values.$color-gray-300;
26 | }
27 |
--------------------------------------------------------------------------------
/src/scss/components/_tag.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | .tag {
4 | padding: values.$space-t;
5 | font-size: .8rem;
6 | background-color: values.$color-gray-100;
7 | border-radius: 4px;
8 |
9 | &.is-light {
10 | &.is-success {
11 | background-color: #effaf3;
12 | color: #257942;
13 | }
14 |
15 | &.is-danger {
16 | background-color: #feecf0;
17 | color: #cc0f35;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/scss/components/_text.scss:
--------------------------------------------------------------------------------
1 | @use "values";
2 |
3 | .light-heading{
4 | @include values.font-subheading();
5 |
6 | color: values.$color-gray-600;
7 | }
--------------------------------------------------------------------------------
/src/scss/components/_values.scss:
--------------------------------------------------------------------------------
1 | @use "sass:color";
2 | // Typography.
3 | $font-stack: 'Roboto', sans-serif;
4 | $font-size: 16px;
5 |
6 | @mixin font-display4(){
7 | font-size: 8rem;
8 | font-weight: 200;
9 | }
10 | @mixin font-display3(){
11 | font-size: 4rem;
12 | font-weight: 400;
13 | }
14 | @mixin font-display2(){
15 | font-size: 3.2rem;
16 | font-weight: 400;
17 | }
18 | @mixin font-display1(){
19 | font-size: 2.4rem;
20 | font-weight: 400;
21 | }
22 | @mixin font-brand(){
23 | font-size: 1.4rem;
24 | font-weight: 300;
25 | }
26 | @mixin font-headline(){
27 | font-size: 1.7rem;
28 | font-weight: 400;
29 | }
30 | @mixin font-title(){
31 | font-size: 1.4rem;
32 | font-weight: 400;
33 | }
34 | @mixin font-subheading(){
35 | font-size: 1.1rem;
36 | font-weight: 400;
37 | }
38 | @mixin font-body2(){
39 | font-size: 1rem;
40 | font-weight: 500;
41 | }
42 | @mixin font-body(){
43 | font-size: 1rem;
44 | font-weight: 400;
45 | }
46 | @mixin font-caption(){
47 | font-size: 0.85rem;
48 | font-weight: 400;
49 | }
50 | @mixin font-sub(){
51 | font-size: 0.7rem;
52 | font-weight: 400;
53 | }
54 | @mixin font-button(){
55 | font-size: .95rem;
56 | font-weight: 400;
57 | text-transform: uppercase;
58 | }
59 |
60 | @mixin truncate-ellipsis(){
61 | text-overflow: ellipsis;
62 | overflow: hidden;
63 | white-space: nowrap;
64 | }
65 |
66 |
67 | // Colors.
68 | $color-primary-50: #e3f2fd;
69 | $color-primary-100: #bbdefb;
70 | $color-primary-200: #90caf9;
71 | $color-primary-300: #64b5f6;
72 | $color-primary-400: #42a5f5;
73 | $color-primary-500: #2196f3;
74 | $color-primary-600: #1e88e5;
75 | $color-primary-700: #1976d2;
76 | $color-primary-800: #1565c0;
77 | $color-primary-900: #0d47a1;
78 |
79 | $color-gray-100: #f8f9fa;
80 | $color-gray-150: #ecf0f3;
81 | $color-gray-200: #e0e6eb;
82 | $color-gray-300: #d3dce4;
83 | $color-gray-400: #cad3da;
84 | $color-gray-500: #abbdcb;
85 | $color-gray-600: #8f9eaf;
86 | $color-gray-700: #6d7988;
87 | $color-gray-800: #414d5a;
88 | $color-gray-900: #252d37;
89 |
90 | $color-success-50: #E8F5E9;
91 | $color-success-100: #C8E6C9;
92 | $color-success-200: #A5D6A7;
93 | $color-success-300: #81C784;
94 | $color-success-400: #66BB6A;
95 | $color-success-500: #4CAF50;
96 | $color-success-600: #43A047;
97 | $color-success-700: #388E3C;
98 | $color-success-800: #2E7D32;
99 | $color-success-900: #1B5E20;
100 |
101 | $color-danger-50: #FFEBEE;
102 | $color-danger-100: #FFCDD2;
103 | $color-danger-200: #EF9A9A;
104 | $color-danger-300: #E57373;
105 | $color-danger-400: #EF5350;
106 | $color-danger-500: #F44336;
107 | $color-danger-600: #E53935;
108 | $color-danger-700: #D32F2F;
109 | $color-danger-800: #C62828;
110 | $color-danger-900: #B71C1C;
111 |
112 | $color-warning-50: #FFF8E1;
113 | $color-warning-100: #FFECB3;
114 | $color-warning-200: #FFE082;
115 | $color-warning-300: #FFD54F;
116 | $color-warning-400: #FFCA28;
117 | $color-warning-500: #FFC107;
118 | $color-warning-600: #FFB300;
119 | $color-warning-700: #FFA000;
120 | $color-warning-800: #FF8F00;
121 | $color-warning-900: #FF6F00;
122 |
123 | $color-text: $color-gray-900;
124 | $color-primary: $color-primary-500;
125 | $color-primary-second: #1976D2; //1976D2
126 | $color-secondary: #F44336;
127 | $color-alert: #F44336;
128 | $color-firefox: #ea9c21;
129 | $color-subtitle: #999;
130 | $color-gray-light: #ddd;
131 | $color-gray-hover: #eee;
132 | $color-gray-hover-light: #f9f9f9;
133 | $color-gray-active: #ddd;
134 |
135 |
136 |
137 | $color-batch-selection: #ff9800;
138 |
139 | $color-transparent: rgba(255, 255, 255, 0);
140 | $color-form-active: $color-primary;
141 | $color-button-hover: rgba(153, 153, 153, .2);
142 | $color-button-active: rgba(100, 100, 100, .2);
143 | $color-button-raised: #E0E0E0;
144 | $color-button-disabled: rgba(0, 0, 0, .26);
145 | $color-button-raised-disabled: rgba(0, 0, 0, .12);
146 | $color-button-raised-disabled-text: rgba(0, 0, 0, .26);
147 | // Radio Buttons
148 | $radio-label-color: $color-text;
149 | $radio-fill-color: $color-form-active !default;
150 | $radio-empty-color: #5a5a5a !default;
151 | $color-radio-disabled: #9E9E9E;
152 | // Checkboxes
153 | $color-checkbox-disabled: $color-radio-disabled;
154 | // Switches
155 | $color-switch-disabled: $color-radio-disabled;
156 | $switch-bg-color: $color-form-active !default;
157 | $switch-checked-lever-bg: color.adjust(color.adjust($color-form-active, $lightness: 25%), $saturation: -50%) !default;
158 | $switch-unchecked-bg: #F1F1F1 !default;
159 | $switch-unchecked-lever-bg: #818181 !default;
160 |
161 |
162 | // Distances.
163 | $space-t: 5px;
164 | $space-s: 10px;
165 | $space-m: 15px;
166 | $space-l: 20px;
167 | $space-xl: 40px;
168 |
169 |
170 | // Radius.
171 | $radius-s: 2px;
172 | $radius: 5px;
173 |
174 |
175 | // Animations speed.
176 | $animation-speed: .25s;
177 | $animation-speed-long: 1s;
178 |
--------------------------------------------------------------------------------
/src/scss/styles.scss:
--------------------------------------------------------------------------------
1 | @use 'components/reset';
2 |
3 | @use 'components/fonts';
4 | @use 'components/values';
5 | @use 'components/animations';
6 | @use 'components/shadow';
7 | @use 'components/icons';
8 |
9 | @use 'components/overrides';
10 |
11 | @use 'components/global';
12 | @use 'components/helpers';
13 | @use 'components/layout';
14 |
15 | @use 'components/ripple';
16 | @use 'components/card';
17 | @use 'components/list';
18 | @use 'components/popup';
19 | @use 'components/button';
20 | @use 'components/modal';
21 | @use 'components/form';
22 | @use 'components/text';
23 | @use 'components/actionbar';
24 | @use 'components/progress';
25 | @use 'components/table';
26 | @use 'components/tag';
27 | @use 'components/notification';
28 |
29 | @use 'components/bookmarklet';
30 | @use 'components/header';
31 | @use 'components/pager';
32 | @use 'components/footer';
33 | @use 'components/overlay';
34 | @use 'components/structure';
35 | @use 'components/markdown';
36 |
37 | @use 'components/page-daily';
38 | @use 'components/page-linklist';
39 |
--------------------------------------------------------------------------------
/user.example.css:
--------------------------------------------------------------------------------
1 | /*
2 | This is an example of data/user.css file to change colors from Blue to Teal.
3 | Example color palettes available here: https://material.io/guidelines/style/color.html#color-color-palette
4 | - Base color: #009688
5 | - Focus color: #00796B
6 | - Active color: #004D40
7 | */
8 | div.awesomplete > ul > li[aria-selected=true],
9 | .button-primary,
10 | [type="radio"]:checked + label:after,
11 | [type="radio"].with-gap:checked + label:after,
12 | [type=checkbox].filled-in:checked + label:after,
13 | .switch label input[type=checkbox]:checked + .lever:after,
14 | .header-main {
15 | background-color: #009688;
16 | }
17 | .button-primary:hover, .button-primary:focus{
18 | background-color: #00796B;
19 | }
20 | .button-primary:active{
21 | background-color: #004D40;
22 | }
23 |
24 | a,
25 | label.active {
26 | color: #009688;
27 | }
28 |
29 | a:hover, a:focus {
30 | color: #00796B;
31 | }
32 |
33 | a:active {
34 | color: #004D40;
35 | }
36 |
37 | input[type=text]:focus,
38 | input[type=search]:focus,
39 | input[type=number]:focus,
40 | input[type=password]:focus,
41 | textarea:focus {
42 | border-color: #009688;
43 | box-shadow: 0 1px 0 #009688;
44 | outline: none;
45 | }
46 | input.input-big:focus{
47 | box-shadow: none;
48 | }
49 |
50 | select:focus,
51 | [type="radio"]:checked + label:after,
52 | [type="radio"].with-gap:checked + label:before,
53 | [type="radio"].with-gap:checked + label:after,
54 | [type="checkbox"]:checked + label:before,
55 | [type="checkbox"] :indeterminate + label:before,
56 | [type=checkbox].filled-in:checked + label:after {
57 | border-color: #009688;
58 | }
59 |
60 | .subheader{
61 | background-color: #00796B;
62 | }
--------------------------------------------------------------------------------