Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kakawait/hugo-tranquilpeak-theme.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThibaud Lepretre <thibaud.lepretre@gmail.com>2016-03-30 22:59:16 +0300
committerThibaud Lepretre <thibaud.lepretre@gmail.com>2016-10-01 14:14:57 +0300
commit5f212cd8263ea9a4bb2861347117d35b5710fa19 (patch)
tree9110ebcc4ab83bfb028d1ab1ebf49039d6e25b51 /src
parent129e0ee39e78cb60c376d56ccf98af1bb3f9b70a (diff)
Transform hexo template to hugo
- [x] show case Transformation - [x] _default - [x] single - [x] summary - [x] list - [x] index (aka layout) - [x] all-archives - [x] all-categories - [x] all-tags - [x] archives - [x] categories - [x] page - [x] post - [x] tag - [x] partials - [x] about - [x] archive-post - ~~[ ] archive~~ Not compatible replace by Taxonomy list (like `taxonomy/category.html` or `taxonomy/tag.html`) - [x] cover - [x] footer - [x] google-analytics - [x] head - [x] header - [x] index - [x] pagination - [x] post - [x] action - [x] category - [x] disqus - [x] gallery - [x] header-cover - [x] header - [x] meta - [x] share-options - [x] tag - [x] script - [x] sidebar --- Misc - [x] Rename `.Site.params.author.picture` to `.Site.Author.picture` - [x] Use new function `md5` for gravatar email - [x] Rename `.Site.params.gravatar_email` to `.Site.Author.gravatar` - [x] Refactor menu to use `Hugo` menu system - [x] Upgrade code to `1.9.1` (currently based on `1.7.1`) - [x] Support non-production and production css/js - [x] TOC ? - [x] Custom tag --- Not supported - Archives pages by years `/archives/2015` - Archives pages by month `/archives/2015/01`
Diffstat (limited to 'src')
-rwxr-xr-xsrc/images/cover-v1.2.0.jpgbin0 -> 343566 bytes
-rwxr-xr-xsrc/images/cover.jpgbin0 -> 248594 bytes
-rw-r--r--src/js/.eslintrc.json10
-rwxr-xr-xsrc/js/about.js123
-rwxr-xr-xsrc/js/archives-filter.js160
-rwxr-xr-xsrc/js/categories-filter.js166
-rwxr-xr-xsrc/js/codeblock-resizer.js58
-rwxr-xr-xsrc/js/fancybox.js61
-rwxr-xr-xsrc/js/header.js71
-rwxr-xr-xsrc/js/image-gallery.js105
-rwxr-xr-xsrc/js/post-bottom-bar.js71
-rwxr-xr-xsrc/js/search-modal.js213
-rwxr-xr-xsrc/js/share-options.js89
-rwxr-xr-xsrc/js/sidebar.js167
-rwxr-xr-xsrc/js/smartresize.js33
-rwxr-xr-xsrc/js/tabbed-codeblocks.js41
-rwxr-xr-xsrc/js/tags-filter.js136
-rwxr-xr-xsrc/scss/base/_base.scss194
-rwxr-xr-xsrc/scss/components/_alert.scss69
-rwxr-xr-xsrc/scss/components/_archive.scss36
-rwxr-xr-xsrc/scss/components/_box.scss14
-rwxr-xr-xsrc/scss/components/_button.scss52
-rwxr-xr-xsrc/scss/components/_caption.scss10
-rwxr-xr-xsrc/scss/components/_code.scss107
-rwxr-xr-xsrc/scss/components/_figure.scss60
-rwxr-xr-xsrc/scss/components/_form.scss22
-rwxr-xr-xsrc/scss/components/_hide.scss32
-rwxr-xr-xsrc/scss/components/_highlight-text.scss39
-rwxr-xr-xsrc/scss/components/_icon.scss17
-rwxr-xr-xsrc/scss/components/_image-gallery.scss78
-rwxr-xr-xsrc/scss/components/_link.scss19
-rwxr-xr-xsrc/scss/components/_main-content.scss7
-rwxr-xr-xsrc/scss/components/_markdown.scss32
-rwxr-xr-xsrc/scss/components/_media.scss23
-rwxr-xr-xsrc/scss/components/_modal.scss70
-rwxr-xr-xsrc/scss/components/_pagination.scss25
-rwxr-xr-xsrc/scss/components/_post-actions.scss83
-rwxr-xr-xsrc/scss/components/_post-header-cover.scss219
-rwxr-xr-xsrc/scss/components/_post.scss88
-rwxr-xr-xsrc/scss/components/_postShorten.scss156
-rwxr-xr-xsrc/scss/components/_pullquote.scss20
-rwxr-xr-xsrc/scss/components/_share-options-bar.scss105
-rwxr-xr-xsrc/scss/components/_tag.scss45
-rwxr-xr-xsrc/scss/components/_text.scss102
-rwxr-xr-xsrc/scss/components/_tooltip.scss166
-rwxr-xr-xsrc/scss/components/_video.scss20
-rwxr-xr-xsrc/scss/layouts/_about.scss113
-rwxr-xr-xsrc/scss/layouts/_blog.scss7
-rwxr-xr-xsrc/scss/layouts/_bottom-bar.scss119
-rwxr-xr-xsrc/scss/layouts/_cover.scss11
-rwxr-xr-xsrc/scss/layouts/_footer.scss8
-rwxr-xr-xsrc/scss/layouts/_header.scss112
-rwxr-xr-xsrc/scss/layouts/_main.scss127
-rwxr-xr-xsrc/scss/layouts/_sidebar.scss168
-rwxr-xr-xsrc/scss/pages/_search.scss60
-rwxr-xr-xsrc/scss/themes/_hljs-custom.scss51
-rwxr-xr-xsrc/scss/themes/_hljs-tranquilpeak.scss556
-rwxr-xr-xsrc/scss/tranquilpeak.scss66
-rwxr-xr-xsrc/scss/utils/_fonts.scss48
-rwxr-xr-xsrc/scss/utils/_variables.scss256
-rwxr-xr-xsrc/scss/utils/mixins/_bottom-bar.scss46
-rwxr-xr-xsrc/scss/utils/mixins/_button.scss19
-rwxr-xr-xsrc/scss/utils/mixins/_category.scss20
-rwxr-xr-xsrc/scss/utils/mixins/_form.scss13
-rwxr-xr-xsrc/scss/utils/mixins/_header.scss19
-rwxr-xr-xsrc/scss/utils/mixins/_main.scss48
-rwxr-xr-xsrc/scss/utils/mixins/_opacity.scss7
-rwxr-xr-xsrc/scss/utils/mixins/_post-header-cover.scss47
-rwxr-xr-xsrc/scss/utils/mixins/_prefix.scss11
-rwxr-xr-xsrc/scss/utils/mixins/_share-options-bar.scss20
-rwxr-xr-xsrc/scss/utils/mixins/_sidebar.scss197
-rwxr-xr-xsrc/scss/utils/mixins/_tag.scss20
72 files changed, 5583 insertions, 0 deletions
diff --git a/src/images/cover-v1.2.0.jpg b/src/images/cover-v1.2.0.jpg
new file mode 100755
index 0000000..2d5a0e1
--- /dev/null
+++ b/src/images/cover-v1.2.0.jpg
Binary files differ
diff --git a/src/images/cover.jpg b/src/images/cover.jpg
new file mode 100755
index 0000000..8956839
--- /dev/null
+++ b/src/images/cover.jpg
Binary files differ
diff --git a/src/js/.eslintrc.json b/src/js/.eslintrc.json
new file mode 100644
index 0000000..c7db13a
--- /dev/null
+++ b/src/js/.eslintrc.json
@@ -0,0 +1,10 @@
+{
+ "globals": {
+ "jQuery": false,
+ "moment": false,
+ "algoliaIndex": false
+ },
+ "env": {
+ "browser": true
+ }
+} \ No newline at end of file
diff --git a/src/js/about.js b/src/js/about.js
new file mode 100755
index 0000000..ba7c8ae
--- /dev/null
+++ b/src/js/about.js
@@ -0,0 +1,123 @@
+(function($) {
+ 'use strict';
+
+ // Fade out the blog and let drop the about card of the author and vice versa
+
+ /**
+ * AboutCard
+ * @constructor
+ */
+ var AboutCard = function() {
+ this.$openBtn = $("#sidebar, #header").find("a[href*='#about']");
+ this.$closeBtn = $('#about-btn-close');
+ this.$blog = $('#blog');
+ this.$about = $('#about');
+ this.$aboutCard = $('#about-card');
+ };
+
+ AboutCard.prototype = {
+
+ /**
+ * Run AboutCard feature
+ * @return {void}
+ */
+ run: function() {
+ var self = this;
+ // Detect click on open button
+ self.$openBtn.click(function(e) {
+ e.preventDefault();
+ self.play();
+ });
+ // Detect click on close button
+ self.$closeBtn.click(function(e) {
+ e.preventDefault();
+ self.playBack();
+ });
+ },
+
+ /**
+ * Play the animation
+ * @return {void}
+ */
+ play: function() {
+ var self = this;
+ // Fade out the blog
+ self.$blog.fadeOut();
+ // Fade in the about card
+ self.$about.fadeIn();
+ // Small timeout to drop the about card after that
+ // the about card fade in and the blog fade out
+ setTimeout(function() {
+ self.dropAboutCard();
+ }, 300);
+ },
+
+ /**
+ * Play back the animation
+ * @return {void}
+ */
+ playBack: function() {
+ var self = this;
+ // Lift the about card
+ self.liftAboutCard();
+ // Fade in the blog after that the about card lifted up
+ setTimeout(function() {
+ self.$blog.fadeIn();
+ }, 500);
+ // Fade out the about card after that the about card lifted up
+ setTimeout(function() {
+ self.$about.fadeOut();
+ }, 500);
+ },
+
+ /**
+ * Slide the card to the middle
+ * @return {void}
+ */
+ dropAboutCard: function() {
+ var self = this;
+ var aboutCardHeight = self.$aboutCard.innerHeight();
+ // default offset from top
+ var offsetTop = ($(window).height() / 2) - (aboutCardHeight / 2) + aboutCardHeight;
+ // if card is longer than the window
+ // scroll is enable
+ // and re-define offsetTop
+ if (aboutCardHeight + 30 > $(window).height()) {
+ offsetTop = aboutCardHeight;
+ }
+ self.$aboutCard
+ .css('top', '0px')
+ .css('top', '-' + aboutCardHeight + 'px')
+ .show(500, function() {
+ self.$aboutCard.animate({
+ top: '+=' + offsetTop + 'px'
+ });
+ });
+ },
+
+ /**
+ * Slide the card to the top
+ * @return {void}
+ */
+ liftAboutCard: function() {
+ var self = this;
+ var aboutCardHeight = self.$aboutCard.innerHeight();
+ // default offset from top
+ var offsetTop = ($(window).height() / 2) - (aboutCardHeight / 2) + aboutCardHeight;
+ if (aboutCardHeight + 30 > $(window).height()) {
+ offsetTop = aboutCardHeight;
+ }
+ self.$aboutCard.animate({
+ top: '-=' + offsetTop + 'px'
+ }, 500, function() {
+ self.$aboutCard.hide();
+ self.$aboutCard.removeAttr('style');
+ });
+ }
+ };
+
+ $(document).ready(function() {
+ var aboutCard = new AboutCard();
+ aboutCard.run();
+ });
+})(jQuery);
diff --git a/src/js/archives-filter.js b/src/js/archives-filter.js
new file mode 100755
index 0000000..49a0d29
--- /dev/null
+++ b/src/js/archives-filter.js
@@ -0,0 +1,160 @@
+(function($) {
+ 'use strict';
+
+ // Filter posts by using their date on archives page : `/archives`
+
+ /**
+ * ArchivesFilter
+ * @param {String} archivesElem
+ * @constructor
+ */
+ var ArchivesFilter = function(archivesElem) {
+ this.$form = $(archivesElem).find('#filter-form');
+ this.$searchInput = $(archivesElem).find('input[name=date]');
+ this.$archiveResult = $(archivesElem).find('.archive-result');
+ this.$postsYear = $(archivesElem).find('.archive-year');
+ this.$postsMonth = $(archivesElem).find('.archive-month');
+ this.$postsDay = $(archivesElem).find('.archive-day');
+ this.postsYear = archivesElem + ' .archive-year';
+ this.postsMonth = archivesElem + ' .archive-month';
+ this.postsDay = archivesElem + ' .archive-day';
+ this.messages = {
+ zero: this.$archiveResult.data('message-zero'),
+ one: this.$archiveResult.data('message-one'),
+ other: this.$archiveResult.data('message-other')
+ };
+ };
+
+ ArchivesFilter.prototype = {
+
+ /**
+ * Run ArchivesFilter feature
+ * @return {void}
+ */
+ run: function() {
+ var self = this;
+
+ self.$searchInput.keyup(function() {
+ self.filter(self.sliceDate(self.getSearch()));
+ });
+
+ // Block submit action
+ self.$form.submit(function(e) {
+ e.preventDefault();
+ });
+ },
+
+ /**
+ * Get Filter entered by user
+ * @returns {String} The date entered by the user
+ */
+ getSearch: function() {
+ return this.$searchInput.val().replace(/([\/|.|-])/g, '').toLowerCase();
+ },
+
+ /**
+ * Slice the date by year, month and day
+ * @param {String} date - The date of the post
+ * @returns {Array} The date of the post splitted in a list
+ */
+ sliceDate: function(date) {
+ return [
+ date.slice(0, 4),
+ date.slice(4, 6),
+ date.slice(6)
+ ];
+ },
+
+ /**
+ * Show related posts and hide others
+ * @param {String} date - The date of the post
+ * @returns {void}
+ */
+ filter: function(date) {
+ var numberPosts;
+
+ // Check if the search is empty
+ if (date[0] === '') {
+ this.showAll();
+ this.showResult(-1);
+ }
+ else {
+ numberPosts = this.countPosts(date);
+
+ this.hideAll();
+ this.showResult(numberPosts);
+
+ if (numberPosts > 0) {
+ this.showPosts(date);
+ }
+ }
+ },
+
+ /**
+ * Display results
+ * @param {Number} numbPosts - The number of posts found
+ * @returns {void}
+ */
+ showResult: function(numbPosts) {
+ if (numbPosts === -1) {
+ this.$archiveResult.html('').hide();
+ }
+ else if (numbPosts === 0) {
+ this.$archiveResult.html(this.messages.zero).show();
+ }
+ else if (numbPosts === 1) {
+ this.$archiveResult.html(this.messages.one).show();
+ }
+ else {
+ this.$archiveResult.html(this.messages.other.replace(/\{n\}/, numbPosts)).show();
+ }
+ },
+
+ /**
+ * Count number of posts
+ * @param {String} date - The date of the post
+ * @returns {Number} The number of posts found
+ */
+ countPosts: function(date) {
+ return $(this.postsDay + '[data-date^=' + date[0] + date[1] + date[2] + ']').length;
+ },
+
+ /**
+ * Show all posts from a date
+ * @param {String} date - The date of the post
+ * @returns {void}
+ */
+ showPosts: function(date) {
+ $(this.postsYear + '[data-date^=' + date[0] + ']').show();
+ $(this.postsMonth + '[data-date^=' + date[0] + date[1] + ']').show();
+ $(this.postsDay + '[data-date^=' + date[0] + date[1] + date[2] + ']').show();
+ },
+
+ /**
+ * Show all posts
+ * @returns {void}
+ */
+ showAll: function() {
+ this.$postsYear.show();
+ this.$postsMonth.show();
+ this.$postsDay.show();
+ },
+
+ /**
+ * Hide all posts
+ * @returns {void}
+ */
+ hideAll: function() {
+ this.$postsYear.hide();
+ this.$postsMonth.hide();
+ this.$postsDay.hide();
+ }
+ };
+
+ $(document).ready(function() {
+ if ($('#archives').length) {
+ var archivesFilter = new ArchivesFilter('#archives');
+ archivesFilter.run();
+ }
+ });
+})(jQuery);
diff --git a/src/js/categories-filter.js b/src/js/categories-filter.js
new file mode 100755
index 0000000..d3c8a53
--- /dev/null
+++ b/src/js/categories-filter.js
@@ -0,0 +1,166 @@
+(function($) {
+ 'use strict';
+
+ // Filter posts by using their categories on categories page : `/categories`
+
+ /**
+ * CategoriesFilter
+ * @param {String} categoriesArchivesElem
+ * @constructor
+ */
+ var CategoriesFilter = function(categoriesArchivesElem) {
+ this.$form = $(categoriesArchivesElem).find('#filter-form');
+ this.$inputSearch = $(categoriesArchivesElem).find('input[name=category]');
+ // Element where result of the filter are displayed
+ this.$archiveResult = $(categoriesArchivesElem).find('.archive-result');
+ this.$posts = $(categoriesArchivesElem).find('.archive');
+ this.$categories = $(categoriesArchivesElem).find('.category-anchor');
+ this.posts = categoriesArchivesElem + ' .archive';
+ this.categories = categoriesArchivesElem + ' .category-anchor';
+ // Html data attribute without `data-` of `.archive` element
+ // which contains the name of category
+ this.dataCategory = 'category';
+ // Html data attribute without `data-` of `.archive` element
+ // which contains the name of parent's categories
+ this.dataParentCategories = 'parent-categories';
+ this.messages = {
+ zero: this.$archiveResult.data('message-zero'),
+ one: this.$archiveResult.data('message-one'),
+ other: this.$archiveResult.data('message-other')
+ };
+ };
+
+ CategoriesFilter.prototype = {
+
+ /**
+ * Run CategoriesFilter feature
+ * @return {void}
+ */
+ run: function() {
+ var self = this;
+
+ self.$inputSearch.keyup(function() {
+ self.filter(self.getSearch());
+ });
+
+ // Block submit action
+ self.$form.submit(function(e) {
+ e.preventDefault();
+ });
+ },
+
+ /**
+ * Get the search entered by user
+ * @returns {String} The name of the category
+ */
+ getSearch: function() {
+ return this.$inputSearch.val().toLowerCase();
+ },
+
+ /**
+ * Show related posts form a category and hide the others
+ * @param {string} category - The name of the category
+ * @return {void}
+ */
+ filter: function(category) {
+ if (category === '') {
+ this.showAll();
+ this.showResult(-1);
+ }
+ else {
+ this.hideAll();
+ this.showPosts(category);
+ this.showResult(this.countCategories(category));
+ }
+ },
+
+ /**
+ * Display results of the search
+ * @param {Number} numbCategories - The number of categories found
+ * @return {void}
+ */
+ showResult: function(numbCategories) {
+ if (numbCategories === -1) {
+ this.$archiveResult.html('').hide();
+ }
+ else if (numbCategories === 0) {
+ this.$archiveResult.html(this.messages.zero).show();
+ }
+ else if (numbCategories === 1) {
+ this.$archiveResult.html(this.messages.one).show();
+ }
+ else {
+ this.$archiveResult.html(this.messages.other.replace(/\{n\}/, numbCategories)).show();
+ }
+ },
+
+ /**
+ * Count number of categories
+ * @param {String} category - The name of theThe date of the post category
+ * @returns {Number} The number of categories found
+ */
+ countCategories: function(category) {
+ return $(this.posts + '[data-' + this.dataCategory + '*=\'' + category + '\']').length;
+ },
+
+ /**
+ * Show all posts from a category
+ * @param {String} category - The name of the category
+ * @return {void}
+ */
+ showPosts: function(category) {
+ var self = this;
+ var parents;
+ var categories = self.categories + '[data-' + self.dataCategory + '*=\'' + category + '\']';
+ var posts = self.posts + '[data-' + self.dataCategory + '*=\'' + category + '\']';
+
+ if (self.countCategories(category) > 0) {
+ // Check if selected categories have parents
+ if ($(categories + '[data-' + self.dataParentCategories + ']').length) {
+ // Get all categories that matches search
+ $(categories).each(function() {
+ // Get all its parents categories name
+ parents = $(this).attr('data-' + self.dataParentCategories).split(',');
+ // Show only the title of the parents's categories and hide their posts
+ parents.forEach(function(parent) {
+ var dataAttr = '[data-' + self.dataCategory + '=\'' + parent + '\']';
+ $(self.categories + dataAttr).show();
+ $(self.posts + dataAttr).show();
+ $(self.posts + dataAttr + ' > .archive-posts > .archive-post').hide();
+ });
+ });
+ }
+ }
+ // Show categories and related posts found
+ $(categories).show();
+ $(posts).show();
+ $(posts + ' > .archive-posts > .archive-post').show();
+ },
+
+ /**
+ * Show all categories and all posts
+ * @return {void}
+ */
+ showAll: function() {
+ this.$categories.show();
+ this.$posts.show();
+ $(this.posts + ' > .archive-posts > .archive-post').show();
+ },
+
+ /**
+ * Hide all categories and all posts
+ * @return {void}
+ */
+ hideAll: function() {
+ this.$categories.hide();
+ this.$posts.hide();
+ }
+ };
+
+ $(document).ready(function() {
+ if ($('#categories-archives').length) {
+ var categoriesFilter = new CategoriesFilter('#categories-archives');
+ categoriesFilter.run();
+ }
+ });
+})(jQuery);
diff --git a/src/js/codeblock-resizer.js b/src/js/codeblock-resizer.js
new file mode 100755
index 0000000..0228cc2
--- /dev/null
+++ b/src/js/codeblock-resizer.js
@@ -0,0 +1,58 @@
+(function($) {
+ 'use strict';
+
+ // Resize code blocks to fit the screen width
+
+ /**
+ * Code block resizer
+ * @param {String} elem
+ * @constructor
+ */
+ var CodeBlockResizer = function(elem) {
+ this.$codeBlocks = $(elem);
+ };
+
+ CodeBlockResizer.prototype = {
+ /**
+ * Run main feature
+ * @return {void}
+ */
+ run: function() {
+ var self = this;
+ // resize all codeblocks
+ self.resize();
+ // resize codeblocks when window is resized
+ $(window).smartresize(function() {
+ self.resize();
+ });
+ },
+
+ /**
+ * Resize codeblocks
+ * @return {void}
+ */
+ resize: function() {
+ var self = this;
+ self.$codeBlocks.each(function() {
+ var $gutter = $(this).find('.gutter');
+ var $code = $(this).find('.code');
+ // get padding of code div
+ var codePaddings = $code.width() - $code.innerWidth();
+ // code block div width with padding - gutter div with padding + code div padding
+ var width = $(this).outerWidth() - $gutter.outerWidth() + codePaddings;
+ // apply new width
+ $code.css('width', width);
+ $code.children('pre').css('width', width);
+ });
+ }
+ };
+
+ $(document).ready(function() {
+ // register jQuery function to check if an element has an horizontal scroll bar
+ $.fn.hasHorizontalScrollBar = function() {
+ return this.get(0).scrollWidth > this.innerWidth();
+ };
+ var resizer = new CodeBlockResizer('figure.highlight');
+ resizer.run();
+ });
+})(jQuery);
diff --git a/src/js/fancybox.js b/src/js/fancybox.js
new file mode 100755
index 0000000..e06e4df
--- /dev/null
+++ b/src/js/fancybox.js
@@ -0,0 +1,61 @@
+(function($) {
+ 'use strict';
+
+ // Run fancybox feature
+
+ $(document).ready(function() {
+ /**
+ * Configure and run Fancybox plugin
+ * @returns {void}
+ */
+ function fancyFox() {
+ var arrows = true;
+ var thumbs = null;
+
+ // disable navigation arrows and display thumbs on medium and large screens
+ if ($(window).height() > 480) {
+ arrows = false;
+ thumbs = {
+ width: 70,
+ height: 70
+ };
+ }
+
+ $('.fancybox').fancybox({
+ maxWidth: 900,
+ maxHeight: 800,
+ fitToView: true,
+ width: '50%',
+ height: '50%',
+ autoSize: true,
+ arrows: arrows,
+ closeClick: false,
+ openEffect: 'elastic',
+ closeEffect: 'elastic',
+ prevEffect: 'none',
+ nextEffect: 'none',
+ padding: '0',
+ helpers: {
+ thumbs: thumbs,
+ overlay: {
+ css: {
+ overflow: 'hidden',
+ background: 'rgba(0, 0, 0, 0.85)'
+ }
+ }
+ },
+ afterLoad: function() {
+ setTimeout(function() {
+ $('.fancybox-next > span, .fancybox-prev > span').css('visibility', 'visible');
+ }, 400);
+ }
+ });
+ }
+
+ fancyFox();
+
+ $(window).smartresize(function() {
+ fancyFox();
+ });
+ });
+})(jQuery);
diff --git a/src/js/header.js b/src/js/header.js
new file mode 100755
index 0000000..3b499cc
--- /dev/null
+++ b/src/js/header.js
@@ -0,0 +1,71 @@
+(function($) {
+ 'use strict';
+
+ // Hide the header when the user scrolls down, and show it when he scrolls up
+
+ /**
+ * Header
+ * @constructor
+ */
+ var Header = function() {
+ this.$header = $('#header');
+ this.headerHeight = this.$header.height();
+ // CSS class located in `source/_css/layout/_header.scss`
+ this.headerUpCSSClass = 'header-up';
+ this.delta = 5;
+ this.lastScrollTop = 0;
+ };
+
+ Header.prototype = {
+
+ /**
+ * Run Header feature
+ * @return {void}
+ */
+ run: function() {
+ var self = this;
+ var didScroll;
+
+ // Detect if the user is scrolling
+ $(window).scroll(function() {
+ didScroll = true;
+ });
+
+ // Check if the user scrolled every 250 milliseconds
+ setInterval(function() {
+ if (didScroll) {
+ self.animate();
+ didScroll = false;
+ }
+ }, 250);
+ },
+
+ /**
+ * Animate the header
+ * @return {void}
+ */
+ animate: function() {
+ var scrollTop = $(window).scrollTop();
+
+ // Check if the user scrolled more than `delta`
+ if (Math.abs(this.lastScrollTop - scrollTop) <= this.delta) {
+ return;
+ }
+
+ // Checks if the user has scrolled enough down and has past the navbar
+ if ((scrollTop > this.lastScrollTop) && (scrollTop > this.headerHeight)) {
+ this.$header.addClass(this.headerUpCSSClass);
+ }
+ else if (scrollTop + $(window).height() < $(document).height()) {
+ this.$header.removeClass(this.headerUpCSSClass);
+ }
+
+ this.lastScrollTop = scrollTop;
+ }
+ };
+
+ $(document).ready(function() {
+ var header = new Header();
+ header.run();
+ });
+})(jQuery);
diff --git a/src/js/image-gallery.js b/src/js/image-gallery.js
new file mode 100755
index 0000000..39c377d
--- /dev/null
+++ b/src/js/image-gallery.js
@@ -0,0 +1,105 @@
+(function($) {
+ 'use strict';
+
+ // Resize all images of an image-gallery
+
+ /**
+ * ImageGallery
+ * @constructor
+ */
+ var ImageGallery = function() {
+ // CSS class located in `source/_css/components/_image-gallery.scss`
+ this.photosBox = '.photo-box';
+ this.$images = $(this.photosBox + ' img');
+ };
+ ImageGallery.prototype = {
+
+ /**
+ * Run ImageGallery feature
+ * @return {void}
+ */
+ run: function() {
+ var self = this;
+
+ // Resize all images at the loading of the page
+ self.resizeImages();
+
+ // Resize all images when the user is resizing the page
+ $(window).smartresize(function() {
+ self.resizeImages();
+ });
+ },
+
+ /**
+ * Resize all images of an image gallery
+ * @return {void}
+ */
+ resizeImages: function() {
+ var photoBoxWidth;
+ var photoBoxHeight;
+ var imageWidth;
+ var imageHeight;
+ var imageRatio;
+ var $image;
+
+ this.$images.each(function() {
+ $image = $(this);
+ photoBoxWidth = $image.parent().parent().width();
+ photoBoxHeight = $image.parent().parent().innerHeight();
+ imageWidth = $image.width();
+ imageHeight = $image.height();
+
+ // Checks if image height is smaller than his box
+ if (imageHeight < photoBoxHeight) {
+ imageRatio = (imageWidth / imageHeight);
+ // Resize image with the box height
+ $image.css({
+ height: photoBoxHeight,
+ width: (photoBoxHeight * imageRatio)
+ });
+ // Center image in his box
+ $image.parent().css({
+ left: '-' + (((photoBoxHeight * imageRatio) / 2) - (photoBoxWidth / 2)) + 'px'
+ });
+ }
+
+ // Update new values of height and width
+ imageWidth = $image.width();
+ imageHeight = $image.height();
+
+ // Checks if image width is smaller than his box
+ if (imageWidth < photoBoxWidth) {
+ imageRatio = (imageHeight / imageWidth);
+
+ $image.css({
+ width: photoBoxWidth,
+ height: (photoBoxWidth * imageRatio)
+ });
+ // Center image in his box
+ $image.parent().css({
+ top: '-' + (((imageHeight) / 2) - (photoBoxHeight / 2)) + 'px'
+ });
+ }
+
+ // Checks if image height is larger than his box
+ if (imageHeight > photoBoxHeight) {
+ // Center image in his box
+ $image.parent().css({
+ top: '-' + (((imageHeight) / 2) - (photoBoxHeight / 2)) + 'px'
+ });
+ }
+ });
+ }
+ };
+
+ $(document).ready(function() {
+ if ($('.image-gallery').length) {
+ var imageGallery = new ImageGallery();
+
+ // Small timeout to wait the loading of all images.
+ setTimeout(function() {
+ imageGallery.run();
+ }, 500);
+ }
+ });
+})(jQuery);
diff --git a/src/js/post-bottom-bar.js b/src/js/post-bottom-bar.js
new file mode 100755
index 0000000..20fd5e9
--- /dev/null
+++ b/src/js/post-bottom-bar.js
@@ -0,0 +1,71 @@
+(function($) {
+ 'use strict';
+
+ // Hide the post bottom bar when the post footer is visible by the user,
+ // and show it when the post footer isn't visible by the user
+
+ /**
+ * PostBottomBar
+ * @constructor
+ */
+ var PostBottomBar = function() {
+ this.$postBottomBar = $('.post-bottom-bar');
+ this.$postFooter = $('.post-actions-wrap');
+ this.$header = $('#header');
+ this.delta = 1;
+ this.lastScrollTop = 0;
+ };
+
+ PostBottomBar.prototype = {
+
+ /**
+ * Run PostBottomBar feature
+ * @return {void}
+ */
+ run: function() {
+ var self = this;
+ var didScroll;
+ // Run animation for first time
+ self.swipePostBottomBar();
+ // Detects if the user is scrolling
+ $(window).scroll(function() {
+ didScroll = true;
+ });
+ // Check if the user scrolled every 250 milliseconds
+ setInterval(function() {
+ if (didScroll) {
+ self.swipePostBottomBar();
+ didScroll = false;
+ }
+ }, 250);
+ },
+
+ /**
+ * Swipe the post bottom bar
+ * @return {void}
+ */
+ swipePostBottomBar: function() {
+ var scrollTop = $(window).scrollTop();
+ var postFooterOffsetTop = this.$postFooter.offset().top;
+ // show bottom bar
+ // if the user scrolled upwards more than `delta`
+ // and `post-footer` div isn't visible
+ if (this.lastScrollTop > scrollTop &&
+ (postFooterOffsetTop + this.$postFooter.height() > scrollTop + $(window).height() ||
+ postFooterOffsetTop < scrollTop + this.$header.height())) {
+ this.$postBottomBar.slideDown();
+ }
+ else {
+ this.$postBottomBar.slideUp();
+ }
+ this.lastScrollTop = scrollTop;
+ }
+ };
+
+ $(document).ready(function() {
+ if ($('.post-bottom-bar').length) {
+ var postBottomBar = new PostBottomBar();
+ postBottomBar.run();
+ }
+ });
+})(jQuery);
diff --git a/src/js/search-modal.js b/src/js/search-modal.js
new file mode 100755
index 0000000..cfd1e50
--- /dev/null
+++ b/src/js/search-modal.js
@@ -0,0 +1,213 @@
+(function($) {
+ 'use strict';
+
+ /**
+ * Search modal with Algolia
+ * @constructor
+ */
+ var SearchModal = function() {
+ this.$openButton = $('.open-algolia-search');
+ this.$searchModal = $('#algolia-search-modal');
+ this.$closeButton = this.$searchModal.find('.close-button');
+ this.$searchForm = $('#algolia-search-form');
+ this.$searchInput = $('#algolia-search-input');
+ this.$results = this.$searchModal.find('.results');
+ this.$noResults = this.$searchModal.find('.no-result');
+ this.$resultsCount = this.$searchModal.find('.results-count');
+ this.algolia = algoliaIndex;
+ };
+
+ SearchModal.prototype = {
+ /**
+ * Run feature
+ * @returns {void}
+ */
+ run: function() {
+ var self = this;
+
+ // open modal when open button is clicked
+ self.$openButton.click(function() {
+ self.open();
+ });
+
+ // open modal when `s` button is pressed
+ $(document).keyup(function(event) {
+ var target = event.target || event.srcElement;
+ // exit if user is focusing an input
+ if (target.tagName.toUpperCase() === 'INPUT') {
+ return;
+ }
+
+ if (event.keyCode === 83 && !self.$searchModal.is(':visible')) {
+ self.open();
+ }
+ });
+
+ // close button when overlay is clicked
+ self.$searchModal.click(function(e) {
+ if (e.target === this) {
+ self.close();
+ }
+ });
+
+ // close modal when close button is clicked
+ self.$closeButton.click(function() {
+ self.close();
+ });
+
+ // close modal when `ESC` button is pressed
+ $(document).keyup(function(e) {
+ if (e.keyCode === 27 && self.$searchModal.is(':visible')) {
+ self.close();
+ }
+ });
+
+ // send search when form is submitted
+ self.$searchForm.submit(function(event) {
+ event.preventDefault();
+ self.search(self.$searchInput.val());
+ });
+ },
+
+ /**
+ * Open search modal and display overlay
+ * @returns {void}
+ */
+ open: function() {
+ this.showSearchModal();
+ this.showOverlay();
+ this.$searchInput.focus();
+ },
+
+ /**
+ * Close search modal and overlay
+ * @returns {void}
+ */
+ close: function() {
+ this.hideSearchModal();
+ this.hideOverlay();
+ this.$searchInput.blur();
+ },
+
+ /**
+ * Search with Algolia API and display results
+ * @param {String} search
+ * @returns {void}
+ */
+ search: function(search) {
+ var self = this;
+ this.algolia.search(search, function(err, content) {
+ if (!err) {
+ self.showResults(content.hits);
+ self.showResultsCount(content.nbHits);
+ }
+ });
+ },
+
+ /**
+ * Display results
+ * @param {Array} posts
+ * @returns {void}
+ */
+ showResults: function(posts) {
+ var html = '';
+ posts.forEach(function(post) {
+ var lang = window.navigator.userLanguage || window.navigator.language || post.lang;
+
+ html += '<div class="media">';
+ if (post.thumbnailImageUrl) {
+ html += '<div class="media-left">';
+ html += '<a class="link-unstyled" href="' + (post.link || post.permalink) + '">';
+ html += '<img class="media-image" ' +
+ 'src="' + post.thumbnailImageUrl + '" ' +
+ 'width="90" height="90"/>';
+ html += '</a>';
+ html += '</div>';
+ }
+
+ html += '<div class="media-body">';
+ html += '<a class="link-unstyled" href="' + (post.link || post.permalink) + '">';
+ html += '<h3 class="media-heading">' + post.title + '</h3>';
+ html += '</a>';
+ html += '<span class="media-meta">';
+ html += '<span class="media-date text-small">';
+ html += moment(post.date).locale(lang).format('ll');
+ html += '</span>';
+ html += '</span>';
+ html += '<div class="media-content hide-xs font-merryweather">' + post.excerpt + '</div>';
+ html += '</div>';
+ html += '<div style="clear:both;"></div>';
+ html += '<hr>';
+ html += '</div>';
+ });
+ this.$results.html(html);
+ },
+
+ /**
+ * Show search modal
+ * @returns {void}
+ */
+ showSearchModal: function() {
+ this.$searchModal.fadeIn();
+ },
+
+ /**
+ * Hide search modal
+ * @returns {void}
+ */
+ hideSearchModal: function() {
+ this.$searchModal.fadeOut();
+ },
+
+ /**
+ * Display messages and counts of results
+ * @param {Number} count
+ * @returns {void}
+ */
+ showResultsCount: function(count) {
+ var string = '';
+ if (count < 1) {
+ string = this.$resultsCount.data('message-zero');
+ this.$noResults.show();
+ }
+ else if (count === 1) {
+ string = this.$resultsCount.data('message-one');
+ this.$noResults.hide();
+ }
+ else if (count > 1) {
+ string = this.$resultsCount.data('message-other').replace(/\{n\}/, count);
+ this.$noResults.hide();
+ }
+ this.$resultsCount.html(string);
+ },
+
+ /**
+ * Show overlay
+ * @returns {void}
+ */
+ showOverlay: function() {
+ $('body').append('<div class="overlay"></div>');
+ $('.overlay').fadeIn();
+ $('body').css('overflow', 'hidden');
+ },
+
+ /**
+ * Hide overlay
+ * @returns {void}
+ */
+ hideOverlay: function() {
+ $('.overlay').fadeOut(function() {
+ $(this).remove();
+ $('body').css('overflow', 'auto');
+ });
+ }
+ };
+
+ $(document).ready(function() {
+ // launch feature only if there is an Algolia index available
+ if (typeof algoliaIndex !== 'undefined') {
+ var searchModal = new SearchModal();
+ searchModal.run();
+ }
+ });
+})(jQuery);
diff --git a/src/js/share-options.js b/src/js/share-options.js
new file mode 100755
index 0000000..5ea077b
--- /dev/null
+++ b/src/js/share-options.js
@@ -0,0 +1,89 @@
+(function($) {
+ 'use strict';
+
+ // Open and close the share options bar
+
+ /**
+ * ShareOptionsBar
+ * @constructor
+ */
+ var ShareOptionsBar = function() {
+ this.$shareOptionsBar = $('#share-options-bar');
+ this.$openBtn = $('.btn-open-shareoptions');
+ this.$closeBtn = $('#share-options-mask');
+ };
+
+ ShareOptionsBar.prototype = {
+
+ /**
+ * Run ShareOptionsBar feature
+ * @return {void}
+ */
+ run: function() {
+ var self = this;
+
+ // Detect the click on the open button
+ self.$openBtn.click(function() {
+ if (!self.$shareOptionsBar.hasClass('opened')) {
+ self.openShareOptions();
+ self.$closeBtn.show();
+ }
+ });
+
+ // Detect the click on the close button
+ self.$closeBtn.click(function() {
+ if (self.$shareOptionsBar.hasClass('opened')) {
+ self.closeShareOptions();
+ self.$closeBtn.hide();
+ }
+ });
+ },
+
+ /**
+ * Open share options bar
+ * @return {void}
+ */
+ openShareOptions: function() {
+ var self = this;
+
+ // Check if the share option bar isn't opened
+ // and prevent multiple click on the open button with `.processing` class
+ if (!self.$shareOptionsBar.hasClass('opened') &&
+ !this.$shareOptionsBar.hasClass('processing')) {
+ // Open the share option bar
+ self.$shareOptionsBar.addClass('processing opened');
+
+ setTimeout(function() {
+ self.$shareOptionsBar.removeClass('processing');
+ }, 250);
+ }
+ },
+
+ /**
+ * Close share options bar
+ * @return {void}
+ */
+ closeShareOptions: function() {
+ var self = this;
+
+ // Check if the share options bar is opened
+ // and prevent multiple click on the close button with `.processing` class
+ if (self.$shareOptionsBar.hasClass('opened') &&
+ !this.$shareOptionsBar.hasClass('processing')) {
+ // Close the share option bar
+ self.$shareOptionsBar
+ .addClass('processing')
+ .removeClass('opened');
+
+ setTimeout(function() {
+ self.$shareOptionsBar.removeClass('processing');
+ }, 250);
+ }
+ }
+ };
+
+ $(document).ready(function() {
+ var shareOptionsBar = new ShareOptionsBar();
+ shareOptionsBar.run();
+ });
+})(jQuery);
diff --git a/src/js/sidebar.js b/src/js/sidebar.js
new file mode 100755
index 0000000..7016678
--- /dev/null
+++ b/src/js/sidebar.js
@@ -0,0 +1,167 @@
+(function($) {
+ 'use strict';
+
+ // Open and close the sidebar by swiping the sidebar and the blog and vice versa
+
+ /**
+ * Sidebar
+ * @constructor
+ */
+ var Sidebar = function() {
+ this.$sidebar = $('#sidebar');
+ this.$openBtn = $('#btn-open-sidebar');
+ // Elements where the user can click to close the sidebar
+ this.$closeBtn = $('#header, #main, .post-header-cover');
+ // Elements affected by the swipe of the sidebar
+ // The `pushed` class is added to each elements
+ // Each element has a different behavior when the sidebar is opened
+ this.$blog = $('.post-bottom-bar, #header, #main, .post-header-cover');
+ // If you change value of `mediumScreenWidth`,
+ // you have to change value of `$screen-min: (md-min)` too
+ // in `source/_css/utils/variables.scss`
+ this.$body = $('body');
+ this.mediumScreenWidth = 768;
+ };
+
+ Sidebar.prototype = {
+ /**
+ * Run Sidebar feature
+ * @return {void}
+ */
+ run: function() {
+ var self = this;
+ // Detect the click on the open button
+ this.$openBtn.click(function() {
+ if (!self.$sidebar.hasClass('pushed')) {
+ self.openSidebar();
+ }
+ });
+ // Detect the click on close button
+ this.$closeBtn.click(function() {
+ if (self.$sidebar.hasClass('pushed')) {
+ self.closeSidebar();
+ }
+ });
+ // Detect resize of the windows
+ $(window).resize(function() {
+ // Check if the window is larger than the minimal medium screen value
+ if ($(window).width() > self.mediumScreenWidth) {
+ self.resetSidebarPosition();
+ self.resetBlogPosition();
+ }
+ else {
+ self.closeSidebar();
+ }
+ });
+ },
+
+ /**
+ * Open the sidebar by swiping to the right the sidebar and the blog
+ * @return {void}
+ */
+ openSidebar: function() {
+ this.swipeBlogToRight();
+ this.swipeSidebarToRight();
+ },
+
+ /**
+ * Close the sidebar by swiping to the left the sidebar and the blog
+ * @return {void}
+ */
+ closeSidebar: function() {
+ this.swipeSidebarToLeft();
+ this.swipeBlogToLeft();
+ },
+
+ /**
+ * Reset sidebar position
+ * @return {void}
+ */
+ resetSidebarPosition: function() {
+ this.$sidebar.removeClass('pushed');
+ },
+
+ /**
+ * Reset blog position
+ * @return {void}
+ */
+ resetBlogPosition: function() {
+ this.$blog.removeClass('pushed');
+ },
+
+ /**
+ * Swipe the sidebar to the right
+ * @return {void}
+ */
+ swipeSidebarToRight: function() {
+ var self = this;
+ // Check if the sidebar isn't swiped
+ // and prevent multiple click on the open button with `.processing` class
+ if (!this.$sidebar.hasClass('pushed') && !this.$sidebar.hasClass('processing')) {
+ // Swipe the sidebar to the right
+ this.$sidebar.addClass('processing pushed');
+ // add overflow on body to remove horizontal scroll
+ this.$body.css('overflow-x', 'hidden');
+ setTimeout(function() {
+ self.$sidebar.removeClass('processing');
+ }, 250);
+ }
+ },
+
+ /**
+ * Swipe the sidebar to the left
+ * @return {void}
+ */
+ swipeSidebarToLeft: function() {
+ // Check if the sidebar is swiped
+ // and prevent multiple click on the close button with `.processing` class
+ if (this.$sidebar.hasClass('pushed') && !this.$sidebar.hasClass('processing')) {
+ // Swipe the sidebar to the left
+ this.$sidebar.addClass('processing').removeClass('pushed processing');
+ // go back to the default overflow
+ this.$body.css('overflow-x', 'auto');
+ }
+ },
+
+ /**
+ * Swipe the blog to the right
+ * @return {void}
+ */
+ swipeBlogToRight: function() {
+ var self = this;
+ // Check if the blog isn't swiped
+ // and prevent multiple click on the open button with `.processing` class
+ if (!this.$blog.hasClass('pushed') && !this.$blog.hasClass('processing')) {
+ // Swipe the blog to the right
+ this.$blog.addClass('processing pushed');
+
+ setTimeout(function() {
+ self.$blog.removeClass('processing');
+ }, 250);
+ }
+ },
+
+ /**
+ * Swipe the blog to the left
+ * @return {void}
+ */
+ swipeBlogToLeft: function() {
+ var self = this;
+ // Check if the blog is swiped
+ // and prevent multiple click on the close button with `.processing` class
+ if (self.$blog.hasClass('pushed') && !this.$blog.hasClass('processing')) {
+ // Swipe the blog to the left
+ self.$blog.addClass('processing').removeClass('pushed');
+
+ setTimeout(function() {
+ self.$blog.removeClass('processing');
+ }, 250);
+ }
+ }
+ };
+
+ $(document).ready(function() {
+ var sidebar = new Sidebar();
+ sidebar.run();
+ });
+})(jQuery);
diff --git a/src/js/smartresize.js b/src/js/smartresize.js
new file mode 100755
index 0000000..3b51497
--- /dev/null
+++ b/src/js/smartresize.js
@@ -0,0 +1,33 @@
+(function($, sr) {
+ // debouncing function from John Hann
+ // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
+ var debounce = function(func, threshold, execAsap) {
+ var timeout;
+
+ return function debounced() {
+ var obj = this;
+ var args = arguments;
+
+ function delayed() {
+ if (!execAsap) {
+ func.apply(obj, args);
+ }
+
+ timeout = null;
+ }
+
+ if (timeout) {
+ clearTimeout(timeout);
+ }
+ else if (execAsap) {
+ func.apply(obj, args);
+ }
+
+ timeout = setTimeout(delayed, threshold || 100);
+ };
+ };
+
+ jQuery.fn[sr] = function(fn) {
+ return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr);
+ };
+})(jQuery, 'smartresize');
diff --git a/src/js/tabbed-codeblocks.js b/src/js/tabbed-codeblocks.js
new file mode 100755
index 0000000..234901a
--- /dev/null
+++ b/src/js/tabbed-codeblocks.js
@@ -0,0 +1,41 @@
+(function($) {
+ 'use strict';
+
+ // Animate tabs of tabbed code blocks
+
+ /**
+ * TabbedCodeBlock
+ * @param {String} elems
+ * @constructor
+ */
+ var TabbedCodeBlock = function(elems) {
+ this.$tabbedCodeBlocs = $(elems);
+ };
+
+ TabbedCodeBlock.prototype = {
+ /**
+ * Run TabbedCodeBlock feature
+ * @return {void}
+ */
+ run: function() {
+ var self = this;
+ self.$tabbedCodeBlocs.find('.tab').click(function() {
+ var $codeblock = $(this).parent().parent().parent();
+ var $tabsContent = $codeblock.find('.tabs-content').children('pre, .highlight');
+ // remove `active` css class on all tabs
+ $(this).siblings().removeClass('active');
+ // add `active` css class on the clicked tab
+ $(this).addClass('active');
+ // hide all tab contents
+ $tabsContent.hide();
+ // show only the right one
+ $tabsContent.eq($(this).index()).show();
+ });
+ }
+ };
+
+ $(document).ready(function() {
+ var tabbedCodeBlocks = new TabbedCodeBlock('.codeblock--tabbed');
+ tabbedCodeBlocks.run();
+ });
+})(jQuery);
diff --git a/src/js/tags-filter.js b/src/js/tags-filter.js
new file mode 100755
index 0000000..967e799
--- /dev/null
+++ b/src/js/tags-filter.js
@@ -0,0 +1,136 @@
+(function($) {
+ 'use strict';
+
+ // Filter posts by using their categories on categories page : `/categories`
+
+ /**
+ * TagsFilter
+ * @param {String} tagsArchivesElem
+ * @constructor
+ */
+ var TagsFilter = function(tagsArchivesElem) {
+ this.$form = $(tagsArchivesElem).find('#filter-form');
+ this.$inputSearch = $(tagsArchivesElem + ' #filter-form input[name=tag]');
+ this.$archiveResult = $(tagsArchivesElem).find('.archive-result');
+ this.$tags = $(tagsArchivesElem).find('.tag');
+ this.$posts = $(tagsArchivesElem).find('.archive');
+ this.tags = tagsArchivesElem + ' .tag';
+ this.posts = tagsArchivesElem + ' .archive';
+ // Html data attribute without `data-` of `.archive` element which contains the name of tag
+ this.dataTag = 'tag';
+ this.messages = {
+ zero: this.$archiveResult.data('message-zero'),
+ one: this.$archiveResult.data('message-one'),
+ other: this.$archiveResult.data('message-other')
+ };
+ };
+
+ TagsFilter.prototype = {
+ /**
+ * Run TagsFilter feature
+ * @return {void}
+ */
+ run: function() {
+ var self = this;
+
+ // Detect keystroke of the user
+ self.$inputSearch.keyup(function() {
+ self.filter(self.getSearch());
+ });
+
+ // Block submit action
+ self.$form.submit(function(e) {
+ e.preventDefault();
+ });
+ },
+
+ /**
+ * Get the search entered by user
+ * @returns {String} the name of tag entered by the user
+ */
+ getSearch: function() {
+ return this.$inputSearch.val().toLowerCase();
+ },
+
+ /**
+ * Show related posts form a tag and hide the others
+ * @param {String} tag - name of a tag
+ * @return {void}
+ */
+ filter: function(tag) {
+ if (tag === '') {
+ this.showAll();
+ this.showResult(-1);
+ }
+ else {
+ this.hideAll();
+ this.showPosts(tag);
+ this.showResult(this.countTags(tag));
+ }
+ },
+
+ /**
+ * Display results of the search
+ * @param {Number} numbTags - Number of tags found
+ * @return {void}
+ */
+ showResult: function(numbTags) {
+ if (numbTags === -1) {
+ this.$archiveResult.html('').hide();
+ }
+ else if (numbTags === 0) {
+ this.$archiveResult.html(this.messages.zero).show();
+ }
+ else if (numbTags === 1) {
+ this.$archiveResult.html(this.messages.one).show();
+ }
+ else {
+ this.$archiveResult.html(this.messages.other.replace(/\{n\}/, numbTags)).show();
+ }
+ },
+
+ /**
+ * Count number of tags
+ * @param {String} tag
+ * @returns {Number}
+ */
+ countTags: function(tag) {
+ return $(this.posts + '[data-' + this.dataTag + '*=\'' + tag + '\']').length;
+ },
+
+ /**
+ * Show all posts from a tag
+ * @param {String} tag - name of a tag
+ * @return {void}
+ */
+ showPosts: function(tag) {
+ $(this.tags + '[data-' + this.dataTag + '*=\'' + tag + '\']').show();
+ $(this.posts + '[data-' + this.dataTag + '*=\'' + tag + '\']').show();
+ },
+
+ /**
+ * Show all tags and all posts
+ * @return {void}
+ */
+ showAll: function() {
+ this.$tags.show();
+ this.$posts.show();
+ },
+
+ /**
+ * Hide all tags and all posts
+ * @return {void}
+ */
+ hideAll: function() {
+ this.$tags.hide();
+ this.$posts.hide();
+ }
+ };
+
+ $(document).ready(function() {
+ if ($('#tags-archives').length) {
+ var tagsFilter = new TagsFilter('#tags-archives');
+ tagsFilter.run();
+ }
+ });
+})(jQuery);
diff --git a/src/scss/base/_base.scss b/src/scss/base/_base.scss
new file mode 100755
index 0000000..617eccf
--- /dev/null
+++ b/src/scss/base/_base.scss
@@ -0,0 +1,194 @@
+html {
+ font-family: $font-family-base;
+ // equal to 10px, useful to use em and rem
+ font-size: 10px;
+ // Gives you better control of the font size when the first selected font is not available.
+ @include prefix(text-size-adjust, 100%, 'ms' 'webkit');
+ // Overrides the highlight color shown when the user taps
+ //a link or a JavaScript clickable element in Safari on iPhone
+ @include prefix(tap-highlight-color, rgba(0, 0, 0, 0), 'webkit');
+}
+
+body {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ background: white;
+ font-family: $font-family-base;
+ font-size: map-get($font-size, base);
+ line-height: $line-height-base;
+ letter-spacing: $letter-spacing-base;
+ // Improve smoothing of the font by adding subpixel in Safari
+ @include prefix(font-smoothing, subpixel-antialiased, 'webkit');
+
+ // Hide overflow-x when the sidebar is swiped
+ &.pushed {
+ overflow-x: hidden;
+ }
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ letter-spacing: -0.04em;
+ font-family: map-get($font-families, 'headings');
+ font-weight: 700;
+ line-height: 1.45em;
+ color: #4a4a4a;
+}
+
+h1,
+h2,
+h3 {
+ margin: 1em 0 1em 0;
+}
+
+h4,
+h5,
+h6 {
+ margin: 1em 0 0.5em 0;
+}
+
+// List each header with his font size
+@each $key, $value in $headings-font-size {
+ #{$key} {
+ font-size: $value;
+ }
+}
+
+p {
+ margin: 0 0 1.5em 0;
+}
+
+ul,
+ol,
+dl {
+ margin: 0 0 0.5em 0;
+}
+
+a {
+ &,
+ &:hover,
+ &:active,
+ &:visited {
+ cursor: pointer;
+ color: map-get($colors, link);
+ text-decoration: none;
+ }
+ &:hover {
+ color: map-get($colors, link);
+ text-decoration: underline;
+ }
+}
+
+table {
+ width: 100%;
+ background: transparent;
+ border-collapse: collapse;
+ border-spacing: 0;
+ text-align: left;
+
+ th {
+ padding: 5px 10px;
+ font-weight: bold;
+ border-bottom: 2px solid #909ba2;
+ }
+ td {
+ padding: 5px 10px;
+ }
+ tr {
+ &:nth-child(2n) {
+ background: #f7f8f8;
+ }
+ }
+}
+
+hr {
+ margin: 1.5em 0 0;
+ outline: none;
+ border: none;
+ border-top: 1px solid #eef2f8;
+}
+
+dl {
+ dt {
+ font-weight: bold;
+ }
+ dd {
+ margin-left: 0;
+ }
+}
+
+// code block
+pre > code {
+ display: block;
+ width: 100%;
+ box-sizing: border-box;
+ padding: 15px;
+ font-family: #{map-get($font-families, 'highlight')};
+ border: none;
+ margin: 0;
+ // To override cursor attribute of `.tag` components
+ cursor: text;
+ overflow-x: auto;
+ line-height: map-get($highlight, line-height) + 0.4em;
+ font-size: map-get($highlight, font-size);
+}
+
+// inline code
+code {
+ font-size: map-get($font-size, medium);
+ display: inline-block;
+ font-family: map-get($font-families, 'code');
+ font-weight: 400;
+ background-color: map-get($highlight, 'background');
+ padding: 0 10px;
+}
+
+acronym,
+abbr {
+ border-bottom: 1px dotted $font-color-base;
+}
+
+blockquote {
+ border-left: 3px solid map-get($colors, 'base');
+ padding: 0 15px;
+ font-style: italic;
+ margin: 1.5em 0 0;
+
+ cite {
+ &:before {
+ content: ' — ';
+ padding: 0 0.3em;
+ }
+ }
+ & > p:first-child {
+ margin: 0;
+ }
+}
+
+// Reduce global font-size base and headings font size on small screen and down
+@media #{$small-and-down} {
+ code {
+ font-size: map-get($font-size, medium) - $font-size-base-sm-screen-reduction-factor;
+ }
+ @each $key, $value in $headings-font-size {
+ #{$key} {
+ font-size: $value - $headings-font-size-sm-screen-reduction-factor;
+ }
+ }
+}
+
+// Reduce global font-size base and headings font size on medium screen only
+@media #{$medium-only} {
+ @each $key, $value in $headings-font-size {
+ #{$key} {
+ font-size: $value - $headings-font-size-md-screen-reduction-factor;
+ }
+ }
+}
+ \ No newline at end of file
diff --git a/src/scss/components/_alert.scss b/src/scss/components/_alert.scss
new file mode 100755
index 0000000..80d6d87
--- /dev/null
+++ b/src/scss/components/_alert.scss
@@ -0,0 +1,69 @@
+.alert {
+ position: relative;
+ text-align: left;
+ padding: 10px 15px;
+ min-height: 30px;
+ margin: 1em 0 0;
+ border: none;
+ border-left: 3px solid;
+ p {
+ margin: 1.5em 0 0;
+
+ &:first-child {
+ margin: 0;
+ }
+ }
+ &:not(.no-icon) {
+ padding-left: 55px;
+
+ &:before {
+ position: absolute;
+ top: 10px;
+ left: 15px;
+ font-family: 'FontAwesome';
+ font-size: 2.5rem;
+ }
+ }
+ &.info {
+ border-color: map-get($colors, 'primary');
+ background-color: lighten(map-get($colors, 'primary'), 37%);
+
+ &:not(.no-icon) {
+ &:before {
+ content: "\f05a";
+ color: map-get($colors, 'primary');
+ }
+ }
+ }
+ &.success {
+ border-color: map-get($colors, 'success');
+ background-color: lighten(map-get($colors, 'success'), 42%);
+ content: "\f058";
+ &:not(.no-icon) {
+ &:before {
+ content: "\f058";
+ color: map-get($colors, 'success');
+ }
+ }
+ }
+ &.warning {
+ border-color: map-get($colors, 'warning');
+ background-color: lighten(map-get($colors, 'warning'), 42%);
+ &:not(.no-icon) {
+ &:before {
+ content: "\f071";
+ color: map-get($colors, 'warning');
+ }
+ }
+ }
+ &.danger {
+ border-color: map-get($colors, 'danger');
+ background-color: lighten(map-get($colors, 'danger'), 42%);
+ &:not(.no-icon) {
+ &:before {
+ content: "\f05e";
+ color: map-get($colors, 'danger');
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_archive.scss b/src/scss/components/_archive.scss
new file mode 100755
index 0000000..813b6de
--- /dev/null
+++ b/src/scss/components/_archive.scss
@@ -0,0 +1,36 @@
+.archive-result {
+ display: none;
+}
+
+.archive {
+ .archive-title {
+ color: $font-color-base;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+ .archive-posts {
+ list-style: none;
+
+ .archive-post {
+ .archive-post-title {
+ margin-left: 10px;
+ color: $font-color-base;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+ .archive-post-date {
+ color: map-get($colors, light);
+ }
+ // Change styl of the list by adding font-awesome icon
+ &::before {
+ font-family: 'FontAwesome';
+ content: '\f0da';
+ font-size: map-get($font-size, small);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_box.scss b/src/scss/components/_box.scss
new file mode 100755
index 0000000..771af92
--- /dev/null
+++ b/src/scss/components/_box.scss
@@ -0,0 +1,14 @@
+// Group of `.box`
+// Add margin when `.box` are in `.box-group`
+.boxes {
+ margin-top: 20px;
+
+ .box:nth-child(n + 2) {
+ margin-top: 20px;
+ }
+}
+
+// Box
+.box {
+ border-bottom: 1px solid #eef2f8;
+} \ No newline at end of file
diff --git a/src/scss/components/_button.scss b/src/scss/components/_button.scss
new file mode 100755
index 0000000..c45681c
--- /dev/null
+++ b/src/scss/components/_button.scss
@@ -0,0 +1,52 @@
+.btn {
+ width: auto;
+ height: auto;
+ background: white;
+ border-radius: 3px;
+ padding: 8px 15px;
+ margin: 0;
+ letter-spacing: $letter-spacing-base;
+ font-size: $font-size-base;
+ cursor: pointer;
+
+ &:hover,
+ &:focus,
+ &:active {
+ text-decoration: none;
+ }
+}
+
+// Disabled button
+.btn--disabled,
+.btn--disabled:hover {
+ color: lighten(map-get($colors, light), 10) !important;
+ border: 1px solid lighten(map-get($colors, light), 10);
+ cursor: not-allowed;
+ text-decoration: none;
+}
+
+// Color variant
+.btn--default {
+ @include button-color-variant(map-get($colors, light));
+}
+
+.btn--success {
+ @include button-color-variant(map-get($colors, success));
+}
+
+.btn--primary {
+ @include button-color-variant(map-get($colors, primary));
+}
+
+.btn--danger {
+ @include button-color-variant(map-get($colors, danger));
+}
+
+// Size variant
+.btn--medium {
+ @include button-size-variant(map-get($font-size, medium), 8px 15px);
+}
+
+.btn--small {
+ @include button-size-variant(map-get($font-size, small), 8px 15px);
+} \ No newline at end of file
diff --git a/src/scss/components/_caption.scss b/src/scss/components/_caption.scss
new file mode 100755
index 0000000..3f9bb1f
--- /dev/null
+++ b/src/scss/components/_caption.scss
@@ -0,0 +1,10 @@
+.caption {
+ display: block;
+ font-family: map-get($font-families, 'caption');
+ font-size: map-get($font-size, small);
+ color: darken(map-get($colors, 'light'), 10%);
+ text-align: center;
+ font-style: italic;
+ padding-right: 10px;
+ padding-left: 10px;
+} \ No newline at end of file
diff --git a/src/scss/components/_code.scss b/src/scss/components/_code.scss
new file mode 100755
index 0000000..f108d94
--- /dev/null
+++ b/src/scss/components/_code.scss
@@ -0,0 +1,107 @@
+// Highlight code block
+figure.highlight,
+.codeblock {
+ margin: 10px 0;
+ line-height: map-get($highlight, line-height);
+ padding-top: 15px;
+ padding-bottom: 15px;
+ overflow: hidden;
+
+ table {
+ display: block;
+ width: 100%;
+ }
+
+ // Reset for tag `pre` and for class `.gutter`, `.code`, `.tag`
+ pre,
+ .gutter,
+ .code,
+ .tag {
+ background-color: inherit;
+ font-family: #{map-get($font-families, 'highlight')};
+ border: none;
+ padding: 0;
+ margin: 0;
+ // To override cursor attribute of `.tag` components
+ cursor: text;
+ }
+ // To align line number and line of code regardless if there is a scroll bar or not
+ .gutter,
+ .code {
+ vertical-align: top;
+ }
+ // hide gutter when code is plain text
+ &.plain {
+ .gutter {
+ display: none;
+ }
+ }
+ // Meta bar which contains name of the file and his link
+ figcaption {
+ font-size: 1.3rem;
+ padding: 0 15px 20px;
+ margin: 0;
+
+ a {
+ float: right;
+ }
+ }
+
+ // Gutter which contains line numbers
+ .gutter {
+ border-right: map-get($highlight, border);
+ padding: 0.3em 15px;
+ }
+ // Code container
+ .code {
+ padding: 0.3em 15px 0.3em 1em;
+ width: 100%;
+
+ pre {
+ max-width: calc(#{map-get($main-content, 'max-width')} - 50px);
+ overflow-x: auto;
+ overflow-y: hidden;
+ }
+ }
+ // All lines in gutter and code container
+ .line {
+ height: map-get($highlight, line-height);
+ font-size: map-get($highlight, font-size);
+ }
+}
+
+// Tabbed code block
+.codeblock--tabbed {
+ figure.highlight,
+ pre > code {
+ margin-bottom: 0;
+ padding-bottom: 0;
+ }
+ figcaption {
+ a, span {
+ float: left !important;
+ }
+ .tabs {
+ float: right;
+ .tab {
+ cursor: pointer;
+ display: inline-block;
+ margin: 0 5px;
+ padding: 0 7px;
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+ }
+ }
+}
+
+// Gist
+.gist {
+ .line,
+ .line-number {
+ font-family: map-get($font-families, 'highlight');
+ font-size: 1em;
+ margin: 0 0 5px 0;
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_figure.scss b/src/scss/components/_figure.scss
new file mode 100755
index 0000000..33ac0d9
--- /dev/null
+++ b/src/scss/components/_figure.scss
@@ -0,0 +1,60 @@
+.figure {
+ &.clear {
+ clear: both;
+ }
+ &.center {
+ width: calc(100% - 4px);
+ margin: 2px auto;
+
+ .fig-img {
+ margin: 2px auto;
+ }
+ }
+ &.left {
+ float: left;
+ margin: 2px;
+ }
+ &.right {
+ float: right;
+ margin: 2px;
+ }
+ &.fig-20 {
+ @extend .left;
+ width: calc(20% - 4px);
+ }
+ &.fig-25 {
+ @extend .left;
+ width: calc(25% - 4px);
+ }
+ &.fig-33 {
+ @extend .left;
+ width: calc(33.3% - 4px);
+ }
+ &.fig-50 {
+ @extend .left;
+ width: calc(50% - 4px);
+ }
+ &.fig-75 {
+ @extend .left;
+ width: calc(75% - 4px);
+ }
+ &.fig-100 {
+ width: calc(100% - 4px);
+ margin: 2px;
+ }
+ &.figure--fullWidth {
+ width: 100%;
+ .figure-img {
+ margin: 0 auto;
+ }
+ }
+}
+
+// Hide caption of small pictures on small screen
+@media #{$small-and-down} {
+ .fig-33, .fig-25, .fig-20 {
+ .caption {
+ display: none;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_form.scss b/src/scss/components/_form.scss
new file mode 100755
index 0000000..64e1471
--- /dev/null
+++ b/src/scss/components/_form.scss
@@ -0,0 +1,22 @@
+.form-control {
+ background: transparent;
+ width: 100%;
+ border: none;
+ outline: none;
+ color: map-get($colors, base);
+ font-weight: 300;
+
+ &:hover,
+ &:focus {
+ outline: none;
+ }
+}
+
+
+// Input size variant
+.input--large {
+ @include input-size-variant(auto, 10px 0, 18px, 21px);
+}
+.input--xlarge {
+ @include input-size-variant(auto, 10px 0, 25px, 30px);
+} \ No newline at end of file
diff --git a/src/scss/components/_hide.scss b/src/scss/components/_hide.scss
new file mode 100755
index 0000000..f9f0a17
--- /dev/null
+++ b/src/scss/components/_hide.scss
@@ -0,0 +1,32 @@
+// Hide element on all screens
+.hide {
+ display: none;
+}
+
+// Hide element on very small screen and down
+@media #{$xsmall-and-down} {
+ .hide-xs {
+ display: none;
+ }
+}
+
+// Hide element on small screen only
+@media #{$small-only} {
+ .hide-sm {
+ display: none;
+ }
+}
+
+// Hide element on medium screen only
+@media #{$medium-only} {
+ .hide-md {
+ display: none;
+ }
+}
+
+// Hide element on large screen and up
+@media #{$large-and-up} {
+ .hide-lg {
+ display: none;
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_highlight-text.scss b/src/scss/components/_highlight-text.scss
new file mode 100755
index 0000000..8e5ff99
--- /dev/null
+++ b/src/scss/components/_highlight-text.scss
@@ -0,0 +1,39 @@
+.highlight-text {
+ display: inline;
+ padding: 3px;
+
+ &.red {
+ background-color:map-get($highlight-text-bg-colors, 'red');
+ }
+ &.green {
+ background-color:map-get($highlight-text-bg-colors, 'green');
+ }
+ &.blue {
+ background-color:map-get($highlight-text-bg-colors, 'blue');
+ }
+ &.purple {
+ background-color:map-get($highlight-text-bg-colors, 'purple');
+ }
+ &.orange {
+ background-color:map-get($highlight-text-bg-colors, 'orange');
+ }
+ &.yellow {
+ background-color:map-get($highlight-text-bg-colors, 'yellow');
+ }
+ &.cyan {
+ background-color:map-get($highlight-text-bg-colors, 'cyan');
+ }
+ &.primary {
+ background-color:map-get($highlight-text-bg-colors, 'primary');
+ }
+ &.success {
+ background-color:map-get($highlight-text-bg-colors, 'success');
+ }
+ &.warning {
+ background-color:map-get($highlight-text-bg-colors, 'warning');
+ }
+ &.danger {
+ background-color:map-get($highlight-text-bg-colors, 'danger');
+ }
+
+} \ No newline at end of file
diff --git a/src/scss/components/_icon.scss b/src/scss/components/_icon.scss
new file mode 100755
index 0000000..e48c74d
--- /dev/null
+++ b/src/scss/components/_icon.scss
@@ -0,0 +1,17 @@
+// Add margin to an element
+// Specifically implement for font-awesome's icons to add space between icon and text in a button
+.icon-mt {
+ margin-top: 10px;
+}
+
+.icon-mr {
+ margin-right: 10px;
+}
+
+.icon-mb {
+ margin-bottom: 10px;
+}
+
+.icon-ml {
+ margin-left: 10px;
+} \ No newline at end of file
diff --git a/src/scss/components/_image-gallery.scss b/src/scss/components/_image-gallery.scss
new file mode 100755
index 0000000..10a067a
--- /dev/null
+++ b/src/scss/components/_image-gallery.scss
@@ -0,0 +1,78 @@
+.image-gallery {
+ display: block;
+ position: relative;
+ height: auto;
+ overflow: hidden;
+ margin-bottom: 30px;
+
+ .image-gallery-metabar {
+ position: absolute;
+ bottom: 0;
+ // width: (full with) - ((padding right-left of `.image-gallery-metabar` + 0.05em) * 4) to be responsive on all screen
+ width: calc(100% - (1.5em) * 2);
+ font-family: map-get($font-families, 'image-gallery');
+ font-style: italic;
+ background: rgba(0, 0, 0, 0.75);
+ font-size: map-get($font-size, small);
+ color: white;
+ padding: 0.5em 1.5em;
+ // Use to go over all images of the gallery
+ z-index: 1;
+ }
+ .image-gallery-photos {
+ .photo-box {
+ float: left;
+ position: relative;
+ overflow: hidden;
+ display: none;
+
+ &:first-child {
+ display: block;
+ width: 100%;
+ // 16:9 ratio, consider as height value
+ padding-bottom: 56.25%;
+ }
+ .photo-box-inner {
+ position: absolute;
+ overflow: hidden;
+
+ .photo {
+ width: 100%;
+ cursor: -webkit-zoom-in;
+ cursor: -moz-zoom-in;
+ }
+ }
+ }
+ }
+ // Thumbnail image of gallery
+ // Used when image gallery contains more than 2 images
+ // You can change the style of image gallery by changing the following value
+ // Currently, it display one large image above 2 smaller images
+ // First image of the gallery
+ .image-gallery-photos--thumbnail {
+ // Display all images
+ .photo-box {
+ display: block;
+ width: 50%;
+ // Consider as height value
+ padding-bottom: 30%;
+ // Display First image in large
+ &:first-child {
+ width: 100%;
+ // Consider as height value
+ padding-bottom: 40%;
+ margin-bottom: $image-gallery-photos-margin;
+ }
+ // Resize seconde image minus space between 2 images
+ &:nth-child(2) {
+ margin-right: $image-gallery-photos-margin;
+ // width: 50% minus the space between 2 images
+ width: calc(50% - #{$image-gallery-photos-margin}); // Consider as height value
+ }
+ // Hide all other images after the 3 first
+ &:nth-child(n + 4) {
+ display: none;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_link.scss b/src/scss/components/_link.scss
new file mode 100755
index 0000000..df54206
--- /dev/null
+++ b/src/scss/components/_link.scss
@@ -0,0 +1,19 @@
+a.link-unstyled {
+ &,
+ &:hover,
+ &:active {
+ cursor: pointer !important;
+ color: inherit !important;
+ text-decoration: none !important;
+ }
+ a.link {
+ &,
+ &:hover,
+ &:active {
+ text-decoration: underline !important;
+ }
+ }
+}
+a.fancybox {
+ cursor: zoom-in !important;
+} \ No newline at end of file
diff --git a/src/scss/components/_main-content.scss b/src/scss/components/_main-content.scss
new file mode 100755
index 0000000..07c28f0
--- /dev/null
+++ b/src/scss/components/_main-content.scss
@@ -0,0 +1,7 @@
+.main-content-wrap {
+ display: block;
+ max-width: map-get($main-content, max-width);
+ margin: 0 auto;
+ padding-right: map-get($main-content, padding-right-left);
+ padding-left: map-get($main-content, padding-right-left);
+} \ No newline at end of file
diff --git a/src/scss/components/_markdown.scss b/src/scss/components/_markdown.scss
new file mode 100755
index 0000000..cf15a38
--- /dev/null
+++ b/src/scss/components/_markdown.scss
@@ -0,0 +1,32 @@
+// Set markdown headings font size on large screen and up
+@media #{$large-and-up} {
+ .markdown {
+ @each $key, $value in $markdown-headings-font-size {
+ #{$key} {
+ font-size: $value;
+ }
+ }
+ }
+}
+
+// Reduce global font-size base and headings font size on small screen and down
+@media #{$small-and-down} {
+ .markdown {
+ @each $key, $value in $markdown-headings-font-size {
+ #{$key} {
+ font-size: $value - $markdown-headings-font-size-sm-screen-reduction-factor;
+ }
+ }
+ }
+}
+
+// Reduce global font-size base and headings font size on medium screen only
+@media #{$medium-only} {
+ .markdown {
+ @each $key, $value in $markdown-headings-font-size {
+ #{$key} {
+ font-size: $value - $markdown-headings-font-size-md-screen-reduction-factor;
+ }
+ }
+ }
+}
diff --git a/src/scss/components/_media.scss b/src/scss/components/_media.scss
new file mode 100755
index 0000000..ec4c5c5
--- /dev/null
+++ b/src/scss/components/_media.scss
@@ -0,0 +1,23 @@
+.media {
+ &-body,
+ &-left {
+ display: table-cell;
+ vertical-align: top;
+ }
+ &-left {
+ float: left;
+ padding-right: 15px;
+ }
+ &-body {
+ width: 100%;
+ }
+ &-heading {
+ margin: 0 0 -5px;
+ }
+ &-meta {
+ color: map-get($colors, 'light');
+ }
+ &-content {
+ color: map-get($colors, 'base');
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_modal.scss b/src/scss/components/_modal.scss
new file mode 100755
index 0000000..0aca4f2
--- /dev/null
+++ b/src/scss/components/_modal.scss
@@ -0,0 +1,70 @@
+.modal-container {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ box-sizing: border-box;
+ z-index: map-get($z-indexes, 'c-modal');
+}
+
+.modal {
+ width: 100%;
+ height: 100%;
+ max-width: #{map-get($main-content, 'max-width')};
+ box-sizing: border-box;
+ position: relative;
+ margin: 0 auto;
+ padding: 0;
+ overflow: hidden;
+
+ &-header {
+ position: relative;
+ padding: 10px 15px 0;
+ background: white;
+ border-bottom: 1px solid #eef2f8;
+ }
+ &-body {
+ position: relative;
+ padding: 0 15px;
+ overflow-y: auto;
+ background: white;
+ }
+ &-footer {
+ height: 50px;
+ padding: 0 15px;
+ background: white;
+ border-top: 1px solid #eef2f8;
+ }
+ .close-button {
+ position: absolute;
+ // perfect position
+ top: 9px;
+ right: 15px;
+ color: $font-color-base;
+ cursor: pointer;
+ }
+}
+
+.overlay {
+ display: none;
+ background: rgba(0, 0, 0, 0.50);
+ width: 100%;
+ height: 100%;
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: map-get($z-indexes, 'c-overlay');
+ overflow: hidden;
+}
+
+@media #{$medium-and-up} {
+ .modal-container {
+ padding: 50px 0;
+ left: 50%;
+ transform: translateX(-50%);
+ }
+ .modal {
+ border-radius: 5px;
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_pagination.scss b/src/scss/components/_pagination.scss
new file mode 100755
index 0000000..0f7be25
--- /dev/null
+++ b/src/scss/components/_pagination.scss
@@ -0,0 +1,25 @@
+.pagination-bar {
+ height: auto;
+ width: 100%;
+ height: $pagination-height;
+
+ .pagination {
+ height: $pagination-height;
+ line-height: $pagination-height;
+ display: block;
+ list-style: none;
+ padding: 0 10px;
+ width: auto;
+
+ .pagination-prev,
+ .pagination-next {
+ float: left;
+ margin-right: 10px;
+ }
+ .pagination-number {
+ float: right;
+ font-size: map-get($font-size, small);
+ color: map-get($colors, light);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_post-actions.scss b/src/scss/components/_post-actions.scss
new file mode 100755
index 0000000..55ccba6
--- /dev/null
+++ b/src/scss/components/_post-actions.scss
@@ -0,0 +1,83 @@
+.post-actions-wrap {
+ height: 60px;
+ padding: 0;
+ line-height: 60px;
+ clear: both;
+
+ ul.post-actions {
+ float: left;
+ padding-left: 0;
+ margin-top: 0;
+ list-style: none;
+
+ li.post-action {
+ width: auto;
+ text-align: center;
+ }
+ }
+ // Post's navigation options
+ ul.post-action-nav {
+ // Best width for responsive post's navigation panel on small screen and up
+ width: 45%;
+ // On very small screen `.post-actions-nav` will be above `.post-actions-share`
+ z-index: map-get($z-indexes, c-post-bottom-bar) + 2;
+
+ li.post-action {
+ float: left;
+ // Fix a bug on Firefox. the right part of button `previous` fall down without this `min-width`
+ min-width: 42px;
+
+ &:last-child {
+ .post-action-btn {
+ margin-left: 15px;
+ }
+ }
+ }
+ }
+ // Post's share options
+ ul.post-action-share {
+ // 100% minus width of `.post-action-nav`,
+ // best width for responsive post's share panel on small screen and up
+ width: 55%;
+ // On very small screen `.post-actions-nav` will be above `.post-actions-share`
+ z-index: map-get($z-indexes, c-post-bottom-bar) + 1;
+
+ li.post-action {
+ float: right;
+
+ &:nth-child(n + 3) {
+ .post-action-btn {
+ margin-right: 15px;
+ }
+ }
+ }
+ }
+}
+
+// Increase width of `.post-actions-share` on small screen
+@media #{$small-and-down} {
+ .post-actions-wrap {
+ ul.post-action-nav {
+ // Best width for responsive post's navigation panel on small screen
+ width: 25%;
+ }
+ ul.post-action-share {
+ // Best width for responsive post's share panel on small screen
+ width: 75%;
+ }
+ }
+}
+
+// Increase width of `.post-actions-nav` on very small screen
+@media #{$xsmall-and-down} {
+ .post-actions-wrap {
+ ul.post-action-nav {
+ // Best width for responsive post's navigation panel on very small screen
+ width: 35%;
+ }
+ ul.post-action-share {
+ // Best width for responsive post's share panel on very small screen
+ width: 65%;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_post-header-cover.scss b/src/scss/components/_post-header-cover.scss
new file mode 100755
index 0000000..2c330ad
--- /dev/null
+++ b/src/scss/components/_post-header-cover.scss
@@ -0,0 +1,219 @@
+.post-header {
+ .post-title {
+ margin: 0;
+ word-break: initial;
+ overflow: hidden;
+
+ &:hover {
+ text-decoration: none;
+ }
+ }
+}
+
+// Cover image displayed in single post view
+// When post's `coverImage` variable is defined
+.post-header-cover {
+ display: table;
+ position: relative;
+ // Fix the cover image to the top of the page
+ top: 0;
+ left: 0;
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ width: 100%;
+ padding: calc(#{map-get($header, 'height')} + 30px) 0 30px 0;
+ // 100% minus header high, minus padding-top, minus padding bottom and minus 4px for perfect pixels
+ height: 100%;
+ z-index: map-get($z-indexes, 'c-post-header-cover');
+ // Sidebar animation
+ // Transition style (push)
+ transition: transform .25s ease-in-out;
+ -webkit-transition: -webkit-transform .25s ease-in-out;
+ // Eliminate any flickering of elements while they are in a state of being animated
+ -webkit-backface-visibility: hidden;
+ -webkit-perspective: 1000;
+
+ .post-header {
+ display: table-cell;
+ vertical-align: middle;
+
+ .post-title {
+ max-width: map-get($main-content, 'max-width');
+ margin: 0 auto;
+ color: white;
+ text-shadow: 0 2px 0 rgba(0, 0, 0, 0.9);
+ margin-bottom: 20px;
+
+ &:hover {
+ text-decoration: none;
+ }
+ }
+ // Post meta contains post's date, post's categories and tags
+ .post-meta {
+ max-width: map-get($main-content, 'max-width');
+ font-family: map-get($font-families, 'post-meta');
+ font-size: $font-size-base;
+ color: white !important;
+ font-weight: 400;
+ letter-spacing: 0.05em;
+ text-shadow: 0 1px 0 rgba(0, 0, 0, 0.9);
+ margin: 0 auto;
+
+ a {
+ color: white;
+ }
+ }
+ }
+}
+
+// Decrease height of cover image
+.post-header-cover.post-header-cover--partial {
+ height: 60%;
+}
+
+.post-header-cover-caption {
+ margin: 5px 0 50px 0;
+}
+
+// Decrease the font size of the post's title on very small screen
+@media #{$xsmall-and-down} {
+ .post-header-cover {
+ .post-header {
+ .post-title {
+ font-size: map-get($headings-font-size, h1);
+ }
+ }
+ }
+}
+
+// Increase the font size of the post's title on small screen
+@media #{$small-only} {
+ .post-header-cover {
+ .post-header {
+ .post-title {
+ font-size: map-get($headings-font-size, h1) + 0.5rem;
+ }
+ }
+ }
+}
+
+@media #{$small-and-down} {
+ .post-header-cover {
+ // Display post header cover div in large size
+ @include post-header-cover-lg;
+
+ // Push post header cover div from the size of the large sidebar
+ &[data-behavior="1"],
+ &[data-behavior="2"],
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ @include post-header-cover-pushed-lg;
+ }
+ // Push post header cover div from the size of the medium sidebar
+ &[data-behavior="3"],
+ &[data-behavior="6"] {
+ @include post-header-cover-pushed-md;
+ }
+ }
+}
+
+@media #{$medium-only} {
+ // Increase the font size of the post's title on medium screen
+ .post-header-cover {
+ .post-header {
+ .post-title {
+ font-size: map-get($headings-font-size, h1) + 3rem;
+ line-height: 1.3em;
+ }
+ }
+ // Display post header cover div in medium size
+ &[data-behavior="1"],
+ &[data-behavior="2"],
+ &[data-behavior="3"] {
+ @include post-header-cover-md;
+ }
+ // Display post header cover div in large size and push it from the size of the large sidebar
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ @include post-header-cover-lg;
+ @include post-header-cover-pushed-lg;
+ }
+ // Display post header cover div in large size and push it from the size of the medium sidebar
+ &[data-behavior="6"] {
+ @include post-header-cover-lg;
+ @include post-header-cover-pushed-md;
+ }
+ }
+}
+
+@media #{$large-only} {
+ // Increase the font size of the post's title on large screen
+ .post-header-cover {
+ .post-header {
+ .post-title {
+ font-size: map-get($headings-font-size, h1) + 3.7rem;
+ line-height: 1.3em;
+ }
+ }
+ // Display post header cover div in small size
+ &[data-behavior="1"],
+ &[data-behavior="2"] {
+ @include post-header-cover-sm;
+ }
+ // Display post header cover div in medium size
+ &[data-behavior="3"] {
+ @include post-header-cover-md;
+ }
+ // Display post header cover div in large size and push it from the size of the large sidebar
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ @include post-header-cover-lg;
+ @include post-header-cover-pushed-lg;
+ }
+ // Display post header cover div in large size and push it from the size of the medium sidebar
+ &[data-behavior="6"] {
+ @include post-header-cover-lg;
+ @include post-header-cover-pushed-md;
+ }
+ }
+}
+
+@media #{$xlarge-and-up} {
+ // Increase the font size of the post's title on large screen
+ .post-header-cover {
+ .post-header {
+ .post-title {
+ font-size: map-get($headings-font-size, h1) + 3.7rem;
+ line-height: 1.3em;
+ }
+ }
+ // Display post header cover div in extra small size
+ &[data-behavior="1"] {
+ @include post-header-cover-xs;
+ }
+ // Display post header cover div in small size
+ &[data-behavior="2"] {
+ @include post-header-cover-sm;
+ }
+ // Display post header cover div in medium size
+ &[data-behavior="3"] {
+ @include post-header-cover-md;
+ }
+ // Display post header cover div in large size and push it from the size of the large sidebar
+ &[data-behavior="4"] {
+ @include post-header-cover-lg;
+ @include post-header-cover-pushed-xlg;
+ }
+ // Display post header cover div in large size and push it from the size of the extra large sidebar
+ &[data-behavior="5"] {
+ @include post-header-cover-lg;
+ @include post-header-cover-pushed-lg;
+ }
+ // Display post header cover div in large size and push it from the size of the medium sidebar
+ &[data-behavior="6"] {
+ @include post-header-cover-lg;
+ @include post-header-cover-pushed-md;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_post.scss b/src/scss/components/_post.scss
new file mode 100755
index 0000000..b0a34bb
--- /dev/null
+++ b/src/scss/components/_post.scss
@@ -0,0 +1,88 @@
+.post {
+ position: relative;
+ width: 100%;
+ display: inline-block;
+ vertical-align: top;
+
+ .post-header {
+ .post-title {
+ margin: 0;
+ word-break: initial;
+ overflow: hidden;
+
+ &:hover {
+ text-decoration: none;
+ }
+ }
+ }
+ // Post meta contains post's date, post's categories and tags
+ .post-meta {
+ line-height: 1.5em;
+ font-family: map-get($font-families, 'post-meta');
+ font-size: map-get($font-size, small);
+ font-weight: 400;
+ color: map-get($colors, light);
+
+ a {
+ color: map-get($colors, light);
+ }
+ }
+ .post-content {
+ text-rendering: optimizelegibility;
+ letter-spacing: -0.3px;
+ font-family: map-get($font-families, 'post-content');
+ color: map-get($colors, base);
+ margin-top: 20px;
+ font-weight: 400;
+ overflow: hidden;
+ @include prefix('hypens', 'auto', 'webkit' 'moz');
+
+ img {
+ display: block;
+ width: auto;
+ max-width: 100%;
+ }
+ :not(blockquote):not(.alert) {
+ & > p {
+ margin: 1.5em 0 0 0;
+ }
+ }
+ }
+ .post-footer {
+ margin-top: 20px;
+ &-tags {
+ padding-bottom: 10px;
+ margin-bottom: 10px;
+ border-bottom: 1px solid #eef2f8;
+ }
+ }
+}
+
+// Increase the font size of the post's title on medium screen (only for single post view)
+@media #{$medium-only} {
+ .post {
+ .post-header {
+ .post-title {
+ font-size: map-get($headings-font-size, h1) + 0.5rem;
+ }
+ }
+ }
+}
+
+// Increase font size of the post's title on large screen (only for single post view)
+@media #{$large-and-up} {
+ .post {
+ .post-header {
+ .post-title {
+ font-size: map-get($headings-font-size, h1) + 0.9rem;
+ }
+ }
+ }
+}
+
+// Increase font-size on medium and large screen
+@media #{$medium-and-up} {
+ .post-content {
+ font-size: 1.7rem;
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_postShorten.scss b/src/scss/components/_postShorten.scss
new file mode 100755
index 0000000..83725df
--- /dev/null
+++ b/src/scss/components/_postShorten.scss
@@ -0,0 +1,156 @@
+// Group of `.postShorten`
+// Add margin and border bottom when `.postShorten` are in `.postShorten-group`
+.postShorten-group {
+ .postShorten {
+ // Space between 2 shorten post
+ margin-top: 15px;
+ border-bottom: 1px solid #eef2f8;
+ }
+}
+
+// Post
+.postShorten {
+ position: relative;
+ width: 100%;
+ display: inline-block;
+ vertical-align: top;
+
+ .postShorten-thumbnailimg {
+ overflow:hidden;
+ }
+ .postShorten-header {
+ .postShorten-title {
+ margin: 0;
+ word-break: initial;
+ overflow: hidden;
+
+ &:hover {
+ text-decoration: none;
+ }
+ }
+ }
+ // postShorten meta contains post's date, post's categories and tags
+ .postShorten-meta {
+ line-height: 1.5em;
+
+ a {
+ color: map-get($colors, light);
+ }
+ }
+ .postShorten-meta,
+ .postShorten-readingtime {
+ color: map-get($colors, light);
+ }
+ .postShorten-excerpt_link {
+ // Bring the post's link nearest of the excerpt
+ margin-top: -15px;
+ }
+ .postShorten-meta,
+ .postShorten-readingtime,
+ .postShorten-excerpt_link {
+ font-family: map-get($font-families, 'post-excerpt-link');
+ font-size: map-get($font-size, small);
+ font-weight: 400;
+ }
+ .postShorten-excerpt,
+ .postShorten-content {
+ text-rendering: optimizelegibility;
+ letter-spacing: -0.3px;
+ font-family: map-get($font-families, 'post-content');
+ color: map-get($colors, base);
+ font-weight: 400;
+ overflow: hidden;
+ @include prefix('hypens', 'auto', 'webkit' 'moz');
+
+ img {
+ display: block;
+ width: auto;
+ max-width: 100%;
+ }
+ }
+ .postShorten-excerpt {
+ margin-top: 15px;
+ }
+ .postShorten-content {
+ margin-top: 25px;
+ }
+}
+
+// Hide the post's thumbnail image on very small screen and down
+@media #{$xsmall-and-down} {
+ .postShorten {
+ .postShorten-thumbnailimg {
+ display: none;
+
+ img {
+ display: none;
+ }
+ }
+ }
+}
+
+// Display the post's thumbnail image on small screen and up
+@media #{$small-and-up} {
+ .postShorten.postShorten--thumbnailimg-right {
+ .postShorten-thumbnailimg {
+ float: right;
+ margin: 5px 0 30px 15px;
+
+ img {
+ display: block;
+ width: $post-thumbnail-image-width;
+ height: $post-thumbnail-image-width;
+ object-fit: cover;
+ overflow: hidden;
+ }
+ }
+ .postShorten-wrap {
+ float: left;
+ width: calc(100% - #{$post-thumbnail-image-width} - 20px);
+ }
+ }
+ .postShorten.postShorten--thumbnailimg-left {
+ .postShorten-thumbnailimg {
+ float: left;
+ margin: 5px 15px 30px 0;
+
+ img {
+ display: block;
+ width: $post-thumbnail-image-width;
+ height: $post-thumbnail-image-width;
+ object-fit: cover;
+ overflow: hidden;
+ }
+ }
+ .postShorten-wrap {
+ float: right;
+ width: calc(100% - #{$post-thumbnail-image-width} - 20px);
+ }
+ }
+ .postShorten.postShorten--thumbnailimg-top {
+ .postShorten-thumbnailimg {
+ margin-top: 5px;
+ }
+ }
+ .postShorten.postShorten--thumbnailimg-bottom {
+ .postShorten-wrap {
+ display: block;
+ width: 100%;
+ }
+ .postShorten-excerpt > p {
+ margin-bottom: 0;
+ }
+ .postShorten-thumbnailimg {
+
+ display: block;
+ width: 100%;
+ overflow: hidden;
+ margin: 15px 0 15px 0;
+
+ img {
+ width: auto;
+ height: auto;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_pullquote.scss b/src/scss/components/_pullquote.scss
new file mode 100755
index 0000000..13c9038
--- /dev/null
+++ b/src/scss/components/_pullquote.scss
@@ -0,0 +1,20 @@
+.pullquote {
+ text-align: left;
+ font-style: italic;
+ margin: 1.5em 0 0;
+
+ &.left {
+ width: 45%;
+ float: left;
+ margin: 1.5em 35px 1.5em 0;
+ }
+ &.right {
+ width: 45%;
+ float: right;
+ margin: 1.5em 0 1.5em 35px;
+ }
+ &.blur {
+ background-color: lighten(map-get($colors, 'base'), 54%);
+ }
+
+} \ No newline at end of file
diff --git a/src/scss/components/_share-options-bar.scss b/src/scss/components/_share-options-bar.scss
new file mode 100755
index 0000000..95aba60
--- /dev/null
+++ b/src/scss/components/_share-options-bar.scss
@@ -0,0 +1,105 @@
+.share-options-bar {
+ position: fixed;
+ // height + border-top
+ // used to hide the div at the bottom of the window
+ bottom: -156px;
+ background: white;
+ height: 155px;
+ clear: both;
+ border-top: 1px solid #eef2f8;
+ transition: transform .25s ease-in-out;
+ z-index: map-get($z-indexes, 'c-share-options-bar');
+ -webkit-transition: -webkit-transform .25s ease-in-out;
+ // use to animate the share option bar
+ &.opened {
+ @include prefix(transform, translate3d(0, -155px, 0), 'webkit' 'moz');
+ }
+
+ .share-options {
+ padding: 0;
+ margin: 0;
+ text-align: center;
+ list-style: none;
+
+ .share-option {
+ &:first-child {
+ .share-option-btn {
+ padding: 20px 0 10px 0;
+ }
+ }
+ &:last-child {
+ .share-option-btn {
+ padding: 10px 0 20px 0;
+ }
+ }
+ .share-option-btn {
+ color: #6e7681;
+ display: block;
+ width: 100%;
+ padding: 10px 0 10px 0;
+
+ .fa {
+ margin-right: 15px;
+ }
+ }
+ }
+ }
+}
+
+// mask where the user can click to close the share options bar
+.share-options-mask {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ display: none;
+ z-index: map-get($z-indexes, 'c-mask');
+}
+
+// Behavior of the share options bar on small screens
+@media #{$small-and-down} {
+ .share-options-bar {
+ // Display bottom bar in large size
+ @include share-options-bar-lg;
+ }
+}
+
+// Behavior of the share options bar on medium screens
+@media #{$medium-only} {
+ .share-options-bar {
+ // Display share options bar in small size
+ &[data-behavior="1"],
+ &[data-behavior="2"],
+ &[data-behavior="3"] {
+ @include share-options-bar-md;
+ }
+ // Display share options bar in large size
+ &[data-behavior="4"],
+ &[data-behavior="5"],
+ &[data-behavior="6"] {
+ @include share-options-bar-lg;
+ }
+ }
+}
+
+// Behavior of the share options bar on large screens
+@media #{$large-and-up} {
+ .share-options-bar {
+ // Display share options bar in small size
+ &[data-behavior="1"],
+ &[data-behavior="2"]{
+ @include share-options-bar-sm;
+ }
+ // Display share options bar in medium size
+ &[data-behavior="3"] {
+ @include share-options-bar-md;
+ }
+ // Display share options bar in large size
+ &[data-behavior="4"],
+ &[data-behavior="5"],
+ &[data-behavior="6"] {
+ @include share-options-bar-lg;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_tag.scss b/src/scss/components/_tag.scss
new file mode 100755
index 0000000..c609486
--- /dev/null
+++ b/src/scss/components/_tag.scss
@@ -0,0 +1,45 @@
+a.tag,
+.tag {
+ display: inline-block;
+ background: #fff;
+ width: auto;
+ height: auto;
+ border-radius: 3px;
+ letter-spacing: $letter-spacing-base;
+ cursor: pointer;
+ margin: 0;
+ margin-right: 4px;
+ margin-bottom: 7px;
+}
+
+// Colors variant
+a.tag--default,
+.tag--default {
+ @include tag-color-variant(map-get($colors, light));
+}
+
+a.tag--success,
+.tag--success {
+ @include tag-color-variant(map-get($colors, success));
+}
+
+a.tag--primary,
+.tag--primary {
+ @include tag-color-variant(map-get($colors, primary));
+}
+
+a.tag--danger,
+.tag--danger {
+ @include tag-color-variant(map-get($colors, danger));
+}
+
+// Size variant
+a.tag--default,
+.tag--default {
+ @include tag-size-variant(map-get($font-size, small), 4.5px 15px);
+}
+
+a.tag--small,
+.tag--small {
+ @include tag-size-variant(map-get($font-size, small), 2px 10px);
+} \ No newline at end of file
diff --git a/src/scss/components/_text.scss b/src/scss/components/_text.scss
new file mode 100755
index 0000000..1bc5919
--- /dev/null
+++ b/src/scss/components/_text.scss
@@ -0,0 +1,102 @@
+// Text alignment
+.text-left {
+ text-align: left !important;
+}
+
+.text-right {
+ text-align: right !important;
+}
+
+.text-center {
+ text-align: center !important;
+}
+
+.text-justify {
+ text-align: justify !important;
+}
+
+.text-nowrap {
+ white-space: nowrap !important;
+}
+
+// Text transformation
+.text-lowercase {
+ text-transform: lowercase !important;
+}
+
+.text-uppercase {
+ text-transform: uppercase !important;
+}
+
+.text-capitalize {
+ text-transform: capitalize !important;
+}
+
+// Text size
+.text-xsmall {
+ font-size: map-get($font-size, xsmall) !important;
+}
+
+.text-small {
+ font-size: map-get($font-size, small) !important;
+}
+
+.text-medium {
+ font-size: map-get($font-size, medium) !important;
+}
+
+.text-base {
+ font-size: $font-size-base !important;
+}
+
+.text-large {
+ font-size: map-get($font-size, large) !important;
+}
+
+.text-xlarge {
+ font-size: map-get($font-size, xlarge) !important;
+}
+
+// Text style
+.text-strong {
+ font-weight: 700 !important;
+}
+
+.text-regular {
+ font-weight: 400 !important;
+}
+
+.text-light {
+ font-weight: 300 !important;
+}
+
+.text-italic {
+ font-style: italic !important;
+}
+
+.text-underline {
+ text-decoration: underline !important;
+}
+
+.text-underline-hover {
+ &:hover {
+ text-decoration: underline !important;
+ }
+}
+
+// Text coloration
+.text-color-base {
+ color: map-get($colors, base) !important;
+}
+
+.text-color-light {
+ color: map-get($colors, light) !important;
+}
+
+.text-color-link {
+ color: map-get($colors, link) !important;
+}
+
+.font-merryweather {
+ font-family: $merriweather-serif;
+} \ No newline at end of file
diff --git a/src/scss/components/_tooltip.scss b/src/scss/components/_tooltip.scss
new file mode 100755
index 0000000..c619199
--- /dev/null
+++ b/src/scss/components/_tooltip.scss
@@ -0,0 +1,166 @@
+// The default position of a tooltip is at the top of the focused element
+.tooltip {
+ position: relative;
+ cursor: pointer;
+ // Add default behavior from `tooltip--top`
+ @extend .tooltip--top;
+
+ &:before {
+ z-index: map-get($z-indexes, c-tooltip);
+ border: 6px solid transparent;
+ background: transparent;
+ content: "";
+ }
+ &:after {
+ z-index: map-get($z-indexes, c-tooltip);
+ padding: 8px;
+ // Fixed width of tooltip
+ min-width: map-get($tooltip, min-width);
+ background-color: map-get($tooltip, background);
+ color: #fff;
+ content: attr(data-tooltip);
+ font-size: 0.93em;
+ line-height: $line-height-base;
+ border-radius: 5px;
+ }
+ &:before,
+ &:after {
+ position: absolute;
+ visibility: hidden;
+ @include opacity(0);
+ // Animate tooltip
+ -webkit-transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out, -webkit-transform 0.2s cubic-bezier(0.71, 1.7, 0.77, 1.24);
+ -moz-transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out, -moz-transform 0.2s cubic-bezier(0.71, 1.7, 0.77, 1.24);
+ transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out, transform 0.2s cubic-bezier(0.71, 1.7, 0.77, 1.24);
+ @include prefix(transform, translate3d(0, 0, 0), 'webkit' 'moz' 'ms');
+ pointer-events: none;
+ }
+
+ &:hover:before,
+ &:hover:after,
+ &:focus:before,
+ &:focus:after {
+ visibility: visible;
+ @include opacity(1);
+ // Animate tooltip
+ @include prefix(transform, translateY(-12px), 'webkit' 'moz' 'ms' 'o');
+ }
+}
+
+[data-tooltip] {
+ @extend .tooltip;
+}
+
+// Directions
+// Position tooltip at the top of the focused element
+.tooltip--top {
+ &:before {
+ // Let's appear perfectly tooltip's arrow
+ margin-bottom: -#{map-get($tooltip, arrow-height)};
+ border-top-color: map-get($tooltip, background);
+ }
+ &:after {
+ // Center tooltip with his arrow
+ margin-left: -#{(map-get($tooltip, min-width) / 2) + 1};
+ }
+ &:before,
+ &:after {
+ // Position tooltip at the right of the focused element
+ bottom: 100%;
+ // Horizontally center tooltip's arrow relative to the focused element
+ left: calc(50% - (#{map-get($tooltip, arrow-width)} / 2));
+ }
+ &:hover:before,
+ &:hover:after,
+ &:focus:before,
+ &:focus:after {
+ // Translate tooltip to the top
+ @include prefix(transform, translateY(-12px), 'webkit' 'moz' 'ms' 'o');
+ }
+}
+
+// Position tooltip at the left of the focused element
+.tooltip--left {
+ &:before {
+ margin-left: 0;
+ margin-right: -#{map-get($tooltip, arrow-height)};
+ margin-bottom: 0;
+ border-top-color: transparent;
+ border-left-color: map-get($tooltip, background);
+ }
+ &:after {
+ margin-left: 0;
+ // Vertically center tooltip content
+ margin-bottom: -#{map-get($tooltip, arrow-width)};
+ }
+ &:before,
+ &:after {
+ // Position arrow at the left of the focused element
+ right: 100%;
+ // Vertically center tooltip's arrow relative to the focused element
+ bottom: calc(50% - (#{map-get($tooltip, arrow-width)} / 2));
+ left: auto;
+ }
+ &:hover:before,
+ &:hover:after,
+ &:focus:before,
+ &:focus:after {
+ // Translate tooltip to the left
+ @include prefix(transform, translateX(-12px), 'webkit' 'moz' 'ms' 'o');
+ }
+}
+
+// Position tooltip at the bottom of the focused element
+.tooltip--bottom {
+ &:before {
+ margin-top: -#{map-get($tooltip, arrow-height)};
+ margin-bottom: 0;
+ border-top-color: transparent;
+ border-bottom-color: map-get($tooltip, background);
+ }
+ &:before,
+ &:after {
+ // Position arrow at the bottom of the focused element
+ top: 100%;
+ bottom: auto;
+ // Horizontally center tooltip's arrow relative to the focused element
+ left: calc(50% - (#{map-get($tooltip, arrow-width)} / 2));
+ }
+ &:hover:before,
+ &:hover:after,
+ &:focus:before,
+ &:focus:after {
+ // Translate tooltip to the bottom
+ @include prefix(transform, translateY(12px), 'webkit' 'moz' 'ms' 'o');
+ }
+}
+
+// Position tooltip at the right of the focused element
+.tooltip--right {
+ &:before {
+ margin-bottom: 0;
+ margin-left: -#{map-get($tooltip, arrow-height)};
+ border-top-color: transparent;
+ border-right-color: map-get($tooltip, background);
+ }
+ &:after {
+ margin-left: 0;
+ // Vertically center tooltip content
+ margin-bottom: -#{map-get($tooltip, arrow-width)};
+ }
+ &:before,
+ &:after {
+ // Vertically center tooltip's arrow relative to the focused element
+ bottom: calc(50% - (#{map-get($tooltip, arrow-width)} / 2));
+ // Position arrow at the right of the focused element
+ left: 100%;
+ right: auto;
+ }
+ &:hover:before,
+ &:hover:after,
+ &:focus:before,
+ &:focus:after {
+ // Translate tooltip to the right
+ @include prefix(transform, translateX(12px), 'webkit' 'moz' 'ms' 'o');
+ }
+} \ No newline at end of file
diff --git a/src/scss/components/_video.scss b/src/scss/components/_video.scss
new file mode 100755
index 0000000..c68267f
--- /dev/null
+++ b/src/scss/components/_video.scss
@@ -0,0 +1,20 @@
+// Responsive video container
+.video-container {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ // 16:9 ratio, consider as height value
+ padding-bottom: 56.25%;
+ margin: 0 0 1.75em 0;
+
+ iframe,
+ object,
+ embed {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ margin-top: 0;
+ }
+} \ No newline at end of file
diff --git a/src/scss/layouts/_about.scss b/src/scss/layouts/_about.scss
new file mode 100755
index 0000000..6d7bb91
--- /dev/null
+++ b/src/scss/layouts/_about.scss
@@ -0,0 +1,113 @@
+#about {
+ display: none;
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: map-get($about, background);
+ text-align: center;
+ line-height: 100%;
+ overflow-y: auto;
+ overflow-x: hidden;
+ z-index: map-get($z-indexes, l-about);
+
+ #about-card {
+ position: relative;
+ // Position the card out the page to improve the javascript drop effect
+ top: -1000px;
+ display: block;
+ background: white;
+ max-width: 400px;
+ margin: 15px auto;
+ border-radius: 3px;
+ padding: 30px 0;
+ @include prefix(box-shadow, 0 0 5px rgba(0, 0, 0, 0.50), 'webkit' 'moz');
+
+ #about-btn-close {
+ position: absolute;
+ top: 15px;
+ right: 15px;
+ color: map-get($colors, light);
+ cursor: pointer;
+
+ &:hover {
+ color: darken(map-get($colors, light), 15);
+ }
+ }
+ #about-card-picture {
+ margin-bottom: 15px;
+ }
+ #about-card-name {
+ margin-top: 0;
+ margin-bottom: 20px;
+ }
+ #about-card-bio {
+ padding: 0 30px;
+ margin: 0 0 30px 0;
+ }
+ #about-card-job,
+ #about-card-location {
+ display: inline-block;
+ vertical-align: top;
+ }
+ #about-card-job,
+ #about-card-location,
+ #about-card-bio {
+ font-size: $font-size-base;
+ line-height: $line-height-base;
+ font-weight: 400;
+ color: map-get($colors, base);
+ }
+ }
+}
+
+// Improve responsiveness of about card on small screen and down
+@media #{$small-and-down} {
+ #about {
+ #about-card {
+ width: 90%;
+
+ #about-card-job,
+ #about-card-location {
+ display: block;
+ width: calc(100% - 60px); // 60px = padding right + padding left of `#about-card`
+ padding: 0 30px;
+ }
+ #about-card-picture {
+ width: 90px;
+ height: 90px;
+ border-radius: 45px;
+ }
+ #about-card-job {
+ margin-bottom: 15px;
+ }
+ }
+ }
+}
+
+// Improve responsiveness of about card on medium screen and up
+@media #{$medium-and-up} {
+ #about {
+ #about-card {
+ width: 80%;
+ #about-card-picture {
+ width: 110px;
+ height: 110px;
+ border-radius: 55px;
+ }
+ #about-card-job,
+ #about-card-location {
+ display: inline-block;
+ // 48px = padding right of `#about-card-job` + `#about-card-location`
+ width: calc((100% / 2) - 48px);
+ }
+ #about-card-job {
+ padding: 0 15px 0 30px;
+ }
+ #about-card-location {
+ padding: 0 30px 0 15px;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/layouts/_blog.scss b/src/scss/layouts/_blog.scss
new file mode 100755
index 0000000..03f16f9
--- /dev/null
+++ b/src/scss/layouts/_blog.scss
@@ -0,0 +1,7 @@
+#blog {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+} \ No newline at end of file
diff --git a/src/scss/layouts/_bottom-bar.scss b/src/scss/layouts/_bottom-bar.scss
new file mode 100755
index 0000000..b4d5119
--- /dev/null
+++ b/src/scss/layouts/_bottom-bar.scss
@@ -0,0 +1,119 @@
+// bottom bar which contains navigation and share options
+#bottom-bar {
+ display: none;
+ position: fixed;
+ bottom: 0;
+ height: 60px;
+ background: white;
+ margin: 0;
+ border-top: 1px solid #eef2f8;
+ padding: 0 15px;
+ z-index: map-get($z-indexes, c-post-bottom-bar);
+ transition: transform .25s ease-in-out;
+ -webkit-transition: -webkit-transform .25s ease-in-out;
+}
+
+@media #{$small-and-down} {
+ #bottom-bar {
+ // Display bottom bar in large size
+ @include bottom-bar-lg;
+
+ // Push the bottom bar from the size of the large sidebar
+ &[data-behavior="1"],
+ &[data-behavior="2"],
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ @include bottom-bar-pushed-lg;
+ }
+ // Push the bottom bar from the size of the medium sidebar
+ &[data-behavior="3"],
+ &[data-behavior="6"] {
+ @include bottom-bar-pushed-md;
+ }
+ }
+}
+
+@media #{$medium-only} {
+ #bottom-bar {
+ // Display bottom bar in medium size and push it from the size of the medium sidebar
+ &[data-behavior="1"],
+ &[data-behavior="2"],
+ &[data-behavior="3"] {
+ @include bottom-bar-md;
+ @include bottom-bar-pushed-md;
+ }
+ // Display bottom bar in large size and push it from the size of the large sidebar
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ @include bottom-bar-lg;
+ @include bottom-bar-pushed-lg;
+ }
+ // Display bottom bar in large size and push it from the size of the medium sidebar
+ &[data-behavior="6"] {
+ @include bottom-bar-lg;
+ @include bottom-bar-pushed-md;
+ }
+ }
+}
+
+@media #{$large-only} {
+ #bottom-bar {
+ // Display bottom bar in small size and push it from the size of the large sidebar
+ &[data-behavior="1"],
+ &[data-behavior="2"] {
+ @include bottom-bar-sm;
+ @include bottom-bar-pushed-lg;
+ }
+ // Display bottom bar in medium size and push it from the size of the medium sidebar
+ &[data-behavior="3"] {
+ @include bottom-bar-md;
+ @include bottom-bar-pushed-md;
+ }
+ // Display bottom bar in large size and push it from the size of the large sidebar
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ @include bottom-bar-lg;
+ @include bottom-bar-pushed-lg;
+ }
+ // Display bottom bar in large size and push it from the size of the medium sidebar
+ &[data-behavior="6"] {
+ @include bottom-bar-lg;
+ @include bottom-bar-pushed-md;
+ }
+ }
+}
+
+@media #{$xlarge-and-up} {
+ #bottom-bar {
+ // Display bottom bar in extra small size and push it from the size of the extra large sidebar
+ &[data-behavior="1"] {
+ @include bottom-bar-xs;
+ @include bottom-bar-pushed-xlg;
+ }
+ // Display bottom bar in small size and push it from the size of the large sidebar
+ &[data-behavior="2"] {
+ @include bottom-bar-sm;
+ @include bottom-bar-pushed-lg;
+ }
+ // Display bottom bar in medium size and push it from the size of the medium sidebar
+ &[data-behavior="3"] {
+ @include bottom-bar-md;
+ @include bottom-bar-pushed-md;
+ }
+ // Display bottom bar in large size and push it from the size of the extra large sidebar
+ &[data-behavior="4"] {
+ @include bottom-bar-lg;
+ @include bottom-bar-pushed-xlg;
+ }
+ // Display bottom bar in large size and push it from the size of the extra large sidebar
+ &[data-behavior="5"] {
+ @include bottom-bar-lg;
+ @include bottom-bar-pushed-lg;
+ }
+ // Display bottom bar in large size and push it from the size of the medium sidebar
+ &[data-behavior="6"] {
+ @include bottom-bar-lg;
+ @include bottom-bar-pushed-md;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/layouts/_cover.scss b/src/scss/layouts/_cover.scss
new file mode 100755
index 0000000..f198323
--- /dev/null
+++ b/src/scss/layouts/_cover.scss
@@ -0,0 +1,11 @@
+#cover {
+ position: fixed;
+ width: 100%;
+ height: 100%;
+ background-repeat: no-repeat;
+ background-size: cover;
+ top: 0;
+ left: 0;
+ // position the cover below the whole blog
+ z-index: map-get($z-indexes, l-cover);
+} \ No newline at end of file
diff --git a/src/scss/layouts/_footer.scss b/src/scss/layouts/_footer.scss
new file mode 100755
index 0000000..09f1fad
--- /dev/null
+++ b/src/scss/layouts/_footer.scss
@@ -0,0 +1,8 @@
+#footer {
+ color: map-get($colors, light);
+ font-size: map-get($font-size, medium);
+ text-align: center;
+ margin-top: 70px;
+ height: auto;
+ padding: 20px 20px;
+} \ No newline at end of file
diff --git a/src/scss/layouts/_header.scss b/src/scss/layouts/_header.scss
new file mode 100755
index 0000000..dc71569
--- /dev/null
+++ b/src/scss/layouts/_header.scss
@@ -0,0 +1,112 @@
+#header {
+ display: block;
+ width: 100%;
+ height: map-get($header, height);
+ background: map-get($header, background);
+ position: fixed;
+ top: 0;
+ border: map-get($header, border);
+ color: map-get($header, color);
+ // used to animate the header on small screen with javascript
+ //@include prefix(transition, top 0.25s ease-in-out, 'webkit' 'moz' 'ms' 'o');
+ z-index: map-get($z-indexes, l-header);
+ // Sidebar animation
+ // Transition style (push)
+ transition: transform .25s ease-in-out;
+ -webkit-transition: -webkit-transform .25s ease-in-out;
+ // Eliminate any flickering of elements while they are in a state of being animated
+ -webkit-backface-visibility: hidden;
+ -webkit-perspective: 1000;
+
+ #btn-open-sidebar {
+ position: absolute;
+ // vertical center
+ top: 20px;
+ left: 20px;
+ cursor: pointer;
+ }
+ .header-right-picture {
+ position: absolute;
+ // vertical center
+ top: 12.5px;
+ right: 20px;
+ display: block;
+ width: 30px;
+ height: 30px;
+ color: map-get($header, color);
+
+ .header-picture {
+ display: block;
+ width: 30px;
+ height: 30px;
+ border-radius: 15px;
+ }
+ }
+ .header-right-icon {
+ position: absolute;
+ // vertical center
+ top: 12.5px;
+ right: 20px;
+ color: map-get($header, color);
+ }
+ .header-title {
+ text-align: center;
+ font-size: $font-size-base;
+ line-height: 55px;
+ margin: 0;
+
+ .header-title-link {
+ color: map-get($header, color);
+ font-weight: normal;
+
+ &:hover,
+ &:active {
+ color: darken(map-get($header, color), 10);
+ text-decoration: none;
+ }
+ }
+ }
+ // Class used to swipe to the top the header on small screen when the user scroll down
+ &.header-up {
+ @include prefix(transform, translate3d(0, -#{map-get($header, height)}, 0), 'webkit' 'moz');
+ }
+
+ // Push the header from the size of the large sidebar
+ &[data-behavior="1"],
+ &[data-behavior="2"],
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ @include header-pushed-lg;
+ }
+
+ // Push the header from the size of the medium sidebar
+ &[data-behavior="3"],
+ &[data-behavior="6"] {
+ @include header-pushed-md;
+ }
+}
+
+@media #{$medium-and-up} {
+ #header {
+ // Hide header
+ &[data-behavior="1"],
+ &[data-behavior="2"],
+ &[data-behavior="3"] {
+ display: none;
+ }
+ }
+}
+
+// Push the header from the size of the extra large sidebar
+@media #{$xlarge-and-up} {
+ #header {
+ &[data-behavior="1"],
+ &[data-behavior="4"] {
+ @include header-pushed-xlg;
+ }
+ &[data-behavior="2"],
+ &[data-behavior="5"] {
+ @include header-pushed-lg;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/layouts/_main.scss b/src/scss/layouts/_main.scss
new file mode 100755
index 0000000..782ae58
--- /dev/null
+++ b/src/scss/layouts/_main.scss
@@ -0,0 +1,127 @@
+#main {
+ display: block;
+ min-height: 100%;
+ background: map-get($main, 'background-color');
+ transition: transform .25s ease-in-out;
+ -webkit-transition: -webkit-transform .25s ease-in-out;
+
+ &.hasCover {
+ // Set `padding-top` to `50px` when there is a cover image on page and
+ // if there is a cover caption or
+ // if its meta information are out of cover image
+ &.hasCoverCaption,
+ &.hasCoverMetaOut {
+ padding-top: 50px !important;
+ }
+
+ // Set `padding-top` to 0 when there is a cover image on page and
+ // if its meta information are on image or
+ // if its meta information are out of cover image and
+ // if there is a cover caption
+ //
+ // The cover caption have a `margin-top` to `50px` to replace the padding
+ &.hasCoverMetaIn,
+ &.hasCoverMetaOut.hasCoverCaption {
+ padding-top: 0 !important;
+ }
+ }
+}
+
+@media #{$small-and-down} {
+ #main {
+ // Display `main` div in large size
+ @include main-lg;
+
+ // Push `main` div from the size of the large sidebar
+ &[data-behavior="1"],
+ &[data-behavior="2"],
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ @include main-pushed-lg;
+ }
+ // Push `main` div from the size of the medium sidebar
+ &[data-behavior="3"],
+ &[data-behavior="6"] {
+ @include main-pushed-md;
+ }
+ }
+}
+
+@media #{$medium-only} {
+ #main {
+ // Display `main` div in medium size
+ &[data-behavior="1"],
+ &[data-behavior="2"],
+ &[data-behavior="3"] {
+ @include main-md;
+ }
+ // Display `main` div in large size and push it from the size of the large sidebar
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ @include main-lg;
+ @include main-pushed-lg;
+ }
+ // Display `main` div in large size and push it from the size of the medium sidebar
+ &[data-behavior="6"] {
+ @include main-lg;
+ @include main-pushed-md;
+ }
+ }
+}
+
+@media #{$large-only} {
+ #main {
+ // Display `main` div in small size
+ &[data-behavior="1"],
+ &[data-behavior="2"] {
+ @include main-sm;
+ }
+ // Display `main` div in medium size
+ &[data-behavior="3"] {
+ @include main-md;
+ }
+ // Display `main` div in large size and push it from the size of the large sidebar
+ &[data-behavior="4"],
+ &[data-behavior="5"]{
+ @include main-lg;
+ @include main-pushed-lg;
+ }
+ // Display `main` div in large size and push it from the size of the medium sidebar
+ &[data-behavior="6"] {
+ @include main-lg;
+ @include main-pushed-md;
+ }
+ }
+}
+
+@media #{$xlarge-and-up} {
+ #main {
+ // Display `main` div in extra small size
+ &[data-behavior="1"] {
+ @include main-xs;
+ }
+ // Display `main` div in small size
+ &[data-behavior="2"] {
+ @include main-sm;
+ }
+ // Display `main` div in medium size
+ &[data-behavior="3"] {
+ @include main-md;
+ }
+ // Display `main` div in large size and push it from the size of the extra large sidebar
+ &[data-behavior="4"] {
+ @include main-lg;
+ @include main-pushed-xlg;
+ }
+ // Display `main` div in large size and push it from the size of the extra large sidebar
+ &[data-behavior="5"] {
+ @include main-lg;
+ @include main-pushed-lg;
+ }
+ // Display `main` div in large size and push it from the size of the medium sidebar
+ &[data-behavior="6"] {
+ @include main-lg;
+ @include main-pushed-md;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/layouts/_sidebar.scss b/src/scss/layouts/_sidebar.scss
new file mode 100755
index 0000000..0275397
--- /dev/null
+++ b/src/scss/layouts/_sidebar.scss
@@ -0,0 +1,168 @@
+// Global CSS rules for all screen size
+#sidebar {
+ font-family: map-get($font-families, 'sidebar');
+ height: 100%;
+ position: fixed;
+ top: 0;
+ background: map-get($sidebar, background);
+ overflow: auto;
+ z-index: map-get($z-indexes, l-sidebar);
+ // Sidebar animation
+ // Transition style (push)
+ transition: transform .25s ease-in-out;
+ -webkit-transition: -webkit-transform .25s ease-in-out;
+ // Improve smoothing of the font by adding subpixel in Safari
+ @include prefix(font-smoothing, antialiased, 'webkit');
+
+ .sidebar-container {
+ overflow: auto;
+ }
+ // Author information
+ .sidebar-profile {
+ color: map-get($sidebar, color);
+ text-align: center;
+ padding-top: 18px;
+ margin-bottom: 15px;
+
+ .sidebar-profile-picture {
+ display: block;
+ margin: 0 auto;
+ }
+ .sidebar-profile-name {
+ font-size: 1.1em;
+ color: map-get($sidebar, color);
+ }
+ }
+ // Sidebar's buttons
+ ul.sidebar-buttons {
+ padding: 0;
+ margin: 0 0 20px 0;
+
+ li.sidebar-button {
+ display: block;
+ width: 100%;
+ // Height of a link in the menu
+ height: 45px;
+ line-height: 45px;
+
+ .sidebar-button-link {
+ color: map-get($sidebar, color);
+ display: block;
+ height: 100%;
+
+ &:hover,
+ &:active {
+ text-decoration: none;
+ color: lighten(map-get($sidebar, color), 35);
+ }
+ }
+ }
+ &:first-child {
+ margin-top: 5px;
+ }
+ }
+}
+
+// Define sidebar behavior configured in `_config.yml` for small screen
+// On `$small-and-down` (small screen): It hide by default the sidebar
+// and with javascript located in `source/_js/_sidebar.js`, it will animate the swipe of the sidebar
+@media #{$small-and-down} {
+ #sidebar {
+ &[data-behavior="1"],
+ &[data-behavior="2"],
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ left: -#{map-get($sidebar, lg-screen-width)};
+ @include sidebar-lg;
+ }
+ &[data-behavior="3"],
+ &[data-behavior="6"] {
+ left: -#{map-get($sidebar, md-screen-width)};
+ @include sidebar-md;
+ }
+ }
+}
+
+// Define sidebar behavior configured in `_config.yml` for medium screen
+@media #{$medium-only} {
+ #sidebar {
+ &[data-behavior="1"],
+ &[data-behavior="2"],
+ &[data-behavior="3"] {
+ @include sidebar-md;
+ }
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ left: -#{map-get($sidebar, lg-screen-width)};
+ @include sidebar-lg;
+ }
+ &[data-behavior="6"] {
+ left: -#{map-get($sidebar, md-screen-width)};
+ @include sidebar-md;
+ }
+ }
+}
+
+// Define sidebar behavior configured in `_config.yml` for large screen
+@media #{$large-only} {
+ #sidebar {
+ &[data-behavior="1"],
+ &[data-behavior="2"] {
+ @include sidebar-lg;
+ }
+ &[data-behavior="3"] {
+ @include sidebar-md;
+ }
+ &[data-behavior="4"],
+ &[data-behavior="5"] {
+ left: -#{map-get($sidebar, lg-screen-width)};
+ @include sidebar-lg;
+ }
+ &[data-behavior="6"] {
+ left: -#{map-get($sidebar, md-screen-width)};
+ @include sidebar-md;
+ }
+ }
+}
+
+@media #{$xlarge-and-up} {
+ #sidebar {
+ &[data-behavior="1"] {
+ @include sidebar-xlg;
+ }
+ &[data-behavior="2"] {
+ @include sidebar-lg;
+ }
+ &[data-behavior="3"] {
+ @include sidebar-md;
+ }
+ &[data-behavior="4"] {
+ left: -#{map-get($sidebar, xlg-screen-width)};
+ @include sidebar-xlg;
+ }
+ &[data-behavior="5"] {
+ left: -#{map-get($sidebar, lg-screen-width)};
+ @include sidebar-lg;
+ }
+ &[data-behavior="6"] {
+ left: -#{map-get($sidebar, md-screen-width)};
+ @include sidebar-md;
+ }
+ // hide bio in sidebar when small sidebar is enabled
+ &[data-behavior="2"],
+ &[data-behavior="3"],
+ &[data-behavior="5"],
+ &[data-behavior="6"] {
+ .sidebar-profile-bio {
+ display: none;
+ }
+ }
+ }
+}
+
+// display author bio only on extra large screen
+@media #{$large-and-down} {
+ #sidebar .sidebar-profile-bio {
+ display: none;
+ }
+}
diff --git a/src/scss/pages/_search.scss b/src/scss/pages/_search.scss
new file mode 100755
index 0000000..26077d5
--- /dev/null
+++ b/src/scss/pages/_search.scss
@@ -0,0 +1,60 @@
+#algolia-search-modal {
+ display: none;
+
+ .search-icon {
+ position: absolute;
+ top: 15px;
+ left: 15px;
+ color: $font-color-base;
+ }
+ .media-content {
+ font-size: 0.95em;
+ }
+ .search-input {
+ box-sizing: border-box;
+ padding: 0 130px 0 25px;
+ margin: 0;
+ }
+ .modal-header {
+ padding-bottom: 8px;
+ }
+ .modal-body {
+ padding-top: 15px;
+ // minus its padding and height of header bar and footer bar
+ height: calc(100% - 100px - 15px);
+ }
+
+ .media:nth-child(n+2) {
+ padding-top: 15px;
+ }
+ hr {
+ margin-top: 0;
+ }
+ .results-count {
+ line-height: 50px;
+ color: $font-color-base;
+ }
+ .searchby-algolia {
+ position: absolute;
+ top: 15px;
+ right: 45px;
+ }
+ .searchby-algolia-text {
+ display: inline-block;
+ vertical-align: top;
+ line-height: 20px;
+ height: 20px;
+ }
+ .searchby-algolia-logo {
+ display: inline-block;
+ vertical-align: top;
+ height: 20px;
+ }
+ .no-result {
+ display: none;
+ position: relative;
+ top: 50%;
+ transform: translateY(-50%);
+ }
+}
+
diff --git a/src/scss/themes/_hljs-custom.scss b/src/scss/themes/_hljs-custom.scss
new file mode 100755
index 0000000..3da9e5f
--- /dev/null
+++ b/src/scss/themes/_hljs-custom.scss
@@ -0,0 +1,51 @@
+// Highlight.js custom theme
+// Follow guidelines
+// 1. Uncomment the block just below - remove `/*` and `*/`
+// 2. Fill `background`, `color`, `border-right-color` properties
+// with properties of `.hljs` CSS class of your theme
+// 3. Put your theme where it's indicated just below
+// 4. Remove `.hljs {...}` rules
+// 5. Remove `hljs-` of all CSS class name. E.g : `.hljs-comment` becomes `.comment`
+// 6. Comment line 61 (`'themes/tranquilpeak',`) of `source/_css/tranquilpeak.scss` file
+// 7. Run `grunt buildProd` to build the theme and see the result
+/*
+// Default code block
+pre > code {
+ background: ;
+ color: ;
+}
+
+// Default inline code
+code {
+ background-color: ;
+}
+
+// Tabbed code block tab
+// If your theme is dark then use a lighter background
+// to see clearly which tab is active
+.codeblock--tabbed figcaption .tab.active {
+ background: ;
+ color: ;
+}
+
+// highlight code block
+figure.highlight,
+.codeblock {
+ background: ;
+ color: ;
+
+ figcaption {
+ background: ;
+ color: ;
+ }
+ .gutter {
+ background: ;
+ border-right-color: ;
+ .line {
+ color: ;
+ }
+ }
+ // PUT YOUR THEME HERE
+
+}
+*/ \ No newline at end of file
diff --git a/src/scss/themes/_hljs-tranquilpeak.scss b/src/scss/themes/_hljs-tranquilpeak.scss
new file mode 100755
index 0000000..e374c7f
--- /dev/null
+++ b/src/scss/themes/_hljs-tranquilpeak.scss
@@ -0,0 +1,556 @@
+// Official theme for Tranquilpeak
+// Default code block
+pre > code {
+ background: map-get($highlight, 'background');
+ color: map-get($highlight-colors, night-rider);
+}
+
+// Default inline code
+code {
+ background-color: map-get($highlight, 'background');
+}
+
+// Tabbed code block tab
+.codeblock--tabbed figcaption .tab.active {
+ background: map-get($colors, 'primary');
+ color: white;
+}
+
+// Highlight code block
+figure.highlight,
+.codeblock {
+ background: map-get($highlight, 'background');
+ color: map-get($highlight-colors, night-rider);
+
+ figcaption {
+ background: map-get($highlight, 'background');
+ color: #999999;
+ }
+ .gutter {
+ background: map-get($highlight, 'background');
+ border-right-color: #e6e6e6;
+
+ .line {
+ color: #aaaaaa;
+ }
+ }
+
+ // Highlight code coloration
+ // General
+ .comment {
+ color: map-get($highlight-colors, pewter);
+ }
+ .string {
+ color: map-get($highlight-colors, egyptian-blue);
+ }
+ .keyword {
+ color: map-get($highlight-colors, cardinal);
+ }
+ // ApacheConf
+ &.apacheconf .code {
+ .common,
+ .nomarkup,
+ .attribute,
+ .variable,
+ .cbracket,
+ .keyword {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .sqbracket {
+ color: map-get($highlight-colors, persimmon);
+ }
+ .section,
+ .tag {
+ color: map-get($highlight-colors, asparagus);
+ }
+ }
+ // Bash
+ &.bash .code {
+ .shebang {
+ color: map-get($highlight-colors, pewter);
+ }
+ .literal,
+ .built_in {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .variable {
+ color: map-get($highlight-colors, night-rider);
+ }
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ }
+ // coffescript
+ &.coffeescript .code {
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ .literal,
+ .built_in,
+ .number {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .reserved,
+ .attribute {
+ color: map-get($highlight-colors, bahama-blue);
+ }
+ .subst,
+ .regexp,
+ .attribute {
+ color: map-get($highlight-colors, persimmon);
+ }
+ }
+ // C/C++
+ &.cpp .code,
+ &.c .code {
+ .preprocessor {
+ color: map-get($highlight-colors, persimmon);
+ }
+ .meta-keyword {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .title  {
+ color: map-get($highlight-colors, scampi);
+ }
+ .number,
+ .built_in {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+ // C#
+ &.cs .code {
+ .preprocessor,
+ .preprocessor .keyword {
+ color: map-get($highlight-colors, night-rider);
+ }
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ .number,
+ .built_in {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .xmlDocTag,
+ .doctag {
+ color: map-get($highlight-colors, asparagus);
+ }
+ }
+ // CSS
+ &.css .code {
+ .at_rule,
+ .important,
+ .meta {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .attribute,
+ .hexcolor,
+ .number,
+ .function {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .attr_selector,
+ .value {
+ color: map-get($highlight-colors, night-rider);
+ }
+ .id,
+ .class,
+ .pseudo,
+ .selector-pseudo {
+ color: map-get($highlight-colors, scampi);
+ }
+ .tag,
+ .selector-tag {
+ color: map-get($highlight-colors, asparagus);
+ }
+ }
+ // Diff
+ &.diff .code {
+ .chunk,
+ .meta {
+ color: map-get($highlight-colors, scampi);
+ font-weight: bold;
+ }
+ .addition {
+ color: map-get($highlight-colors, limeade);
+ background-color: map-get($highlight-colors, 'honeydew');
+ }
+ .deletion {
+ color: map-get($highlight-colors, free-speech-red);
+ background-color: map-get($highlight-colors, misty-rose);
+ }
+ }
+ // HTTP
+ &.http .code {
+ .attribute,
+ .attr {
+ color: map-get($highlight-colors, egyptian-blue);
+ }
+ .literal {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .request {
+ color: map-get($highlight-colors, cardinal);
+ }
+ }
+ // INI
+ &.ini .code {
+ .title,
+ .section {
+ color: map-get($highlight-colors, scampi);
+ }
+ .setting,
+ .attr {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .value,
+ .keyword {
+ color: map-get($highlight-colors, night-rider);
+ }
+ }
+ // JAVA
+ &.java .code {
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ .javadoc {
+ color: map-get($highlight-colors, pewter);
+ }
+ .meta,
+ .annotation,
+ .javadoctag {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .number {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .params {
+ color: map-get($highlight-colors, bahama-blue);
+ }
+ }
+ // JavaScript
+ &.js .code {
+ .built_in,
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ .javadoc {
+ color: map-get($highlight-colors, pewter);
+ }
+ .tag,
+ .javadoctag {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .tag .title {
+ color: map-get($highlight-colors, night-rider);
+ }
+ .regexp {
+ color: map-get($highlight-colors, persimmon);
+ }
+ .literal,
+ .number {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+ // JSON
+ &.json .code {
+ .attribute {
+ color: map-get($highlight-colors, egyptian-blue);
+ }
+ .number,
+ .literal {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+ // Makefile
+ &.mak .code {
+ .constant {
+ color: map-get($highlight-colors, night-rider);
+ }
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ .keyword,
+ .meta-keyword {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+ // Markdown
+ &.md .code {
+ .value,
+ .link_label,
+ .strong,
+ .emphasis,
+ .blockquote,
+ .quote,
+ .section {
+ color: map-get($highlight-colors, egyptian-blue);
+ }
+ .link_reference,
+ .symbol,
+ .code {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .link_url,
+ .link {
+ text-decoration: underline;
+ }
+ }
+ // Nginx
+ &.nginx .code {
+ .title,
+ .attribute {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .built_in,
+ .literal {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .regexp {
+ color: map-get($highlight-colors, egyptian-blue);
+ }
+ .variable {
+ color: map-get($highlight-colors, night-rider);
+ }
+ }
+ // Objective-C
+ &.objectivec .code {
+ .preprocessor,
+ .meta {
+ color: map-get($highlight-colors, cardinal);
+
+ .title {
+ color: map-get($highlight-colors, persimmon);
+ }
+ }
+ .meta-string {
+ color: map-get($highlight-colors, egyptian-blue);
+ }
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ .literal,
+ .number,
+ .built_in {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+ // Perl
+ &.perl .code {
+ .sub {
+ color: map-get($highlight-colors, scampi);
+ }
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ .regexp {
+ color: map-get($highlight-colors, persimmon);
+ }
+
+ }
+ // PHP
+ &.php .code {
+ .phpdoc,
+ .doctag {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .regexp {
+ color: map-get($highlight-colors, persimmon);
+ }
+ .literal,
+ .number {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ }
+ // Python
+ &.python .code {
+ .decorator,
+ .title,
+ .meta {
+ color: map-get($highlight-colors, scampi);
+ }
+ .number {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+ // Ruby
+ &.ruby .code {
+ .parent,
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ .prompt,
+ .constant,
+ .number,
+ .subst .keyword,
+ .symbol {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+ // SQL
+ &.sql {
+ .built_in {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .number {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+ // XML, HTML
+ &.xml,
+ &.html {
+ .tag {
+ color: map-get($highlight-colors, night-rider);
+ }
+ .value {
+ color: map-get($highlight-colors, egyptian-blue);
+ }
+ .attribute,
+ .attr {
+ color: map-get($highlight-colors, scampi);
+ }
+ .title,
+ .name {
+ color: map-get($highlight-colors, asparagus);
+ }
+ }
+ // Puppet
+ &.puppet {
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ .function {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .name {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .attr {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+ // LESS
+ &.less {
+ .tag,
+ .at_rule {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .number,
+ .hexcolor,
+ .function,
+ .attribute {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .built_in {
+ color: map-get($highlight-colors, persimmon);
+ }
+ .id,
+ .pseudo,
+ .class,
+ .selector-id,
+ .selector-class,
+ .selector-tag {
+ color: map-get($highlight-colors, scampi);
+ }
+ }
+ // SCSS
+ &.scss {
+ .tag,
+ .at_rule,
+ .important {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .number,
+ .hexcolor,
+ .function,
+ .attribute {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .variable {
+ color: map-get($highlight-colors, night-rider);
+ }
+ .built_in {
+ color: map-get($highlight-colors, persimmon);
+ }
+ .id,
+ .pseudo,
+ .class,
+ .preprocessor,
+ .selector-class,
+ .selector-id {
+ color: map-get($highlight-colors, scampi);
+ }
+ .tag,
+ .selector-tag {
+ color: map-get($highlight-colors, asparagus);
+ }
+ }
+ // Stylus
+ &.stylus {
+ .at_rule {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .tag,
+ .selector-tag {
+ color: map-get($highlight-colors, asparagus);
+ }
+ .number,
+ .hexcolor,
+ .attribute,
+ .params {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ .class,
+ .id,
+ .pseudo,
+ .title,
+ .selector-id,
+ .selector-pseudo,
+ .selector-class {
+ color: map-get($highlight-colors, scampi);
+ }
+ }
+ // Go
+ &.go {
+ .typename {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .built_in,
+ .constant {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+ // Swift
+ &.swift {
+ .preprocessor {
+ color: map-get($highlight-colors, cardinal);
+ }
+ .title {
+ color: map-get($highlight-colors, scampi);
+ }
+ .built_in,
+ .number,
+ .type {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+ // YAML
+ &.yml {
+ .line
+ .attr {
+ color: map-get($highlight-colors, asparagus);
+ }
+ .line,
+ .string,
+ .type,
+ .literal,
+ .meta {
+ color: map-get($highlight-colors, egyptian-blue);
+ }
+ .number {
+ color: map-get($highlight-colors, bondi-blue);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/scss/tranquilpeak.scss b/src/scss/tranquilpeak.scss
new file mode 100755
index 0000000..0181f98
--- /dev/null
+++ b/src/scss/tranquilpeak.scss
@@ -0,0 +1,66 @@
+@import
+ 'utils/fonts',
+ 'utils/variables';
+
+@import
+ 'utils/mixins/bottom-bar',
+ 'utils/mixins/button',
+ 'utils/mixins/category',
+ 'utils/mixins/form',
+ 'utils/mixins/header',
+ 'utils/mixins/main',
+ 'utils/mixins/opacity',
+ 'utils/mixins/post-header-cover',
+ 'utils/mixins/prefix',
+ 'utils/mixins/share-options-bar',
+ 'utils/mixins/sidebar',
+ 'utils/mixins/tag';
+
+@import
+ 'base/base';
+
+@import 'layouts/about',
+'layouts/blog',
+'layouts/bottom-bar',
+'layouts/cover',
+'layouts/footer',
+'layouts/header',
+'layouts/main',
+'layouts/sidebar';
+
+@import
+ 'components/alert',
+ 'components/archive',
+ 'components/box',
+ 'components/button',
+ 'components/caption',
+ 'components/code',
+ 'components/figure',
+ 'components/form',
+ 'components/hide',
+ 'components/highlight-text',
+ 'components/icon',
+ 'components/image-gallery',
+ 'components/link',
+ 'components/main-content',
+ 'components/markdown',
+ 'components/media',
+ 'components/modal',
+ 'components/pagination',
+ 'components/post',
+ 'components/post-actions',
+ 'components/pullquote',
+ 'components/post-header-cover',
+ 'components/postShorten',
+ 'components/share-options-bar',
+ 'components/tag',
+ 'components/text',
+ 'components/tooltip',
+ 'components/video';
+
+@import
+ 'pages/search';
+
+@import
+ 'themes/hljs-tranquilpeak',
+ 'themes/hljs-custom'; \ No newline at end of file
diff --git a/src/scss/utils/_fonts.scss b/src/scss/utils/_fonts.scss
new file mode 100755
index 0000000..9047a9e
--- /dev/null
+++ b/src/scss/utils/_fonts.scss
@@ -0,0 +1,48 @@
+@font-face {
+ font-family: 'Open Sans';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v10/cJZKeOuBrn4kERxqtaUH3SZ2oysoEQEeKwjgmXLRnTc.ttf) format('truetype');
+}
+
+@font-face {
+ font-family: 'Open Sans';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v10/k3k702ZOKiLJc3WVjuplzJS3E-kSBmtLoNJPDtbj2Pk.ttf) format('truetype');
+}
+
+@font-face {
+ font-family: 'Merriweather';
+ font-style: normal;
+ font-weight: 300;
+ src: local('Merriweather Light'), local('Merriweather-Light'), url(https://fonts.gstatic.com/s/merriweather/v8/ZvcMqxEwPfh2qDWBPxn6nk7nEl83IKQRaQwpv_tz1Eg.ttf) format('truetype');
+}
+
+@font-face {
+ font-family: 'Merriweather';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Merriweather'), url(https://fonts.gstatic.com/s/merriweather/v8/RFda8w1V0eDZheqfcyQ4EJS3E-kSBmtLoNJPDtbj2Pk.ttf) format('truetype');
+}
+
+@font-face {
+ font-family: 'Merriweather';
+ font-style: normal;
+ font-weight: 700;
+ src: local('Merriweather Bold'), local('Merriweather-Bold'), url(https://fonts.gstatic.com/s/merriweather/v8/ZvcMqxEwPfh2qDWBPxn6nv83cGrqhiQgWmjXfohD0fc.ttf) format('truetype');
+}
+
+@font-face {
+ font-family: 'Merriweather';
+ font-style: italic;
+ font-weight: 300;
+ src: local('Merriweather Light Italic'), local('Merriweather-LightItalic'), url(https://fonts.gstatic.com/s/merriweather/v8/EYh7Vl4ywhowqULgRdYwIGrKw6K5wsYdxr6rUL2ZGaM.ttf) format('truetype');
+}
+
+@font-face {
+ font-family: 'Merriweather';
+ font-style: italic;
+ font-weight: 700;
+ src: local('Merriweather Bold Italic'), local('Merriweather-BoldItalic'), url(https://fonts.gstatic.com/s/merriweather/v8/EYh7Vl4ywhowqULgRdYwII1kRdeHIFWYEsp6A2f99b0.ttf) format('truetype');
+} \ No newline at end of file
diff --git a/src/scss/utils/_variables.scss b/src/scss/utils/_variables.scss
new file mode 100755
index 0000000..4140626
--- /dev/null
+++ b/src/scss/utils/_variables.scss
@@ -0,0 +1,256 @@
+// Global settings
+// --------------------------------------------
+
+// Font families
+$open-sans: 'Open Sans';
+$open-sans-sans-serif: 'Open Sans', sans-serif;
+$merriweather-serif: 'Merriweather', serif;
+$menlo: Menlo;
+
+$font-family-base: $open-sans-sans-serif;
+
+$font-families: (
+ // base
+ 'headings': $open-sans-sans-serif,
+ // components
+ 'code': $menlo,
+ 'caption': $merriweather-serif,
+ 'image-gallery': $open-sans,
+ 'post-header-cover': $merriweather-serif,
+ 'post-meta': $open-sans-sans-serif,
+ 'post-content': $merriweather-serif,
+ 'post-excerpt-link': $open-sans-sans-serif,
+ 'highlight': $menlo,
+ // layout
+ 'sidebar': $open-sans-sans-serif
+);
+
+// equal to 15px
+$font-size-base: 1.6rem;
+$font-color-base: #5d686f;
+$line-height-base: 1.9em;
+$letter-spacing-base: 0.01em;
+
+// Reduction of font size base on small screen and down
+$font-size-base-sm-screen-reduction-factor: 0.1rem;
+
+// Font size : (X.Xrem = XXpx, 1.0rem = 10px)
+$font-size: (
+ 'xxlarge': 2rem,
+ 'xlarge': 1.8rem,
+ 'large': 1.7rem,
+ 'base': $font-size-base,
+ 'medium': 1.5rem,
+ 'small': 1.3rem,
+ 'xsmall': 1rem
+);
+
+// Colors
+$colors: (
+ 'success': #4dc657,
+ 'danger': #f5311d,
+ 'primary': #349ef3,
+ 'purple': #cf6ae0,
+ 'base': $font-color-base,
+ 'warning': #f5aa0a,
+ 'light': #9eabb3,
+ // use for tag `a`
+ 'link': #349ef3
+);
+
+// Z-indexes
+// `l-` prefix for layout
+// `c-` prefix for components
+$z-indexes: (
+ // position the cover below the whole blog
+ 'l-cover': -1,
+ 'l-main': 10,
+ 'c-post-header-cover': 15,
+ 'l-header': 20,
+ 'l-sidebar': 20,
+ 'l-about': 30,
+ 'c-mask': 30,
+ 'c-post-bottom-bar': 40,
+ 'c-share-options-bar': 50,
+ 'c-tooltip': 1000,
+ 'c-overlay': 1009,
+ 'c-modal': 1010
+);
+
+// Media Query Ranges
+// If you want to change ranges screen size, you can do it easily by changing only `$screen-min` values
+$screen-min: (
+ 'xs-min': 320px,
+ 'sm-min': 480px,
+ // If you change value of `md-min`,
+ // you have to change value of `mediumScreenWidth` too in `source/_js/sidebar.js`
+ 'md-min': 768px,
+ 'lg-min': 1024px,
+ 'xlg-min': 1280px
+);
+$screen-max: (
+ 'xs-max': map-get($screen-min, sm-min) - 1,
+ 'sm-max': map-get($screen-min, md-min) - 1,
+ 'md-max': map-get($screen-min, lg-min) - 1,
+ 'lg-max': map-get($screen-min, xlg-min) - 1
+);
+// Merged screen-* Maps
+$screen: map-merge($screen-min, $screen-max);
+// Shortcuts for medias
+$xsmall-and-down: "only screen and (max-width : #{map-get($screen, xs-max)})" !default;
+$small-and-down: "only screen and (max-width : #{map-get($screen, sm-max)})" !default;
+$small-only: "only screen and (min-width : #{map-get($screen, sm-min)}) and (max-width : #{map-get($screen, sm-max)})" !default;
+$small-and-up: "only screen and (min-width : #{map-get($screen, sm-min)})" !default;
+$medium-and-down: "only screen and (max-width : #{map-get($screen, md-max)})" !default;
+$medium-only: "only screen and (min-width : #{map-get($screen, md-min)}) and (max-width : #{map-get($screen, md-max)})" !default;
+$medium-and-up: "only screen and (min-width : #{map-get($screen, md-min)})" !default;
+$large-and-down: "only screen and (max-width : #{map-get($screen, lg-max)})" !default;
+$large-only: "only screen and (min-width : #{map-get($screen, lg-min)}) and (max-width : #{map-get($screen, lg-max)})" !default;
+$large-and-up: "only screen and (min-width : #{map-get($screen, lg-min)})" !default;
+$xlarge-and-up: "only screen and (min-width : #{map-get($screen, xlg-min)})" !default;
+
+// Base settings
+// Files are located in `base` folder
+// --------------------------------------------
+
+// Headings font-size : (X.Xrem = XXpx, 1.0rem = 10px)
+$headings-font-size: (
+ 'h1': 2.8rem,
+ 'h2': 2.4rem,
+ 'h3': 2.0rem,
+ 'h4': 1.8rem,
+ 'h5': 1.7rem,
+ 'h6': 1.6rem
+);
+// Reduction of headings font size on small screen and down
+$headings-font-size-sm-screen-reduction-factor: 0.2rem;
+// Reduction of headings font size on medium screen only
+$headings-font-size-md-screen-reduction-factor: 0.15rem;
+
+// Layout settings
+// Files are located in `layout` folder
+// --------------------------------------------
+
+// Main
+$about: (
+ 'background': rgba(17, 26, 35, 0),
+);
+
+// Header
+$header:(
+ 'height': 55px,
+ 'background': #fff,
+ 'color': #88909a,
+ 'border': 1px solid #eef2f8
+);
+
+// Sidebar
+$sidebar: (
+ 'md-screen-width': 75px,
+ 'lg-screen-width': 250px,
+ 'xlg-screen-width': 500px,
+ 'background': rgba(17, 26, 35, 0),
+ 'color': #ebebeb
+);
+
+// Main
+$main: (
+ 'padding-top': 15px,
+ 'background-color': #fff
+);
+
+// Components settings
+// Files are located in `components` folder
+// --------------------------------------------
+
+// Highlight code
+$highlight: (
+ 'background': #f7f8f8,
+ 'font-size': 1.4rem,
+ 'border': 1px solid,
+ 'line-height': 1.3em
+);
+
+// Highlight colors
+// name of colors: http://www.color-blindness.com
+$highlight-colors: (
+ // Background
+ 'white': #fff,
+ // General color
+ 'night-rider': #333,
+ 'bondi-blue': #0086b3,
+ 'persimmon': #df5000,
+ 'asparagus': #63a35c,
+ // Comment
+ 'pewter': #969896,
+ 'cardinal': #a71d5d,
+ 'scampi': #795da3,
+ 'bahama-blue': #1d3e81,
+ 'egyptian-blue': #183691,
+ // Deletion color for .diff file
+ 'free-speech-red': #bd2c00,
+ // Deletion background color for .diff file
+ 'misty-rose': #ffecec,
+ // Addition color for .diff file
+ 'limeade': #55a532,
+ // Addition background color for .diff file
+ 'honeydew': #eaffea
+);
+// Highlight text
+$highlight-text-bg-colors: (
+ 'red': lighten(red, 45%),
+ 'green': lighten(green, 65%),
+ 'blue': lighten(blue, 45%),
+ 'purple': lighten(purple, 70%),
+ 'orange': lighten(orange, 40%),
+ 'yellow': lighten(yellow, 40%),
+ 'cyan': lighten(cyan, 40%),
+ 'primary': lighten(map-get($colors, 'primary'), 35%),
+ 'success': lighten(map-get($colors, 'success'),35%),
+ 'warning': lighten(map-get($colors, 'warning'), 40%),
+ 'danger': lighten(map-get($colors, 'danger'), 40%),
+);
+// Image gallery photos
+// Space between 2 photos
+$image-gallery-photos-margin: 2px;
+
+// Main content
+$main-content: (
+ 'max-width': 750px,
+ 'padding-right-left': 20px,
+);
+
+// Mardown
+// These variables are use to have headings smaller than general headings title
+// and use correctly headings in a post instead of use only header below h2
+// because they are larger than the post title or something like that
+// font-size : (X.Xrem = XXpx, 1.0rem = 10px)
+$markdown-headings-font-size: (
+ 'h1': 3rem,
+ 'h2': 2.7rem,
+ 'h3': 2.4rem,
+ 'h4': 2.1rem,
+ 'h5': 1.9rem,
+ 'h6': 1.7rem
+);
+// Reduction of markdwon headings on small screen and down
+$markdown-headings-font-size-sm-screen-reduction-factor: 0.35rem;
+// Reduction of markdwon headings on medium screen only
+$markdown-headings-font-size-md-screen-reduction-factor: 0.2rem;
+
+// Pagination
+$pagination-height: 60px;
+
+// Post thumbnail image
+// Width and height of post's thumbnail image
+$post-thumbnail-image-width: 140px;
+
+// Tooltip
+$tooltip: (
+ 'min-width': 180px,
+ 'background': rgba(0, 0, 20, 0.93),
+ // Don't change this value, used to horizontally center the tooltip content
+ 'arrow-width': 15px,
+ // Don't change this value, used to vertically center the tooltip content
+ 'arrow-height': 12px
+);
diff --git a/src/scss/utils/mixins/_bottom-bar.scss b/src/scss/utils/mixins/_bottom-bar.scss
new file mode 100755
index 0000000..32f7131
--- /dev/null
+++ b/src/scss/utils/mixins/_bottom-bar.scss
@@ -0,0 +1,46 @@
+/// Mixin helper to stylized bottom bar in small size
+/// minus width of sidebar on extra large screen and minus its padding
+@mixin bottom-bar-xs {
+ width: calc(100% - #{map-get($sidebar, xlg-screen-width)} - 15px * 2);
+ left: map-get($sidebar, xlg-screen-width);
+}
+
+/// Mixin helper to stylized bottom bar in small size
+/// minus width of sidebar on large screen and minus its padding
+@mixin bottom-bar-sm {
+ width: calc(100% - #{map-get($sidebar, lg-screen-width)} - 15px * 2);
+ left: map-get($sidebar, lg-screen-width);
+}
+
+/// Mixin helper to stylized bottom bar in medium size
+/// minus width of sidebar on medium screen and minus its padding
+@mixin bottom-bar-md {
+ width: calc(100% - #{map-get($sidebar, md-screen-width)} - 15px * 2);
+ left: map-get($sidebar, md-screen-width);
+}
+
+/// Mixin helper to stylized bottom bar in large size minus its padding
+@mixin bottom-bar-lg {
+ width: calc(100% - 15px * 2);
+ left: 0;
+}
+
+/// Mixin helper to pushed bottom bar from medium sidebar size
+@mixin bottom-bar-pushed-md {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, md-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
+
+/// Mixin helper to pushed bottom bar from large sidebar size
+@mixin bottom-bar-pushed-lg {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, lg-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
+/// Mixin helper to pushed bottom bar from extra large sidebar size
+@mixin bottom-bar-pushed-xlg {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, xlg-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+} \ No newline at end of file
diff --git a/src/scss/utils/mixins/_button.scss b/src/scss/utils/mixins/_button.scss
new file mode 100755
index 0000000..a8cd488
--- /dev/null
+++ b/src/scss/utils/mixins/_button.scss
@@ -0,0 +1,19 @@
+/// Helper for 'components/button' to stylize a button with a specified color
+/// @param {Color} $color - Color CSS value
+@mixin button-color-variant($color) {
+ color: $color !important;
+ border: 1px solid $color;
+
+ &:hover {
+ color: darken($color, 15) !important;
+ border: 1px solid darken($color, 15);
+ }
+}
+
+/// Helper for 'components/button' to stylize a button with a specified size and padding
+/// @param {Number} $font-size - Font size CSS value
+/// @param {List} $padding - Padding CSS value
+@mixin button-size-variant($font-size, $padding) {
+ font-size: $font-size;
+ padding: $padding;
+} \ No newline at end of file
diff --git a/src/scss/utils/mixins/_category.scss b/src/scss/utils/mixins/_category.scss
new file mode 100755
index 0000000..79ef92e
--- /dev/null
+++ b/src/scss/utils/mixins/_category.scss
@@ -0,0 +1,20 @@
+/// Helper for 'components/category' to stylize a category with a specified color
+/// @param {Color} $color - Color CSS value
+@mixin category-color-variant($color) {
+ color: $color !important;
+ border: 1px solid $color;
+
+ &:hover {
+ color: darken($color, 15) !important;
+ border: 1px solid darken($color, 15);
+ text-decoration: none;
+ }
+}
+
+/// Helper for 'components/category' to stylize a category with a specified size and padding
+/// @param {Number} $font-size - Font-size CSS value
+/// @param {List} $padding - Padding CSS value
+@mixin category-size-variant($font-size, $padding) {
+ font-size: $font-size;
+ padding: $padding;
+} \ No newline at end of file
diff --git a/src/scss/utils/mixins/_form.scss b/src/scss/utils/mixins/_form.scss
new file mode 100755
index 0000000..a24398f
--- /dev/null
+++ b/src/scss/utils/mixins/_form.scss
@@ -0,0 +1,13 @@
+/// Helper to stylize a input with a specified size
+/// @param {Number} $height - Height CSS value
+/// @param {String} $padding - Padding CSS value
+/// @param {String} $font-size - Font-size CSS value
+/// @param {String} $line-height - Line-height CSS value
+@mixin input-size-variant($height, $padding, $font-size, $line-height) {
+ & {
+ height: $height;
+ padding: $padding;
+ font-size: $font-size;
+ line-height: $line-height;
+ }
+} \ No newline at end of file
diff --git a/src/scss/utils/mixins/_header.scss b/src/scss/utils/mixins/_header.scss
new file mode 100755
index 0000000..028275c
--- /dev/null
+++ b/src/scss/utils/mixins/_header.scss
@@ -0,0 +1,19 @@
+/// Mixin helper to push header from medium sidebar size
+@mixin header-pushed-md {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, md-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
+
+/// Mixin helper to push header from large sidebar size
+@mixin header-pushed-lg {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, lg-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
+/// Mixin helper to push header from extra large sidebar size
+@mixin header-pushed-xlg {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, xlg-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+} \ No newline at end of file
diff --git a/src/scss/utils/mixins/_main.scss b/src/scss/utils/mixins/_main.scss
new file mode 100755
index 0000000..a74364c
--- /dev/null
+++ b/src/scss/utils/mixins/_main.scss
@@ -0,0 +1,48 @@
+/// Mixin helper to stylized `main` div in extra small size
+@mixin main-xs {
+ padding-top: map-get($main, padding-top);
+ float: right;
+ width: calc(100% - #{map-get($sidebar, xlg-screen-width)});
+}
+
+/// Mixin helper to stylized `main` div in small size
+@mixin main-sm {
+ padding-top: map-get($main, padding-top);
+ float: right;
+ width: calc(100% - #{map-get($sidebar, lg-screen-width)});
+}
+
+/// Mixin helper to stylized `main` div in medium size
+@mixin main-md {
+ padding-top: map-get($main, padding-top);
+ float: right;
+ width: calc(100% - #{map-get($sidebar, md-screen-width)});
+}
+
+/// Mixin helper to stylized `main` div in large size
+@mixin main-lg {
+ padding-top: map-get($header, height) + map-get($main, padding-top);
+ display: block;
+ width: 100%;
+}
+
+/// Mixin helper to push `main` div from medium sidebar size
+@mixin main-pushed-md {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, md-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
+
+/// Mixin helper to push `main` div from large sidebar size
+@mixin main-pushed-lg {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, lg-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
+
+/// Mixin helper to push `main` div from extra large sidebar size
+@mixin main-pushed-xlg {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, xlg-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
diff --git a/src/scss/utils/mixins/_opacity.scss b/src/scss/utils/mixins/_opacity.scss
new file mode 100755
index 0000000..8788358
--- /dev/null
+++ b/src/scss/utils/mixins/_opacity.scss
@@ -0,0 +1,7 @@
+/// Mixin helper to add opacity rules
+/// @param {number} $opacity - Opacity CSS value
+@mixin opacity($opacity) {
+ opacity: $opacity;
+ $opacity-ie: $opacity * 100;
+ filter: alpha(opacity=$opacity-ie); // IE8
+} \ No newline at end of file
diff --git a/src/scss/utils/mixins/_post-header-cover.scss b/src/scss/utils/mixins/_post-header-cover.scss
new file mode 100755
index 0000000..fd805f9
--- /dev/null
+++ b/src/scss/utils/mixins/_post-header-cover.scss
@@ -0,0 +1,47 @@
+/// Mixin helper to stylized post header cover in extra small size
+/// minus width of sidebar on extra large screen
+@mixin post-header-cover-xs {
+ width: calc(100% - #{map-get($sidebar, xlg-screen-width)});
+ left: map-get($sidebar, xlg-screen-width);
+}
+
+/// Mixin helper to stylized post header cover in small size
+/// minus width of sidebar on large screen
+@mixin post-header-cover-sm {
+ width: calc(100% - #{map-get($sidebar, lg-screen-width)});
+ left: map-get($sidebar, lg-screen-width);
+}
+
+/// Mixin helper to stylized post header cover in medium size
+/// minus width of sidebar on medium screen
+@mixin post-header-cover-md {
+ width: calc(100% - #{map-get($sidebar, md-screen-width)});
+ left: map-get($sidebar, md-screen-width);
+}
+
+/// Mixin helper to stylized post header cover in large size
+@mixin post-header-cover-lg {
+ width: 100%;
+ left: 0;
+}
+
+/// Mixin helper to pushed post header cover from medium sidebar size
+@mixin post-header-cover-pushed-md {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, md-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
+
+/// Mixin helper to pushed post header cover from large sidebar size
+@mixin post-header-cover-pushed-lg {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, lg-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
+
+/// Mixin helper to pushed post header cover from extra large sidebar size
+@mixin post-header-cover-pushed-xlg {
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, xlg-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+} \ No newline at end of file
diff --git a/src/scss/utils/mixins/_prefix.scss b/src/scss/utils/mixins/_prefix.scss
new file mode 100755
index 0000000..74d6f13
--- /dev/null
+++ b/src/scss/utils/mixins/_prefix.scss
@@ -0,0 +1,11 @@
+/// Mixin helper to output vendor prefixes
+/// @param {String} $property - Unprefixed CSS property
+/// @param {*} $value - Raw CSS value
+/// @param {List} $prefixes - List of prefixes to output
+@mixin prefix($property, $value, $prefixes: ()) {
+ @each $prefix in $prefixes {
+ -#{$prefix}-#{$property}: #{$value};
+ }
+
+ #{$property}: #{$value};
+} \ No newline at end of file
diff --git a/src/scss/utils/mixins/_share-options-bar.scss b/src/scss/utils/mixins/_share-options-bar.scss
new file mode 100755
index 0000000..6450ca6
--- /dev/null
+++ b/src/scss/utils/mixins/_share-options-bar.scss
@@ -0,0 +1,20 @@
+/// Mixin helper to stylized `share-options-bar` div in extra small size
+@mixin share-options-bar-xs {
+ width: calc(100% - #{map-get($sidebar, xlg-screen-width)});
+ left: map-get($sidebar, xlg-screen-width);
+}
+/// Mixin helper to stylized `share-options-bar` div in small size
+@mixin share-options-bar-sm {
+ width: calc(100% - #{map-get($sidebar, lg-screen-width)});
+ left: map-get($sidebar, lg-screen-width);
+}
+/// Mixin helper to stylized `share-options-bar` div in medium size
+@mixin share-options-bar-md {
+ width: calc(100% - #{map-get($sidebar, md-screen-width)});
+ left: map-get($sidebar, md-screen-width);
+
+}
+/// Mixin helper to stylized `share-options-bar` div in large size
+@mixin share-options-bar-lg {
+ width: 100%;
+}
diff --git a/src/scss/utils/mixins/_sidebar.scss b/src/scss/utils/mixins/_sidebar.scss
new file mode 100755
index 0000000..f1ff827
--- /dev/null
+++ b/src/scss/utils/mixins/_sidebar.scss
@@ -0,0 +1,197 @@
+/// Mixin helper to display the sidebar in medium size
+@mixin sidebar-md {
+ width: map-get($sidebar, md-screen-width);
+
+ // Author information
+ .sidebar-profile {
+ .sidebar-profile-picture {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+ vertical-align: middle;
+ border-radius: 30px;
+ }
+ .sidebar-profile-name {
+ display: none;
+ }
+ }
+ // Buttons
+ ul.sidebar-buttons {
+ li.sidebar-button {
+ text-align: center;
+
+ .sidebar-button-link {
+ text-align: center;
+ width: 100%;
+
+ .sidebar-button-icon {
+ font-size: 2rem;
+ display: inline-block;
+ text-align: center;
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+ padding-top: 0;
+ vertical-align: middle;
+ }
+ .sidebar-button-desc {
+ display: none;
+ }
+ }
+ }
+ }
+ // Used to animate the sidebar (pushed effect)
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, md-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
+
+/// Mixin helper to display the sidebar in large size
+@mixin sidebar-lg {
+ width: map-get($sidebar, lg-screen-width);
+
+ // Author information
+ .sidebar-profile {
+ height: 130px;
+ padding-top: 40px;
+ padding-bottom: 7.5px;
+
+ .sidebar-profile-picture {
+ width: 90px;
+ height: 90px;
+ border-radius: 90px;
+ margin-bottom: 5px;
+ }
+ .sidebar-profile-name {
+ font-size: 1.6rem;
+ }
+ }
+ // Buttons
+ ul.sidebar-buttons {
+ li.sidebar-button {
+ text-align: left;
+
+ .sidebar-button-link {
+ text-align: left;
+ width: auto;
+ padding-left: 23px;
+ padding-top: 0;
+
+ // Font-awesome icon
+ .sidebar-button-icon {
+ font-size: 2rem;
+ display: inline-block;
+ text-align: center;
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+ padding-top: 0;
+ vertical-align: middle;
+ margin-right: 15px;
+ }
+ // Description (name) of a link
+ .sidebar-button-desc {
+ display: inline-block;
+ width: auto;
+ height: 35px;
+ line-height: 35px;
+ font-size: 1.5rem;
+ letter-spacing: 0.3px;
+ vertical-align: middle;
+ }
+ }
+ }
+ }
+ // Used to animate the sidebar (pushed effect)
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, lg-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
+
+/// Mixin helper to display the sidebar in large size
+@mixin sidebar-xlg {
+ width: map-get($sidebar, xlg-screen-width);
+ box-sizing: border-box;
+ padding: 0 80px;
+ .sidebar-container {
+ position: relative;
+ top: 50%;
+ transform: translateY(-50%);
+ -webkit-transform: translateY(-50%);
+ -moz-transform: translateY(-50%);
+ }
+ // Author information
+ .sidebar-profile {
+ padding-top: 0;
+ padding-bottom: 7.5px;
+
+ .sidebar-profile-picture {
+ width: 90px;
+ height: 90px;
+ border-radius: 90px;
+ margin-bottom: 5px;
+ }
+ .sidebar-profile-bio,
+ .sidebar-profile-job,
+ .sidebar-profile-location {
+ font-weight: 400;
+ font-size: 1.6rem;
+ color: map-get($sidebar, color);
+ }
+ .sidebar-profile-job,
+ .sidebar-profile-location {
+ margin-top: 0;
+ width: 49%;
+ display: inline-block;
+ }
+ }
+ // Buttons
+ ul.sidebar-buttons {
+ width: 49%;
+ vertical-align: top;
+ display: inline-block;
+
+ li.sidebar-button {
+ text-align: left;
+ box-sizing: border-box;
+ .sidebar-button-link {
+ text-align: left;
+ width: auto;
+ padding-top: 0;
+ white-space: nowrap;
+ // Font-awesome icon
+ .sidebar-button-icon {
+ font-size: 2rem;
+ float: left;
+ text-align: center;
+ width: 30px;
+ height: 35px;
+ line-height: 35px;
+ padding-top: 0;
+ vertical-align: middle;
+ margin-right: 15px;
+ }
+ // Description (name) of a link
+ .sidebar-button-desc {
+ display: block;
+ width: auto;
+ height: 35px;
+ line-height: 35px;
+ font-size: 1.5rem;
+ letter-spacing: 0.3px;
+ vertical-align: middle;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+ }
+ &:nth-child(odd) {
+ padding-right: 20px;
+ }
+ }
+ }
+ // Used to animate the sidebar (pushed effect)
+ &.pushed {
+ @include prefix(transform, translate3d(#{map-get($sidebar, xlg-screen-width)}, 0, 0), 'webkit' 'moz');
+ }
+}
diff --git a/src/scss/utils/mixins/_tag.scss b/src/scss/utils/mixins/_tag.scss
new file mode 100755
index 0000000..b5b63b9
--- /dev/null
+++ b/src/scss/utils/mixins/_tag.scss
@@ -0,0 +1,20 @@
+/// Helper for 'components/tag' to stylize a tag with a specified color
+/// @param {Color} $color - Color CSS value
+@mixin tag-color-variant($color) {
+ color: $color !important;
+ border: 1px solid $color;
+
+ &:hover {
+ color: darken($color, 15) !important;
+ border: 1px solid darken($color, 15);
+ text-decoration: none;
+ }
+}
+
+/// Helper for 'components/tag' to stylize a tag with a specified size and padding
+/// @param {String} $font-size - Font-size CSS value
+/// @param {List} $padding - List of padding CSS value
+@mixin tag-size-variant($font-size, $padding) {
+ font-size: $font-size;
+ padding: $padding;
+} \ No newline at end of file