├── .dependabot
└── config.yml
├── .gitattributes
├── .github
└── FUNDING.yml
├── .gitignore
├── LICENSE
├── README.md
├── account.hbs
├── amp.hbs
├── assets
├── css
│ ├── bootstrap.min.css
│ ├── bootstrap.min.css.map
│ └── hl-styles
│ │ └── atom-one-dark.min.css
├── dist
│ └── sw-toolbox.js
├── images
│ ├── apple-icon.png
│ ├── apple-touch-icon-120x120.png
│ ├── apple-touch-icon-120x120_.png
│ ├── apple-touch-icon-152x152.png
│ ├── apple-touch-icon-152x152_.png
│ ├── apple-touch-icon-512x512.png
│ ├── apple-touch-icon-76x76.png
│ ├── apple-touch-icon-76x76_.png
│ ├── apple-touch-icon.png
│ ├── apple-touch-icon_.png
│ ├── favicon.png
│ ├── favicon_.png
│ ├── logo-alternate.svg
│ ├── logo-alternate_.svg
│ ├── logo.png
│ ├── qr-alipay-255.png
│ └── qr-wechat-255.png
├── js
│ ├── app.bundle.min.js
│ ├── index.js
│ └── vendor
│ │ ├── clipboard.min.js
│ │ ├── fuse.min.js
│ │ ├── jquery-3.5.1.min.js
│ │ ├── jquery.disqusloader.js
│ │ ├── jquery.fitvids.js
│ │ ├── jquery.toc.js
│ │ ├── lazy.js
│ │ ├── medium-zoom.min.js
│ │ └── prism.js
└── scss
│ ├── ampstyle-dark.scss
│ ├── ampstyle-light.scss
│ ├── components
│ ├── _archive.scss
│ ├── _color-and-font.scss
│ ├── _common.scss
│ ├── _cover.scss
│ ├── _error.scss
│ ├── _footer.scss
│ ├── _header.scss
│ ├── _hero-area.scss
│ ├── _members.scss
│ ├── _post-list.scss
│ ├── _prism.scss
│ ├── _search-popup.scss
│ └── _single-article.scss
│ └── screen.scss
├── author.hbs
├── custom-author-archive.hbs
├── custom-tag-archive.hbs
├── default.hbs
├── error-404.hbs
├── error.hbs
├── example
├── Gruntfile.js
├── README.md
├── checkwave
│ ├── checkwave.png
│ ├── index.html
│ └── style.css
├── cloudy-spiral
│ ├── index.html
│ ├── style.css
│ └── style.scss
├── device-loop
│ ├── device-loop.png
│ ├── index.html
│ ├── style.css
│ └── style.scss
├── flexing-pagination
│ ├── flexing-pagination.png
│ ├── index.html
│ ├── style.css
│ └── style.scss
├── flipside
│ ├── index.html
│ ├── script.js
│ ├── style.css
│ └── style.scss
├── monocle
│ ├── index.html
│ ├── script.js
│ ├── style.css
│ └── style.scss
├── package-lock.json
├── package.json
└── progress-nav
│ ├── index.html
│ ├── normalize.css
│ ├── script.js
│ ├── style.css
│ └── style.scss
├── gulpfile.js
├── index.hbs
├── locales
└── en.json
├── logo.png
├── manifest.json
├── package-lock.json
├── package.json
├── page.hbs
├── partials
├── about-author.hbs
├── api-key.hbs
├── disqus-comment.hbs
├── footer-simple.hbs
├── footer.hbs
├── header.hbs
├── hero-section.hbs
├── icons
│ ├── arrow-down.hbs
│ ├── arrow-left.hbs
│ ├── arrow-right.hbs
│ ├── arrow-up.hbs
│ ├── behance.hbs
│ ├── check-mark.hbs
│ ├── close.hbs
│ ├── dribbble.hbs
│ ├── facebook.hbs
│ ├── github.hbs
│ ├── image.hbs
│ ├── instagram.hbs
│ ├── link.hbs
│ ├── linkedin.hbs
│ ├── location.hbs
│ ├── medium.hbs
│ ├── menu.hbs
│ ├── pinterest.hbs
│ ├── search.hbs
│ ├── star.hbs
│ ├── twitter.hbs
│ ├── user.hbs
│ └── youtube.hbs
├── loop.hbs
├── members
│ ├── notifications.hbs
│ ├── pricing-table-free.hbs
│ ├── pricing-table-monthly.hbs
│ └── pricing-table-yearly.hbs
├── navigation.hbs
├── pagination.hbs
├── prev-next.hbs
├── search-popup.hbs
├── share.hbs
├── social-links.hbs
├── styles
│ ├── ampstyle-dark.hbs
│ ├── ampstyle-light.hbs
│ └── bundle-css.hbs
├── subscription.hbs
└── widgets
│ ├── footer-about.hbs
│ ├── footer-newsletter.hbs
│ ├── footer-recent-posts.hbs
│ ├── footer-tags.hbs
│ ├── sidebar-featured-posts.hbs
│ ├── sidebar-recent-posts.hbs
│ └── tags-clouds.hbs
├── post.hbs
├── routes.yaml
├── serviceworker-v1.js
├── signin.hbs
├── signup-free.hbs
├── signup.hbs
└── tag.hbs
/.dependabot/config.yml:
--------------------------------------------------------------------------------
1 | version: 1
2 | update_configs:
3 | # Keep package.json (& lockfiles) secure and up-to-date,
4 | # batching pull requests daily
5 | - package_manager: "javascript"
6 | directory: "/"
7 | update_schedule: "daily"
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.hbs linguist-language=css
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [halfrost]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated Stuff
2 | .sass-cache
3 | .sass-cache/*
4 | css/*.map
5 |
6 | # bundling output
7 | build/*
8 | build
9 | dist/*
10 | dist
11 |
12 | # Node Modules (use `npm install` to generate these)
13 | node_modules/*
14 | node_modules
15 | ../*
16 |
17 | # OS X Junk
18 | .DS_Store
19 | .DS_Store/*
20 |
21 |
22 | # Not-Needed System Files
23 | *.swp
24 | *.bak
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 halfrost
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/account.hbs:
--------------------------------------------------------------------------------
1 | {{!< default}}
2 | {{! The tag above means - insert everything in this file into the {body} of the default.hbs template }}
3 |
4 |
5 |
6 |
7 |
8 |
9 | {{#if @member.paid}}
10 |
15 |
16 |
17 | {{t "Hey! You are currently logged in with"}} {{@member.email}} . {{t "You have an active"}} {{@site.title}} {{t "account with access to all areas."}} {{t "You're all set, but if you need any help, get in touch with us and we'd be happy to help."}}
18 |
19 |
22 |
23 | {{else if @member}}
24 |
29 |
30 |
31 | {{t "Hey! You are currently logged in with"}} {{@member.email}} . {{t "You have subscribed to free updates from"}} {{@site.title}}. {{t "Subscribe to paid plan to unlock full access."}}
32 |
33 |
34 | {{> members/pricing-table-monthly}}
35 | {{> members/pricing-table-yearly}}
36 |
37 |
38 | {{else}}
39 | {{!-- Not logged in: Redirect to signin --}}
40 |
41 | {{/if}}
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/assets/css/hl-styles/atom-one-dark.min.css:
--------------------------------------------------------------------------------
1 | .hljs{display:block;overflow-x:auto;padding:.5em;color:#abb2bf;background:#282c34}.hljs-comment,.hljs-quote{color:#5c6370;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#c678dd}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-addition,.hljs-attribute,.hljs-meta-string,.hljs-regexp,.hljs-string{color:#98c379}.hljs-built_in,.hljs-class .hljs-title{color:#e6c07b}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#d19a66}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#61aeee}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}
--------------------------------------------------------------------------------
/assets/images/apple-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/apple-icon.png
--------------------------------------------------------------------------------
/assets/images/apple-touch-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/apple-touch-icon-120x120.png
--------------------------------------------------------------------------------
/assets/images/apple-touch-icon-120x120_.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/apple-touch-icon-120x120_.png
--------------------------------------------------------------------------------
/assets/images/apple-touch-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/apple-touch-icon-152x152.png
--------------------------------------------------------------------------------
/assets/images/apple-touch-icon-152x152_.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/apple-touch-icon-152x152_.png
--------------------------------------------------------------------------------
/assets/images/apple-touch-icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/apple-touch-icon-512x512.png
--------------------------------------------------------------------------------
/assets/images/apple-touch-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/apple-touch-icon-76x76.png
--------------------------------------------------------------------------------
/assets/images/apple-touch-icon-76x76_.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/apple-touch-icon-76x76_.png
--------------------------------------------------------------------------------
/assets/images/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/apple-touch-icon.png
--------------------------------------------------------------------------------
/assets/images/apple-touch-icon_.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/apple-touch-icon_.png
--------------------------------------------------------------------------------
/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/favicon.png
--------------------------------------------------------------------------------
/assets/images/favicon_.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/favicon_.png
--------------------------------------------------------------------------------
/assets/images/logo-alternate_.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
85 |
86 |
--------------------------------------------------------------------------------
/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/logo.png
--------------------------------------------------------------------------------
/assets/images/qr-alipay-255.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/qr-alipay-255.png
--------------------------------------------------------------------------------
/assets/images/qr-wechat-255.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/assets/images/qr-wechat-255.png
--------------------------------------------------------------------------------
/assets/js/vendor/jquery.disqusloader.js:
--------------------------------------------------------------------------------
1 | /*
2 | disqusLoader.js v1.0
3 | A JavaScript plugin for lazy-loading Disqus comments widget.
4 | -
5 | By Osvaldas Valutis, www.osvaldas.info
6 | Available for use under the MIT License
7 | */
8 |
9 | ;( function( $, window, document, undefined )
10 | {
11 | 'use strict';
12 |
13 | var $win = $( window ),
14 | throttle = function(a,b){var c,d;return function(){var e=this,f=arguments,g=+new Date;c&&g $win.height() * laziness || winST - $instance.offset().top - $instance.outerHeight() - ( $win.height() * laziness ) > 0 )
33 | return true;
34 |
35 | $( '#disqus_thread' ).removeAttr( 'id' );
36 | $instance.attr( 'id', 'disqus_thread' ).data( 'disqusLoaderStatus', 'loaded' );
37 |
38 | if( scriptStatus == 'loaded' )
39 | {
40 | DISQUS.reset({ reload: true, config: disqusConfig });
41 | }
42 | else // unloaded | loading
43 | {
44 | window.disqus_config = disqusConfig;
45 | if( scriptStatus == 'unloaded' )
46 | {
47 | scriptStatus = 'loading';
48 | $.ajax(
49 | {
50 | url: scriptUrl,
51 | async: true,
52 | cache: true,
53 | dataType: 'script',
54 | success: function()
55 | {
56 | scriptStatus = 'loaded';
57 | }
58 | });
59 | }
60 | }
61 | };
62 |
63 | $win.on( 'scroll resize', throttle( throttleTO, init ));
64 |
65 | $.disqusLoader = function( element, options )
66 | {
67 | options = $.extend({},
68 | {
69 | laziness: 1,
70 | throttle: 250,
71 | scriptUrl: false,
72 | disqusConfig: false,
73 |
74 | }, options );
75 |
76 | laziness = options.laziness + 1;
77 | throttleTO = options.throttle;
78 | disqusConfig = options.disqusConfig;
79 | scriptUrl = scriptUrl === false ? options.scriptUrl : scriptUrl; // set it only once
80 | $instance = ( typeof element == 'string' ? $( element ) : element ).eq( 0 );
81 |
82 | $instance.data( 'disqusLoaderStatus', 'unloaded' );
83 |
84 | init();
85 | };
86 |
87 | })( jQuery, window, document );
88 |
--------------------------------------------------------------------------------
/assets/js/vendor/jquery.fitvids.js:
--------------------------------------------------------------------------------
1 | /*jshint browser:true */
2 | /*!
3 | * FitVids 1.1
4 | *
5 | * Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com
6 | * Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/
7 | * Released under the WTFPL license - http://sam.zoy.org/wtfpl/
8 | *
9 | */
10 |
11 | ;(function( $ ){
12 |
13 | 'use strict';
14 |
15 | $.fn.fitVids = function( options ) {
16 | var settings = {
17 | customSelector: null,
18 | ignore: null
19 | };
20 |
21 | if(!document.getElementById('fit-vids-style')) {
22 | // appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js
23 | var head = document.head || document.getElementsByTagName('head')[0];
24 | var css = '.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}';
25 | var div = document.createElement("div");
26 | div.innerHTML = 'x
';
27 | head.appendChild(div.childNodes[1]);
28 | }
29 |
30 | if ( options ) {
31 | $.extend( settings, options );
32 | }
33 |
34 | return this.each(function(){
35 | var selectors = [
36 | 'iframe[src*="player.vimeo.com"]',
37 | 'iframe[src*="youtube.com"]',
38 | 'iframe[src*="youtube-nocookie.com"]',
39 | 'iframe[src*="kickstarter.com"][src*="video.html"]',
40 | 'object',
41 | 'embed'
42 | ];
43 |
44 | if (settings.customSelector) {
45 | selectors.push(settings.customSelector);
46 | }
47 |
48 | var ignoreList = '.fitvidsignore';
49 |
50 | if(settings.ignore) {
51 | ignoreList = ignoreList + ', ' + settings.ignore;
52 | }
53 |
54 | var $allVideos = $(this).find(selectors.join(','));
55 | $allVideos = $allVideos.not('object object'); // SwfObj conflict patch
56 | $allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video.
57 |
58 | $allVideos.each(function(){
59 | var $this = $(this);
60 | if($this.parents(ignoreList).length > 0) {
61 | return; // Disable FitVids on this video.
62 | }
63 | if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }
64 | if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width'))))
65 | {
66 | $this.attr('height', 9);
67 | $this.attr('width', 16);
68 | }
69 | var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),
70 | width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),
71 | aspectRatio = height / width;
72 | if(!$this.attr('name')){
73 | var videoName = 'fitvid' + $.fn.fitVids._count;
74 | $this.attr('name', videoName);
75 | $.fn.fitVids._count++;
76 | }
77 | $this.wrap('
').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+'%');
78 | $this.removeAttr('height').removeAttr('width');
79 | });
80 | });
81 | };
82 |
83 | // Internal counter for unique video names.
84 | $.fn.fitVids._count = 0;
85 |
86 | // Works with either jQuery or Zepto
87 | })( window.jQuery || window.Zepto );
88 |
--------------------------------------------------------------------------------
/assets/js/vendor/jquery.toc.js:
--------------------------------------------------------------------------------
1 | (function (factory) {
2 | if (typeof define === 'function' && define.amd) {
3 | // AMD. Register as an anonymous module.
4 | define(['jquery'], factory);
5 | } else {
6 | // Browser globals
7 | factory(jQuery);
8 | }
9 | }(function ($) {
10 | 'use strict';
11 |
12 | /**
13 | * get header level
14 | * @param {String} header: header's tag name
15 | *
16 | * @return {Number}
17 | */
18 | var getLevel = function (header) {
19 | if (typeof header !== 'string') {
20 | return 0;
21 | }
22 |
23 | var decs = header.match(/\d/g);
24 | return decs ? Math.min.apply(null, decs) : 1;
25 | };
26 |
27 | /**
28 | * create ordered list
29 | * @param {jQuert} $wrapper
30 | * @param {Number} count
31 | *
32 | * @return {jQuery} list
33 | */
34 | var createList = function ($wrapper, count) {
35 | while (count--) {
36 | $wrapper = $('').appendTo($wrapper);
37 |
38 | if (count) {
39 | $wrapper = $(' ').appendTo($wrapper);
40 | }
41 | }
42 |
43 | return $wrapper;
44 | };
45 |
46 | /**
47 | * insert position jump back
48 | * @param {jQuery} $currentWrapper: current insert point
49 | * @param {Number} offset: distance between current's and target's depth
50 | *
51 | * @return {jQuery} insert point
52 | */
53 | var jumpBack = function ($currentWrapper, offset) {
54 | while (offset--) {
55 | $currentWrapper = $currentWrapper.parent();
56 | }
57 |
58 | return $currentWrapper;
59 | };
60 |
61 | /**
62 | * set element href/id and content
63 | * @param {Boolean} overwrite: whether overwrite source element existed id
64 | * @param {String} prefix: prefix to prepend to href/id
65 | *
66 | * @return {Function}
67 | */
68 | var setAttrs = function (overwrite, prefix) {
69 | return function ($src, $target, index) {
70 | var content = $src.text();
71 | var pre = prefix + '-' + index;
72 | $target.text(content);
73 |
74 | var src = $src[0];
75 | var target = $target[0];
76 | var id = overwrite ? pre : (src.id || pre);
77 |
78 | id = encodeURIComponent(id);
79 |
80 | src.id = id;
81 | target.href = '#' + id;
82 | };
83 | };
84 |
85 | /**
86 | * build table of contents
87 | * @param {Object} options
88 | *
89 | * @return {jQuery} list
90 | */
91 | var buildTOC = function (options) {
92 | var selector = options.selector;
93 | var scope = options.scope;
94 |
95 | var $ret = $('');
96 | var $wrapper = $ret;
97 | var $lastLi = null;
98 |
99 | var prevDepth = getLevel(selector);
100 | var _setAttrs = setAttrs(options.overwrite, options.prefix);
101 |
102 | $(scope)
103 | .find(selector)
104 | .each(function (index, elem) {
105 | var currentDepth = getLevel(elem.tagName);
106 | var offset = currentDepth - prevDepth;
107 |
108 | if (offset > 0) {
109 | $wrapper = createList($lastLi, offset);
110 | }
111 |
112 | if (offset < 0) {
113 | // should be once more level to jump back
114 | // eg: h2 + h3 + h2, offset = h2 - h3 = -1
115 | //
116 | // ol <------+ target
117 | // li |
118 | // ol ---+ current
119 | // li
120 | //
121 | // jumpback = target - current = 2
122 | $wrapper = jumpBack($wrapper, -offset * 2);
123 | }
124 |
125 | if (!$wrapper.length) {
126 | $wrapper = $ret;
127 | }
128 |
129 | var $li = $(' ');
130 | var $a = $(' ');
131 |
132 | _setAttrs($(elem), $a, index);
133 |
134 | $li.append($a).appendTo($wrapper);
135 |
136 | $lastLi = $li;
137 | prevDepth = currentDepth;
138 | });
139 |
140 | return $ret;
141 | };
142 |
143 | /**
144 | * init table of contents
145 | * @param {Object} [option]: TOC options, available props:
146 | * {String} [selector]: headers selector, default is 'h1, h2, h3, h4, h5, h6'
147 | * {String} [scope]: selector to specify elements search scope, default is 'body'
148 | * {Boolean} [overwrite]: whether to overwrite existed headers' id, default is false
149 | * {String} [prefix]: string to prepend to id/href prop, default is 'toc'
150 | *
151 | * @return {jQuery} $this
152 | */
153 | $.fn.initTOC = function (options) {
154 | var defaultOpts = {
155 | selector: 'h1, h2, h3, h4, h5, h6',
156 | scope: 'body',
157 | overwrite: false,
158 | prefix: 'toc'
159 | };
160 |
161 | options = $.extend(defaultOpts, options);
162 |
163 | var selector = options.selector;
164 |
165 | if (typeof selector !== 'string') {
166 | throw new TypeError('selector must be a string');
167 | }
168 |
169 | if (!selector.match(/^(?:h[1-6],?\s*)+$/g)) {
170 | throw new TypeError('selector must contains only h1-6');
171 | }
172 |
173 | $(this).append(buildTOC(options));
174 |
175 | var currentHash = location.hash;
176 |
177 | if (currentHash) {
178 | setTimeout(function () {
179 | var anchor = document.getElementById(currentHash.slice(1));
180 | if (anchor) anchor.scrollIntoView();
181 | }, 0);
182 | }
183 |
184 | return $(this);
185 | };
186 | }));
187 |
--------------------------------------------------------------------------------
/assets/scss/ampstyle-dark.scss:
--------------------------------------------------------------------------------
1 | /*=====================================================
2 | Style for AMP page - dark mode
3 | =====================================================*/
4 | @import "components/color-and-font";
5 | @import "components/common";
6 | * {
7 | box-sizing: border-box;
8 | }
9 | body {
10 | background-color: map-get($theme-dark, "bg-color");
11 | color: map-get($theme-dark, "text-body");
12 | }
13 | h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
14 | color: map-get($theme-dark, "text-title");
15 | }
16 | h1, .h1 {
17 | font-size: 2rem; //48
18 | }
19 | h2, .h2 {
20 | font-size: 1.75rem; //40
21 | }
22 | h3, .h3 {
23 | font-size: 1.5rem; //24
24 | }
25 | h4, .h4 {
26 | font-size: 1.25rem; //18
27 | }
28 | h5, .h5 {
29 | font-size: 1rem; //16
30 | }
31 | h6, .h6 {
32 | font-size: 0.875rem; //14
33 | }
34 | pre {
35 | overflow-x: scroll;
36 | padding: 16px;
37 | font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
38 | background-color: rgba(#000, 0.22);
39 | code {
40 | background: none;
41 | padding: 0;
42 | }
43 | }
44 | .site-header, .site-footer {
45 | background-color: rgba(#000, 0.22);
46 | margin: 0;
47 | }
48 | .blog-title, .copyright {
49 | max-width: 600px;
50 | margin: auto;
51 | text-align: center;
52 | }
53 | .blog-title {
54 | padding: 8px 0;
55 | a {
56 | color: map-get($theme-dark, "text-title");
57 | text-decoration: none;
58 | font-size: 1.5rem;
59 | }
60 | }
61 | .post-image {
62 | margin: 16px 0;
63 | }
64 | .content {
65 | max-width:600px;
66 | margin: auto;
67 | padding: 15px;
68 | }
69 | .post-header {
70 | text-align: center;
71 | .post-title {
72 | margin-top: 8px;
73 | }
74 | }
75 | blockquote {
76 | margin: 16px 0;
77 | }
78 | .copyright {
79 | padding: 16px 0;
80 | font-size: 0.875rem;
81 | color: map-get($theme-dark, "text-light");
82 | a {
83 | color: map-get($theme-dark, "text-light");
84 | text-decoration: none;
85 | &:hover {
86 | color: $accent-color;
87 | }
88 | }
89 | }
90 | @media (min-width:601px) {
91 | .content {
92 | border-left: 1px solid rgba(#000, 0.22);
93 | border-right: 1px solid rgba(#000, 0.22);
94 | }
95 | }
96 |
97 |
--------------------------------------------------------------------------------
/assets/scss/ampstyle-light.scss:
--------------------------------------------------------------------------------
1 | /*=====================================================
2 | Style for AMP page - light mode
3 | =====================================================*/
4 | @import "components/color-and-font";
5 | @import "components/common";
6 | * {
7 | box-sizing: border-box;
8 | }
9 | body {
10 | background-color: map-get($theme-light, "bg-color");
11 | color: map-get($theme-light, "text-body");
12 | }
13 | h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
14 | color: map-get($theme-light, "text-title");
15 | }
16 | h1, .h1 {
17 | font-size: 2rem; //48
18 | }
19 | h2, .h2 {
20 | font-size: 1.75rem; //40
21 | }
22 | h3, .h3 {
23 | font-size: 1.5rem; //24
24 | }
25 | h4, .h4 {
26 | font-size: 1.25rem; //18
27 | }
28 | h5, .h5 {
29 | font-size: 1rem; //16
30 | }
31 | h6, .h6 {
32 | font-size: 0.875rem; //14
33 | }
34 | pre {
35 | overflow-x: scroll;
36 | padding: 16px;
37 | font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
38 | background-color: rgba(#000, 0.05);
39 | code {
40 | background: none;
41 | padding: 0;
42 | }
43 | }
44 | .site-header, .site-footer {
45 | background-color: rgba(#000, 0.05);
46 | margin: 0;
47 | }
48 | .blog-title, .copyright {
49 | max-width: 600px;
50 | margin: auto;
51 | text-align: center;
52 | }
53 | .blog-title {
54 | padding: 8px 0;
55 | a {
56 | color: map-get($theme-light, "text-title");
57 | text-decoration: none;
58 | font-size: 1.5rem;
59 | }
60 | }
61 | .post-image {
62 | margin: 16px 0;
63 | }
64 | .content {
65 | max-width:600px;
66 | margin: auto;
67 | padding: 15px;
68 | }
69 | .post-header {
70 | text-align: center;
71 | .post-title {
72 | margin-top: 8px;
73 | }
74 | }
75 | blockquote {
76 | margin: 16px 0;
77 | }
78 | .copyright {
79 | padding: 16px 0;
80 | font-size: 0.875rem;
81 | color: map-get($theme-light, "text-light");
82 | a {
83 | color: map-get($theme-light, "text-light");
84 | text-decoration: none;
85 | &:hover {
86 | color: $accent-color;
87 | }
88 | }
89 | }
90 | @media (min-width:601px) {
91 | .content {
92 | border-left: 1px solid rgba(#000, 0.05);
93 | border-right: 1px solid rgba(#000, 0.05);
94 | }
95 | }
96 |
97 |
--------------------------------------------------------------------------------
/assets/scss/components/_archive.scss:
--------------------------------------------------------------------------------
1 | .card-wrap {
2 | margin-bottom: 30px;
3 | }
4 | .card-single {
5 | padding: 32px 24px;
6 | position: relative;
7 | min-height: 200px;
8 | &:before {
9 | content: "";
10 | position: absolute;
11 | top: 0;
12 | left: 0;
13 | height: 100%;
14 | width: 100%;
15 | background-color: rgba(#000, 0.22);
16 | }
17 | .inner-content {
18 | position: relative;
19 | .avatar {
20 | width: 96px;
21 | height: 96px;
22 | margin-bottom: 16px;
23 | }
24 | .tag-name, .author-name a {
25 | position: relative;
26 | &::before {
27 | content: "";
28 | position: absolute;
29 | bottom: -8px;
30 | left: 0;
31 | width: 0;
32 | height: 2px;
33 | background: $accent-color;
34 | transition: width 0.3s;
35 | }
36 | }
37 | .author-name {
38 | margin-bottom: 16px;
39 | a {
40 | color: var(--text-title);
41 | &:hover {
42 | color: var(--text-title);
43 | &:before {
44 | width: 100%;
45 | }
46 | }
47 | }
48 | }
49 | .post-count {
50 | margin-top: 16px;
51 | font-size: 0.875rem;
52 | letter-spacing: 1px;
53 | text-transform: uppercase;
54 | color: var(--text-title);
55 | }
56 | .bio {
57 | margin-top: 16px;
58 | }
59 | .meta-info {
60 | padding: 0;
61 | margin-top: 24px;
62 | color: var(--text-body);
63 | li {
64 | margin: 0px 4px 8px;
65 | display: inline-block;
66 | list-style: none;
67 | svg {
68 | width: 20px;
69 | height: 20px;
70 | }
71 | &.location {
72 | svg {
73 | margin-right: 4px;
74 | }
75 | }
76 | a {
77 | color: var(--text-body);
78 | &:hover {
79 | color: $accent-color;
80 | }
81 | }
82 | }
83 | }
84 | }
85 | &.has-image {
86 | background-size: cover;
87 | background-position: center center;
88 | color: #fff;
89 | &:before {
90 | background-color: rgba(#000, 0.6);
91 | }
92 | .inner-content {
93 | .tag-name, .post-count, .bio {
94 | color: #fff;
95 | }
96 | .author-name {
97 | a {
98 | color: #fff;
99 | &:hover {
100 | color: #fff;
101 | }
102 | }
103 | }
104 | .meta-info {
105 | color: #fff;
106 | li {
107 | a {
108 | color: #fff;
109 | &:hover {
110 | color: $accent-color;
111 | }
112 | }
113 | }
114 | }
115 | }
116 | }
117 | &:hover {
118 | .tag-name {
119 | &::before {
120 | width: 100%;
121 | }
122 | }
123 | }
124 | }
125 | [data-theme="light"] {
126 | .card-single:not(.has-image) {
127 | &:before {
128 | background-color: rgba(#000, 0.05);
129 | }
130 | }
131 | }
--------------------------------------------------------------------------------
/assets/scss/components/_color-and-font.scss:
--------------------------------------------------------------------------------
1 | /*=====================================================
2 | Fonts
3 | =====================================================*/
4 | $accent-color: #FDA403; /* theme highlight/primary color */
5 | $success: #0ca910;
6 | $error: #f0134d;
7 |
8 | $theme-light: (
9 | bg-color: #FFFFFF,
10 | text-title: #161616,
11 | text-body: #313131,
12 | text-light: #929399,
13 | );
14 |
15 | $theme-dark: (
16 | bg-color: #252733,
17 | text-title: #FFFFFF,
18 | text-body: #D5D5D5,
19 | text-light: #929399,
20 | );
21 |
22 | /*=====================================================
23 | Fonts
24 | =====================================================*/
25 | $font-body: 'Noto Sans', sans-serif;
26 | $font-title: 'Playfair Display', serif;
27 |
28 | /*=====================================================
29 | Please don't edit below code if you are not sure
30 | =====================================================*/
31 | :root {
32 | @each $name, $value in $theme-dark {
33 | --#{$name}: #{$value};
34 | }
35 | }
36 |
37 | [data-theme="light"] {
38 | @each $name, $value in $theme-light {
39 | --#{$name}: #{$value};
40 | }
41 | }
--------------------------------------------------------------------------------
/assets/scss/components/_cover.scss:
--------------------------------------------------------------------------------
1 | .cover-wrap {
2 | padding-top: 24px;
3 | .cover-inner {
4 | max-width: 858px;
5 | margin-left: 30px;
6 | margin-right: 30px;
7 | position: relative;
8 | z-index: 2;
9 | .avatar {
10 | width: 112px;
11 | height: 112px;
12 | margin-bottom: 24px;
13 | }
14 | .name {
15 | position: relative;
16 | &:before {
17 | content: "";
18 | width: 100%;
19 | height: 2px;
20 | position: absolute;
21 | left: 0;
22 | bottom: -16px;
23 | background: $accent-color;
24 | }
25 | }
26 | a {
27 | color: var(--text-title);
28 | &:hover {
29 | color: $accent-color;
30 | }
31 | }
32 | .post-count {
33 | margin-top: 24px;
34 | text-transform: uppercase;
35 | font-size: 0.875rem;
36 | letter-spacing: 1px;
37 | }
38 | .meta-info {
39 | padding: 0;
40 | margin-top: 24px;
41 | color: var(--text-body);
42 | li {
43 | margin: 0px 4px 8px;
44 | display: inline-block;
45 | list-style: none;
46 | svg {
47 | width: 20px;
48 | height: 20px;
49 | }
50 | a {
51 | color: var(--text-body);
52 | &:hover {
53 | color: $accent-color;
54 | }
55 | }
56 | }
57 | }
58 | .description, .bio {
59 | margin-top: 24px;
60 | font-size: 1.5rem;
61 | }
62 | }
63 | &.has-image {
64 | padding-top: 64px;
65 | padding-bottom: 64px;
66 | position: relative;
67 | background-size: cover;
68 | background-position: center center;
69 | color: #fff;
70 | &::before {
71 | content: '';
72 | width: 100%;
73 | height: 100%;
74 | background: rgba(#000, 0.6);
75 | position: absolute;
76 | top: 0;
77 | left: 0;
78 | z-index: 1;
79 | }
80 | .cover-inner {
81 | .name {
82 | color: #fff;
83 | }
84 | a {
85 | color: $accent-color;
86 | &:hover {
87 | color: $accent-color;
88 | }
89 | }
90 | .meta-info {
91 | li {
92 | a {
93 | color: #fff;
94 | &:hover {
95 | color: $accent-color;
96 | }
97 | }
98 | }
99 | }
100 | }
101 | }
102 | }
103 | @media screen and (min-width: 888px) {
104 | .cover-wrap {
105 | .cover-inner {
106 | width: 858px;
107 | margin-left: auto;
108 | margin-right: auto;
109 | }
110 | }
111 | }
--------------------------------------------------------------------------------
/assets/scss/components/_error.scss:
--------------------------------------------------------------------------------
1 | .error-wrap {
2 | margin: 0 auto;
3 | padding: 80px 30px;
4 | max-width: 760px;
5 | .error-code {
6 | font-family: $font-body;
7 | font-size: 5rem;
8 | line-height: 1;
9 | font-weight: 700;
10 | padding: 0px 24px 0px;
11 | border-radius: 8px;
12 | display: inline-flex;
13 | }
14 | .error-message {
15 | margin-bottom: 16px;
16 | font-family: $font-title;
17 | }
18 | .message-manual {
19 | font-size: 1.125rem;
20 | margin-bottom: 32px;
21 | }
22 | }
23 | @media screen and (min-width: 768px) {
24 | .error-wrap {
25 | .error-code {
26 | font-size: 7.5rem;
27 | }
28 | .error-message {
29 | font-size: 2rem;
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/assets/scss/components/_hero-area.scss:
--------------------------------------------------------------------------------
1 | .hero-area {
2 | padding-top: 24px;
3 | overflow: hidden;
4 | .container-fluid {
5 | height: 100%;
6 | }
7 | .hero-row {
8 | height: 100%;
9 | }
10 | .by-line {
11 | font-family: $font-body;
12 | line-height: 1.5;
13 | font-size: 1.5rem;
14 | }
15 | .headshot-wrap {
16 | height: 100%;
17 | }
18 | .headshot {
19 | width: 100%;
20 | height: 100%;
21 | object-fit: cover;
22 | object-position: center top;
23 | }
24 | div {
25 | max-height: 100%;
26 | }
27 | }
28 |
29 | @media screen and (min-width:768px) {
30 | .hero-area {
31 | height: calc( 100% - 96px);
32 | .intro {
33 | font-size: 7.5rem;
34 | }
35 | .by-line {
36 | font-size: 2rem;
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/assets/scss/components/_members.scss:
--------------------------------------------------------------------------------
1 | .members-page-content {
2 | max-width: 1200px;
3 | margin: 0 auto;
4 | }
5 | .members-page-subtitle {
6 | font-size: 1.5rem;
7 | margin-bottom: 40px;
8 | max-width: 900px;
9 | margin-left: auto;
10 | margin-right: auto;
11 | }
12 | .members-form-wrap {
13 | max-width: 600px;
14 | margin: 32px auto;
15 | }
16 | .loading-spinner {
17 | width: 14px;
18 | height: 14px;
19 | border: 2px solid;
20 | border-bottom-color: transparent;
21 | display: inline-block;
22 | border-radius: 50%;
23 | animation: spin 1.2s linear infinite;
24 | margin-right: 8px;
25 | margin-bottom: -2px;
26 | }
27 | @keyframes spin {
28 | 0% {
29 | transform: rotate(0deg);
30 | }
31 | 100% {
32 | transform: rotate(360deg);
33 | }
34 | }
35 | .members-form, .subscribe-form {
36 | .loading-spinner {
37 | display: none;
38 | }
39 | &.loading {
40 | .loading-spinner {
41 | display: inline-block;
42 | }
43 | }
44 | }
45 | .messages-wrap {
46 | margin-top: 24px;
47 | }
48 | .message-success, .message-error {
49 | display: none;
50 | color: #fff;
51 | padding: 4px 16px;
52 | border-radius: 4px;
53 | margin-bottom: 16px;
54 | font-size: 0.875rem;
55 | }
56 | .message-success {
57 | background-color: $success;
58 | }
59 | .message-error {
60 | background-color: $error;
61 | }
62 | .loading {
63 | .message-loading {
64 | display: inline-block;
65 | }
66 | }
67 | .success {
68 | .message-success {
69 | display: inline-block;
70 | }
71 | }
72 | .error {
73 | .message-error {
74 | display: inline-block;
75 | }
76 | }
77 | .pricing-table-wrap {
78 | display: flex;
79 | flex-wrap: wrap;
80 | justify-content: center;
81 | margin-left: -15px;
82 | margin-right: -15px;
83 | margin-top: 56px;
84 | }
85 | .pricing-table {
86 | display: flex;
87 | flex: 1 0 300px;
88 | flex-direction: column;
89 | border-radius: 2px;
90 | overflow: hidden;
91 | margin: 0px 15px 30px 15px;
92 | transition: transform 0.2s;
93 | max-width: 350px;
94 | // background: rgba(0, 0, 0, 0.1);
95 | }
96 | .pricing-table .pricing-table-title {
97 | margin-top: 0px;
98 | }
99 | .pricing-table .table-header {
100 | background-color: $accent-color;
101 | color: #ffffff;
102 | padding: 30px;
103 | border-radius: 2px 2px 0px 0px;
104 | }
105 | .pricing-table .pricing-table-title {
106 | color: #ffffff;
107 | text-transform: uppercase;
108 | margin-bottom: 16px;
109 | // font-size: 1.5rem;
110 | }
111 | .pricing-table .price .currency {
112 | font-size: 3rem;
113 | }
114 | .pricing-table .price .value {
115 | font-size: 3rem;
116 | }
117 | .pricing-table .price .duration {
118 | font-size: 1.125rem;
119 | text-transform: uppercase;
120 | }
121 | .pricing-table .table-details {
122 | padding: 30px 30px 30px 30px;
123 | margin-bottom: 0;
124 | list-style-type: none;
125 | flex-grow: 1;
126 | font-size: 16px;
127 | border-left: 2px solid $accent-color;
128 | border-right: 2px solid $accent-color;
129 | }
130 | .pricing-table .table-details li {
131 | margin-bottom: 12px;
132 | position: relative;
133 | padding-left: 20px;
134 | // font-family: $serif;
135 | }
136 | .pricing-table .table-details li svg {
137 | display: inline-block;
138 | color: var(--text-body);
139 | margin-right: 8px;
140 | position: absolute;
141 | left: 0;
142 | top: 8px;
143 | width: 12px;
144 | height: 12px;
145 | }
146 | .pricing-table .table-footer {
147 | padding: 0px 30px 30px 30px;
148 | border-width: 0px 2px 2px 2px;
149 | border-color: $accent-color;
150 | border-style: solid;
151 | border-radius: 0px 0px 2px 2px;
152 | }
153 | .member-alternate-link {
154 | font-size: 0.875rem;
155 | }
156 | .notification {
157 | position: fixed;
158 | top: 0;
159 | right: 0;
160 | left: 0;
161 | z-index: 999;
162 | background-color: $success;
163 | color: #fff;
164 | font-size: 1rem;
165 | padding: 24px 56px;
166 | visibility: hidden;
167 | transform: translateY(-150%);
168 | transition: all .25s ease-in-out .3s;
169 | a {
170 | position: absolute;
171 | top: 0;
172 | left: 0;
173 | right: 0;
174 | bottom: 0;
175 | }
176 | .close-icon {
177 | position: absolute;
178 | top: 16px;
179 | right: 32px;
180 | color: #fff;
181 | font-size: 1.5rem;
182 | }
183 | }
184 | .subscribe-success .notification-subscribe {
185 | visibility: visible;
186 | transform: translateY(0);
187 | }
188 | .signup-success .notification-signup {
189 | visibility: visible;
190 | transform: translateY(0);
191 | }
192 | .signin-success .notification-signin {
193 | visibility: visible;
194 | transform: translateY(0);
195 | }
196 | .checkout-success .notification-checkout {
197 | visibility: visible;
198 | transform: translateY(0);
199 | }
200 | .notification.closed {
201 | visibility: hidden;
202 | transform: translateY(-150%);
203 | transition: all 0.25s ease-in-out 0s;
204 | }
--------------------------------------------------------------------------------
/assets/scss/components/_post-list.scss:
--------------------------------------------------------------------------------
1 | .post-list {
2 | margin-top: 80px;
3 | .post {
4 | margin-bottom: 80px;
5 | min-height: 280px;
6 | }
7 | .post-thumbnail-wrap {
8 | .post-thumbnail {
9 | width: 100%;
10 | height: 400px;
11 | -o-object-fit: cover;
12 | object-fit: cover;
13 | }
14 | }
15 | .post-container {
16 | position: relative;
17 | }
18 | .watermark {
19 | font-family: $font-title;
20 | font-size: 24rem;
21 | text-transform: uppercase;
22 | color: rgba(#fff, 0.03);
23 | position: absolute;
24 | top: -0.46em;
25 | pointer-events: none;
26 | }
27 | .date {
28 | font-size: 0.875rem;
29 | text-transform: uppercase;
30 | letter-spacing: 1px;
31 | color: var(--text-light);
32 | position: absolute;
33 | width: 260px;
34 | top: 260px;
35 | transform: rotate(270deg);
36 | transform-origin: 0 0;
37 | }
38 | .primary-tag {
39 | font-size: 0.875rem;
40 | text-transform: uppercase;
41 | letter-spacing: 1px;
42 | margin-bottom: 16px;
43 | a {
44 | color: $accent-color;
45 | position: relative;
46 | &::before {
47 | content: "";
48 | width: 0;
49 | height: 1px;
50 | background: $accent-color;
51 | position: absolute;
52 | bottom: -4px;
53 | visibility: hidden;
54 | transition: width 0.2s ease;
55 | }
56 | &:hover {
57 | &::before {
58 | width: 100%;
59 | visibility: visible;
60 | }
61 | }
62 | }
63 | }
64 | .featured-label {
65 | background: $accent-color;
66 | color: #000;
67 | font-size: 0.75rem;
68 | padding: 0px 8px;
69 | margin-left: 8px;
70 |
71 | }
72 | .post-title {
73 | margin-bottom: 32px;
74 | a, a:hover {
75 | color: var(--text-title);
76 | }
77 | }
78 | .separetor {
79 | height: 2px;
80 | background-color: $accent-color;
81 | margin-bottom: 16px;
82 | }
83 | .reading-time {
84 | font-size: 0.875rem;
85 | text-transform: uppercase;
86 | color: var(--text-light);
87 | }
88 | }
89 | [data-theme="light"] {
90 | .post-list {
91 | .watermark {
92 | color: rgba(#000, 0.05);
93 | }
94 | }
95 | }
96 | .end-message {
97 | color: var(--text-light);
98 | font-size: 0.875rem;
99 | }
100 | @media screen and (max-width: 575px) {
101 | .post-list {
102 | .post-thumbnail-wrap {
103 | .post-thumbnail {
104 | height: 230px;
105 | }
106 | }
107 | }
108 | }
109 | @media screen and (max-width: 767px) {
110 | .post-list {
111 | .post-thumbnail-wrap {
112 | padding-bottom: 24px;
113 | }
114 | .post-container {
115 | padding: 40px 0px 0px 40px;
116 | }
117 | .watermark {
118 | left: -15px;
119 | font-size: 18rem;
120 | }
121 | .date {
122 | left: -7px;
123 | width: 196px;
124 | top: 196px;
125 | }
126 | .post-title {
127 | font-size: 2rem;
128 | }
129 | }
130 | }
131 | @media screen and (min-width:768px) {
132 | .post-list {
133 | .post:nth-child(odd) {
134 | .row {
135 | flex-direction: row-reverse;
136 | }
137 | .post-thumbnail-wrap {
138 | margin-left: 30px;
139 | }
140 | .post-container {
141 | padding: 40px 0px 0px 108px;
142 | }
143 | .watermark {
144 | left: 0px;
145 | }
146 | .date {
147 | left: 16px;
148 | }
149 | }
150 | .post:nth-child(even) {
151 | .post-thumbnail-wrap {
152 | margin-right: 30px;
153 | }
154 | .post-container {
155 | padding: 40px 108px 0px 0px;
156 | }
157 | .watermark {
158 | right: 0px;
159 | }
160 | .date {
161 | transform-origin: 100% 100%;
162 | top: -21px;
163 | right: 16px;
164 | }
165 | }
166 | }
167 | }
--------------------------------------------------------------------------------
/assets/scss/components/_prism.scss:
--------------------------------------------------------------------------------
1 | /* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript+actionscript+applescript+aspnet+bash+basic+c+bison+csharp+cpp+coffeescript+ruby+css-extras+diff+docker+erlang+fsharp+fortran+git+go+haskell+http+icon+java+json+latex+lua+makefile+markdown+matlab+nasm+nginx+objectivec+pascal+perl+php+php-extras+properties+python+r+jsx+rust+scala+scheme+smalltalk+sql+swift+vim+wiki */
2 | /**
3 | * okaidia theme for JavaScript, CSS and HTML
4 | * Loosely based on Monokai textmate theme by http://www.monokai.nl/
5 | * @author ocodia
6 | */
7 |
8 | code[class*="language-"],
9 | pre[class*="language-"] {
10 | color: #f8f8f2;
11 | background: none;
12 | text-shadow: 0 1px rgba(0, 0, 0, 0.3);
13 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
14 | text-align: left;
15 | white-space: pre;
16 | word-spacing: normal;
17 | word-break: normal;
18 | word-wrap: normal;
19 | line-height: 1.5;
20 |
21 | -moz-tab-size: 4;
22 | -o-tab-size: 4;
23 | tab-size: 4;
24 |
25 | -webkit-hyphens: none;
26 | -moz-hyphens: none;
27 | -ms-hyphens: none;
28 | hyphens: none;
29 | }
30 |
31 | /* Code blocks */
32 | pre[class*="language-"] {
33 | padding: 1em;
34 | margin: .5em 0;
35 | overflow: auto;
36 | border-radius: 0.3em;
37 | }
38 |
39 | :not(pre) > code[class*="language-"],
40 | pre[class*="language-"] {
41 | background: #272822;
42 | }
43 |
44 | /* Inline code */
45 | :not(pre) > code[class*="language-"] {
46 | padding: .1em;
47 | border-radius: .3em;
48 | white-space: normal;
49 | }
50 |
51 | .token.comment,
52 | .token.prolog,
53 | .token.doctype,
54 | .token.cdata {
55 | color: slategray;
56 | }
57 |
58 | .token.punctuation {
59 | color: #f8f8f2;
60 | }
61 |
62 | .namespace {
63 | opacity: .7;
64 | }
65 |
66 | .token.property,
67 | .token.tag,
68 | .token.constant,
69 | .token.symbol,
70 | .token.deleted {
71 | color: #f92672;
72 | }
73 |
74 | .token.boolean,
75 | .token.number {
76 | color: #ae81ff;
77 | }
78 |
79 | .token.selector,
80 | .token.attr-name,
81 | .token.string,
82 | .token.char,
83 | .token.builtin,
84 | .token.inserted {
85 | color: #a6e22e;
86 | }
87 |
88 | .token.operator,
89 | .token.entity,
90 | .token.url,
91 | .language-css .token.string,
92 | .style .token.string,
93 | .token.variable {
94 | color: #f8f8f2;
95 | }
96 |
97 | .token.atrule,
98 | .token.attr-value,
99 | .token.function {
100 | color: #e6db74;
101 | }
102 |
103 | .token.keyword {
104 | color: #66d9ef;
105 | }
106 |
107 | .token.regex,
108 | .token.important {
109 | color: #fd971f;
110 | }
111 |
112 | .token.important,
113 | .token.bold {
114 | font-weight: bold;
115 | }
116 | .token.italic {
117 | font-style: italic;
118 | }
119 |
120 | .token.entity {
121 | cursor: help;
122 | }
123 |
124 | div.prism-show-language {
125 | position: relative;
126 | }
127 |
128 | div.prism-show-language > div.prism-show-language-label[data-language] {
129 | content: attr(data-language);
130 | color: black;
131 | background-color: #CFCFCF;
132 | display: inline-block;
133 | position: absolute;
134 | top: 0;
135 | right: 0;
136 | font-size: 0.9em;
137 | border-radius: 0 0 0 5px;
138 | padding: 0 0.5em;
139 | text-shadow: none;
140 | }
--------------------------------------------------------------------------------
/assets/scss/screen.scss:
--------------------------------------------------------------------------------
1 | /*=====================================================
2 | Please do not reorder any import,
3 | It can break some style
4 | =====================================================*/
5 | @import 'components/color-and-font';
6 | @import 'components/common';
7 | @import 'components/header';
8 | @import 'components/hero-area';
9 | @import 'components/post-list';
10 | @import 'components/footer';
11 | @import 'components/single-article';
12 | @import 'components/archive';
13 | @import 'components/cover';
14 | @import 'components/error';
15 | @import 'components/search-popup';
16 | @import 'components/members';
17 | @import 'components/prism';
--------------------------------------------------------------------------------
/author.hbs:
--------------------------------------------------------------------------------
1 | {{!< default}}
2 | {{! The tag above means - insert everything in this file into the {body} of the default.hbs template }}
3 |
4 | {{#author}}
5 |
6 |
7 |
8 | {{#if profile_image}}
9 |
10 |
11 |
12 | {{else}}
13 |
{{> icons/user}}
14 | {{/if}}
15 |
16 |
{{name}}
17 |
{{t "Total"}} {{plural ../pagination.total empty=(t "0 Post") singular=(t "1 Post") plural=(t "% Posts")}}
18 | {{#if bio}}
19 |
{{bio}}
20 | {{/if}}
21 |
35 |
36 |
37 |
38 | {{/author}}
39 |
40 | {{> loop}}
41 |
42 | {{pagination}}
43 |
--------------------------------------------------------------------------------
/custom-author-archive.hbs:
--------------------------------------------------------------------------------
1 | {{!< default}}
2 | {{! The tag above means - insert everything in this file into the {body} of the default.hbs template }}
3 |
4 |
5 |
6 | {{#post}}
7 |
21 | {{/post}}
22 |
23 | {{#get "authors" limit="all" include="count.posts" order="name asc"}}
24 | {{#foreach authors}}
25 |
57 | {{/foreach}}
58 | {{/get}}
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/custom-tag-archive.hbs:
--------------------------------------------------------------------------------
1 | {{!< default}}
2 | {{! The tag above means - insert everything in this file into the {body} of the default.hbs template }}
3 |
4 |
5 |
6 | {{#post}}
7 |
21 | {{/post}}
22 |
23 | {{#get "tags" limit="all" include="count.posts" order="count.posts desc"}}
24 | {{#foreach tags}}
25 |
35 | {{/foreach}}
36 | {{/get}}
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/default.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{! Document Settings }}
5 |
6 |
7 | {{meta_title}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | {{! Page Meta }}
18 | {{meta_title}}
19 | {{! Styles'n'Scripts }}
20 |
21 |
24 | {{! Ghost outputs important style and meta data with this tag }}
25 |
35 | {{ghost_head}}
36 |
39 |
40 |
41 |
42 |
43 | {{! insert header partial}}
44 | {{> header}}
45 | {{> search-popup}}
46 |
47 | {{{body}}}
48 |
49 | {{! insert footer partial}}
50 | {{> footer}}
51 | {{! scripts}}
52 |
62 |
63 | {{ghost_foot}}
64 |
80 |
81 |
--------------------------------------------------------------------------------
/error.hbs:
--------------------------------------------------------------------------------
1 | {{!< default}}
2 | {{! The tag above means - insert everything in this file into the {body} of the default.hbs template }}
3 |
4 |
5 |
6 |
{{statusCode}}
7 |
{{message}}
8 |
{{t "Return to home page"}}
9 |
10 | {{#if errorDetails}}
11 |
12 | {{t "Theme errors"}}
13 |
25 |
26 | {{/if}}
27 |
28 |
--------------------------------------------------------------------------------
/example/Gruntfile.js:
--------------------------------------------------------------------------------
1 | const sass = require('node-sass');
2 |
3 | /* global module:false */
4 | module.exports = function(grunt) {
5 | var port = grunt.option('port') || 8000;
6 | // Project configuration
7 | grunt.initConfig({
8 | pkg: grunt.file.readJSON('package.json'),
9 | meta: {
10 | banner:
11 | '/*!\n' +
12 | ' * http://lab.hakim.se\n' +
13 | ' *\n' +
14 | ' * Copyright (C) 2015 Hakim El Hattab, http://hakim.se\n' +
15 | ' */'
16 | },
17 |
18 | cssmin: {
19 | compress: {
20 | files: {}
21 | }
22 | },
23 |
24 | sass: {
25 | options: {
26 | implementation: sass
27 | },
28 | main: {
29 | files: {
30 | 'device-loop/style.css': 'device-loop/style.scss',
31 | 'flexing-pagination/style.css': 'flexing-pagination/style.scss',
32 | 'cloudy-spiral/style.css': 'cloudy-spiral/style.scss',
33 | 'checkwave/style.css': 'checkwave/style.scss',
34 | 'monocle/style.css': 'monocle/style.scss',
35 | 'flipside/style.css': 'flipside/style.scss',
36 | 'progress-nav/style.css': 'progress-nav/style.scss'
37 | }
38 | }
39 | },
40 |
41 | autoprefixer: {
42 | dist: {
43 | files: [
44 | { src: 'flexing-pagination/style.css' },
45 | { src: 'flipside/style.css' },
46 | { src: 'progress-nav/style.css' }
47 | ]
48 | }
49 | },
50 |
51 | jshint: {
52 | options: {
53 | curly: false,
54 | eqeqeq: true,
55 | immed: true,
56 | latedef: true,
57 | newcap: true,
58 | noarg: true,
59 | sub: true,
60 | undef: true,
61 | eqnull: true,
62 | browser: true,
63 | expr: true,
64 | globals: {
65 | head: false,
66 | module: false,
67 | console: false
68 | }
69 | },
70 | files: [ 'Gruntfile.js', '**/*.js' ]
71 | },
72 |
73 | connect: {
74 | server: {
75 | options: {
76 | port: port,
77 | base: '.'
78 | }
79 | }
80 | },
81 |
82 | watch: {
83 | main: {
84 | files: [ 'Gruntfile.js', '*/*.js', '*/*.scss' ],
85 | tasks: 'default'
86 | },
87 | }
88 |
89 | });
90 |
91 | // Dependencies
92 | grunt.loadNpmTasks( 'grunt-contrib-jshint' );
93 | grunt.loadNpmTasks( 'grunt-contrib-uglify' );
94 | grunt.loadNpmTasks( 'grunt-contrib-watch' );
95 | grunt.loadNpmTasks( 'grunt-contrib-connect' );
96 | grunt.loadNpmTasks( 'grunt-autoprefixer' );
97 | grunt.loadNpmTasks( 'grunt-sass' );
98 |
99 | // Default task
100 | grunt.registerTask( 'default', [ 'sass', 'autoprefixer' ] );
101 |
102 | // Serve presentation locally
103 | grunt.registerTask( 'serve', [ 'connect', 'watch' ] );
104 |
105 | };
106 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | Assorted CSS and UI experiments from [@hakimel](http://twitter.com/hakimel).
2 |
3 | Live demos:
4 | - Cloudy Spiral http://lab.hakim.se/cloudy-spiral/
5 | - Flexing Pagination http://lab.hakim.se/flexing-pagination/
6 | - Device Loop http://lab.hakim.se/device-loop/
7 | - Checkwave http://lab.hakim.se/checkwave/
8 | - Monocle List http://lab.hakim.se/monocle/
9 | - Flipside http://lab.hakim.se/flipside/
10 | - Progress Nav http://lab.hakim.se/progress-nav/
11 |
12 | Copyright (C) 2016 Hakim El Hattab, http://hakim.se
13 |
--------------------------------------------------------------------------------
/example/checkwave/checkwave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/example/checkwave/checkwave.png
--------------------------------------------------------------------------------
/example/checkwave/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Checkwave
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
87 |
88 |
89 |
90 |
95 |
96 |
123 |
124 |
134 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/example/checkwave/style.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | font-family: Helvetica, sans-serif;
3 | }
4 |
5 | .wrapper {
6 | position: absolute;
7 | top: 0;
8 | right: 0;
9 | bottom: 0;
10 | left: 0;
11 | margin: auto;
12 | zoom: 1.4;
13 | }
14 |
15 | input {
16 | position: absolute;
17 | will-change: transform;
18 | }
19 |
20 | input.grow {
21 | animation: grow 0.8s cubic-bezier(0.175, 0.885, 0.320, 1.275);
22 | }
23 |
24 | @keyframes grow {
25 | 0% { transform: scale(1); }
26 | 30% { transform: scale(2.5); }
27 | 100% { transform: scale(1); }
28 | }
--------------------------------------------------------------------------------
/example/cloudy-spiral/style.scss:
--------------------------------------------------------------------------------
1 |
2 | $particles: 62; // has to match nodes in dom
3 | $particleSize: 8px;
4 | $radius: 80;
5 | $lapDuration: 3s;
6 |
7 |
8 | @keyframes spin {
9 | from {
10 | opacity: 0.0;
11 | }
12 | to {
13 | opacity: 0.6;
14 | transform: translate3d(-$particleSize/2, -$particleSize/2, 570px);
15 | }
16 | }
17 |
18 | html, body {
19 | overflow: hidden;
20 | background: #3e6fa3;
21 | font-family: Helvetica, sans-serif;
22 | }
23 |
24 | .wrapper {
25 | position: absolute;
26 | top: 50%;
27 | left: 50%;
28 | z-index: 2;
29 |
30 | perspective: 500px;
31 | }
32 |
33 | i {
34 | display: block;
35 | position: absolute;
36 | width: $particleSize;
37 | height: $particleSize;
38 | border-radius: $particleSize;
39 | opacity: 0;
40 | background: rgba(255,255,255,0.5);
41 | box-shadow: 0px 0px 10px rgba(255,255,255,1);
42 |
43 | animation-name: spin;
44 | animation-duration: $lapDuration;
45 | animation-iteration-count: infinite;
46 | animation-timing-function: ease-in-out;
47 | }
48 |
49 | @for $i from 1 through $particles {
50 | i:nth-child(#{$i}) {
51 | $angle: ( $i / $particles ) * 720;
52 |
53 | transform: rotate( #{$angle}deg ) translate3d( #{$radius}px, 0, 0 );
54 | animation-delay: $i * ($lapDuration / $particles);
55 | }
56 | }
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | // background color controls
71 | #black {
72 | position: absolute;
73 | left: 15px;
74 | bottom: 15px;
75 | color: rgba(255,255,255,0.6);
76 | text-decoration: none;
77 |
78 | &:after { content: 'Black & white'; }
79 | }
80 |
81 | #black:target {
82 | top: 0;
83 | left: 0;
84 | width: 100%;
85 | height: 100%;
86 | z-index: 1;
87 | background: #111;
88 | cursor: default;
89 |
90 | &:after { content: ''; }
91 | }
--------------------------------------------------------------------------------
/example/device-loop/device-loop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/example/device-loop/device-loop.png
--------------------------------------------------------------------------------
/example/device-loop/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Device loop animation
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | A device loop animation as seen on slides.com
20 |
21 |
33 |
34 |
44 |
45 |
46 |
47 |
52 |
53 |
80 |
81 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/example/device-loop/style.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | margin: 10px;
3 | text-align: center;
4 | font-family: Helvetica, sans-serif; }
5 |
6 | p {
7 | display: inline-block;
8 | color: #333;
9 | vertical-align: middle;
10 | font-size: 20px;
11 | text-align: right;
12 | line-height: 1.6; }
13 | p a {
14 | color: #333;
15 | padding: 2px 4px;
16 | border: 2px solid #aaa;
17 | border-radius: 2px;
18 | text-decoration: none; }
19 | p a:hover {
20 | border-color: #666;
21 | color: #000; }
22 |
23 | .animation {
24 | display: inline-block;
25 | position: relative;
26 | width: 460px;
27 | height: 377px;
28 | margin: 0 auto;
29 | vertical-align: middle; }
30 | .animation .device {
31 | position: absolute;
32 | width: 100%;
33 | height: 100%;
34 | left: 50%;
35 | top: 50%;
36 | background: #111;
37 | -webkit-transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
38 | -moz-transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
39 | -ms-transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
40 | transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
41 | -webkit-transform: translate(-50%, -50%);
42 | -moz-transform: translate(-50%, -50%);
43 | -ms-transform: translate(-50%, -50%);
44 | transform: translate(-50%, -50%); }
45 | .animation .device .phone-home-button,
46 | .animation .device .tablet-home-button {
47 | position: absolute;
48 | border-radius: 50%;
49 | background: #444;
50 | opacity: 0;
51 | z-index: 1;
52 | -webkit-transition: all 0.4s ease;
53 | -moz-transition: all 0.4s ease;
54 | -ms-transition: all 0.4s ease;
55 | transition: all 0.4s ease; }
56 | .animation .device .phone-home-button {
57 | width: 16px;
58 | height: 16px;
59 | margin-top: -8px;
60 | right: 11px;
61 | top: 50%; }
62 | .animation .device .tablet-home-button {
63 | width: 12px;
64 | height: 12px;
65 | margin-left: -6px;
66 | bottom: 7px;
67 | left: 50%; }
68 | .animation .device .screen-stand {
69 | position: absolute;
70 | width: 100%;
71 | margin-left: -10px;
72 | margin-top: -1px;
73 | top: 60%;
74 | opacity: 0;
75 | z-index: 1;
76 | -webkit-transition: all 0.4s ease-out;
77 | -moz-transition: all 0.4s ease-out;
78 | -ms-transition: all 0.4s ease-out;
79 | transition: all 0.4s ease-out; }
80 | .animation .device .screen-stand .leg {
81 | position: absolute;
82 | width: 12px;
83 | height: 16px;
84 | left: 50%;
85 | top: 0;
86 | margin-left: -6px;
87 | background: #111; }
88 | .animation .device .screen-stand .foot {
89 | position: absolute;
90 | width: 120px;
91 | height: 4px;
92 | left: 50%;
93 | top: 15px;
94 | margin-left: -60px;
95 | border-top-left-radius: 2px;
96 | border-top-right-radius: 2px;
97 | background: #111; }
98 | .animation .device .display {
99 | position: relative;
100 | width: 100%;
101 | height: 100%;
102 | overflow: hidden;
103 | background: #34495e;
104 | z-index: 3; }
105 | .animation .device .display div {
106 | position: absolute;
107 | width: 100%;
108 | height: 100%;
109 | left: 100%;
110 | white-space: nowrap;
111 | -webkit-transition: all 0.4s ease;
112 | -moz-transition: all 0.4s ease;
113 | -ms-transition: all 0.4s ease;
114 | transition: all 0.4s ease; }
115 | .animation .device .display div div {
116 | position: absolute;
117 | width: 100%;
118 | left: 0;
119 | top: 50%;
120 | margin-top: -14px;
121 | font-size: 1.1em;
122 | text-align: center;
123 | color: #fff; }
124 | .animation .device .display div div em {
125 | font-weight: bold; }
126 | .animation .device .display .slide1 {
127 | background: #34495e; }
128 | .animation .device .display .slide2 {
129 | background: #16a085; }
130 | .animation .device .display .slide3 {
131 | background: #3498db; }
132 | .animation[data-animation-step="1"] .device {
133 | width: 70%;
134 | height: 60%;
135 | padding: 10px;
136 | border-radius: 4px; }
137 | .animation[data-animation-step="1"] .device .slide1 {
138 | left: 0%; }
139 | .animation[data-animation-step="1"] .device .screen-stand {
140 | opacity: 1;
141 | top: 100%; }
142 | .animation[data-animation-step="2"] .device {
143 | width: 45%;
144 | height: 72%;
145 | padding: 24px;
146 | border-radius: 10px; }
147 | .animation[data-animation-step="2"] .device .slide1 {
148 | left: -100%; }
149 | .animation[data-animation-step="2"] .device .slide2 {
150 | left: 0%; }
151 | .animation[data-animation-step="2"] .device .tablet-home-button {
152 | opacity: 1; }
153 | .animation[data-animation-step="3"] .device {
154 | width: 54%;
155 | height: 38%;
156 | padding: 10px 36px;
157 | border-radius: 6px; }
158 | .animation[data-animation-step="3"] .device .slide1,
159 | .animation[data-animation-step="3"] .device .slide2 {
160 | left: -100%; }
161 | .animation[data-animation-step="3"] .device .slide3 {
162 | left: 0%; }
163 | .animation[data-animation-step="3"] .device .phone-home-button {
164 | opacity: 1; }
165 |
--------------------------------------------------------------------------------
/example/device-loop/style.scss:
--------------------------------------------------------------------------------
1 |
2 | $width: 460px;
3 | $height: 377px;
4 |
5 | $deviceTransitionDuration: 0.4s;
6 |
7 | $screenWidth: 70%;
8 | $screenHeight: 60%;
9 |
10 | $tabletWidth: 45%;
11 | $tabletHeight: 72%;
12 |
13 | $phoneWidth: 54%;
14 | $phoneHeight: 38%;
15 |
16 | @mixin transition( $value ) {
17 | -webkit-transition: $value;
18 | -moz-transition: $value;
19 | -ms-transition: $value;
20 | transition: $value;
21 | }
22 |
23 | @mixin transform( $value ) {
24 | -webkit-transform: $value;
25 | -moz-transform: $value;
26 | -ms-transform: $value;
27 | transform: $value;
28 | }
29 |
30 | html, body {
31 | margin: 10px;
32 | text-align: center;
33 | font-family: Helvetica, sans-serif;
34 | }
35 |
36 | p {
37 | display: inline-block;
38 | color: #333;
39 | vertical-align: middle;
40 | font-size: 20px;
41 | text-align: right;
42 | line-height: 1.6;
43 |
44 | a {
45 | color: #333;
46 | padding: 2px 4px;
47 | border: 2px solid #aaa;
48 | border-radius: 2px;
49 | text-decoration: none;
50 |
51 | &:hover {
52 | border-color: #666;
53 | color: #000;
54 | }
55 | }
56 | }
57 |
58 | .animation {
59 | display: inline-block;
60 | position: relative;
61 | width: $width;
62 | height: $height;
63 | margin: 0 auto;
64 | vertical-align: middle;
65 |
66 | .device {
67 | position: absolute;
68 | width: 100%;
69 | height: 100%;
70 | left: 50%;
71 | top: 50%;
72 | background: #111;
73 |
74 | @include transition( all $deviceTransitionDuration cubic-bezier(0.175, 0.885, 0.320, 1.275) );
75 | @include transform( translate(-50%, -50%) );
76 |
77 | .phone-home-button,
78 | .tablet-home-button {
79 | position: absolute;
80 | border-radius: 50%;
81 | background: #444;
82 | opacity: 0;
83 | z-index: 1;
84 |
85 | @include transition( all $deviceTransitionDuration ease );
86 | }
87 |
88 | .phone-home-button {
89 | width: 16px;
90 | height: 16px;
91 | margin-top: -8px;
92 | right: 11px;
93 | top: 50%;
94 | }
95 |
96 | .tablet-home-button {
97 | width: 12px;
98 | height: 12px;
99 | margin-left: -6px;
100 | bottom: 7px;
101 | left: 50%;
102 | }
103 |
104 | .screen-stand {
105 | position: absolute;
106 | width: 100%;
107 | margin-left: -10px;
108 | margin-top: -1px;
109 | top: 60%;
110 | opacity: 0;
111 | z-index: 1;
112 |
113 | .leg {
114 | position: absolute;
115 | width: 12px;
116 | height: 16px;
117 | left: 50%;
118 | top: 0;
119 | margin-left: -6px;
120 |
121 | background: #111;
122 | }
123 |
124 | .foot {
125 | position: absolute;
126 | width: 120px;
127 | height: 4px;
128 | left: 50%;
129 | top: 15px;
130 | margin-left: -60px;
131 | border-top-left-radius: 2px;
132 | border-top-right-radius: 2px;
133 |
134 | background: #111;
135 | }
136 |
137 | @include transition( all $deviceTransitionDuration ease-out );
138 | }
139 |
140 | .display {
141 | position: relative;
142 | width: 100%;
143 | height: 100%;
144 | overflow: hidden;
145 | background: #34495e;
146 | z-index: 3;
147 |
148 | div {
149 | position: absolute;
150 | width: 100%;
151 | height: 100%;
152 | left: 100%;
153 | white-space: nowrap;
154 |
155 | @include transition( all $deviceTransitionDuration ease );
156 |
157 | div {
158 | position: absolute;
159 | width: 100%;
160 | left: 0;
161 | top: 50%;
162 | margin-top: -14px;
163 | font-size: 1.1em;
164 | text-align: center;
165 | color: #fff;
166 |
167 | em {
168 | font-weight: bold;
169 | }
170 | }
171 | }
172 |
173 | .slide1 { background: #34495e; }
174 | .slide2 { background: #16a085; }
175 | .slide3 { background: #3498db; }
176 | }
177 | }
178 |
179 | &[data-animation-step="1"] .device {
180 | width: $screenWidth;
181 | height: $screenHeight;
182 | padding: 10px;
183 | border-radius: 4px;
184 |
185 | .slide1 {
186 | left: 0%;
187 | }
188 |
189 | .screen-stand {
190 | opacity: 1;
191 | top: 100%;
192 | }
193 | }
194 |
195 | &[data-animation-step="2"] .device {
196 | width: $tabletWidth;
197 | height: $tabletHeight;
198 | padding: 24px;
199 | border-radius: 10px;
200 |
201 | .slide1 {
202 | left: -100%;
203 | }
204 |
205 | .slide2 {
206 | left: 0%;
207 | }
208 |
209 | .tablet-home-button {
210 | opacity: 1;
211 | }
212 | }
213 |
214 | &[data-animation-step="3"] .device {
215 | width: $phoneWidth;
216 | height: $phoneHeight;
217 | padding: 10px 36px;
218 | border-radius: 6px;
219 |
220 | .slide1,
221 | .slide2 {
222 | left: -100%;
223 | }
224 |
225 | .slide3 {
226 | left: 0%;
227 | }
228 |
229 | .phone-home-button {
230 | opacity: 1;
231 | }
232 | }
233 | }
--------------------------------------------------------------------------------
/example/flexing-pagination/flexing-pagination.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/example/flexing-pagination/flexing-pagination.png
--------------------------------------------------------------------------------
/example/flexing-pagination/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Flexing pagination arrows
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Flexing pagination arrows
20 |
21 |
22 |
23 |
24 |
25 |
26 |
49 |
50 |
51 |
52 |
57 |
58 |
93 |
94 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/example/flexing-pagination/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | background: #33ab83;
4 | font-family: Helvetica, sans-serif; }
5 |
6 | button {
7 | -webkit-appearance: none;
8 | background: transparent;
9 | border: 0;
10 | outline: 0; }
11 |
12 | .paginate {
13 | position: relative;
14 | margin: 10px;
15 | width: 50px;
16 | height: 50px;
17 | cursor: pointer;
18 | transform: translate3d(0, 0, 0);
19 | position: absolute;
20 | top: 50%;
21 | margin-top: -20px;
22 | -webkit-filter: drop-shadow(0 2px 0px rgba(0, 0, 0, 0.2)); }
23 | .paginate i {
24 | position: absolute;
25 | top: 40%;
26 | left: 0;
27 | width: 50px;
28 | height: 5px;
29 | border-radius: 2.5px;
30 | background: #fff;
31 | transition: all 0.15s ease; }
32 | .paginate.left {
33 | right: 58%; }
34 | .paginate.left i {
35 | transform-origin: 0% 50%; }
36 | .paginate.left i:first-child {
37 | transform: translate(0, -1px) rotate(40deg); }
38 | .paginate.left i:last-child {
39 | transform: translate(0, 1px) rotate(-40deg); }
40 | .paginate.left:hover i:first-child {
41 | transform: translate(0, -1px) rotate(30deg); }
42 | .paginate.left:hover i:last-child {
43 | transform: translate(0, 1px) rotate(-30deg); }
44 | .paginate.left:active i:first-child {
45 | transform: translate(1px, -1px) rotate(25deg); }
46 | .paginate.left:active i:last-child {
47 | transform: translate(1px, 1px) rotate(-25deg); }
48 | .paginate.left[data-state=disabled] i:first-child {
49 | transform: translate(-5px, 0) rotate(0deg); }
50 | .paginate.left[data-state=disabled] i:last-child {
51 | transform: translate(-5px, 0) rotate(0deg); }
52 | .paginate.left[data-state=disabled]:hover i:first-child {
53 | transform: translate(-5px, 0) rotate(0deg); }
54 | .paginate.left[data-state=disabled]:hover i:last-child {
55 | transform: translate(-5px, 0) rotate(0deg); }
56 | .paginate.right {
57 | left: 58%; }
58 | .paginate.right i {
59 | transform-origin: 100% 50%; }
60 | .paginate.right i:first-child {
61 | transform: translate(0, 1px) rotate(40deg); }
62 | .paginate.right i:last-child {
63 | transform: translate(0, -1px) rotate(-40deg); }
64 | .paginate.right:hover i:first-child {
65 | transform: translate(0, 1px) rotate(30deg); }
66 | .paginate.right:hover i:last-child {
67 | transform: translate(0, -1px) rotate(-30deg); }
68 | .paginate.right:active i:first-child {
69 | transform: translate(1px, 1px) rotate(25deg); }
70 | .paginate.right:active i:last-child {
71 | transform: translate(1px, -1px) rotate(-25deg); }
72 | .paginate.right[data-state=disabled] i:first-child {
73 | transform: translate(5px, 0) rotate(0deg); }
74 | .paginate.right[data-state=disabled] i:last-child {
75 | transform: translate(5px, 0) rotate(0deg); }
76 | .paginate.right[data-state=disabled]:hover i:first-child {
77 | transform: translate(5px, 0) rotate(0deg); }
78 | .paginate.right[data-state=disabled]:hover i:last-child {
79 | transform: translate(5px, 0) rotate(0deg); }
80 | .paginate[data-state=disabled] {
81 | opacity: 0.3;
82 | cursor: default; }
83 |
84 | .counter {
85 | text-align: center;
86 | position: absolute;
87 | width: 100%;
88 | top: 50%;
89 | margin-top: -15px;
90 | font-size: 30px;
91 | text-shadow: 0px 2px 0px rgba(0, 0, 0, 0.2);
92 | color: #fff; }
93 |
--------------------------------------------------------------------------------
/example/flexing-pagination/style.scss:
--------------------------------------------------------------------------------
1 | $size: 50px;
2 | $thickness: 5px;
3 | $angle: 40deg;
4 | $angleHover: 30deg;
5 | $angleActive: 25deg;
6 |
7 | @mixin transition( $value ) {
8 | transition: $value;
9 | }
10 |
11 | @mixin transform( $value ) {
12 | transform: $value;
13 | }
14 |
15 | @mixin transform-origin( $value ) {
16 | transform-origin: $value;
17 | }
18 |
19 | @mixin arrowTransform( $angle, $x: 0, $y: 0 ) {
20 | i:first-child {
21 | @include transform( translate( $x, $y ) rotate( $angle ) );
22 | }
23 |
24 | i:last-child {
25 | @include transform( translate( $x, -$y ) rotate( -$angle ) );
26 | }
27 | }
28 |
29 | body {
30 | margin: 0;
31 | background: #33ab83;
32 | font-family: Helvetica, sans-serif;
33 | }
34 |
35 | button {
36 | -webkit-appearance: none;
37 | background: transparent;
38 | border: 0;
39 | outline: 0;
40 | }
41 |
42 | .paginate {
43 | position: relative;
44 | margin: 10px;
45 | width: $size;
46 | height: $size;
47 | cursor: pointer;
48 | @include transform( translate3d(0,0,0) ); // fixes flicker in webkit
49 |
50 | position: absolute;
51 | top: 50%;
52 | margin-top: -20px;
53 | -webkit-filter: drop-shadow( 0 2px 0px rgba(0,0,0,0.2) );
54 |
55 | i {
56 | position: absolute;
57 | top: 40%;
58 | left: 0;
59 | width: $size;
60 | height: $thickness;
61 | border-radius: $thickness / 2;
62 | background: #fff;
63 |
64 | @include transition( all 0.15s ease );
65 | }
66 |
67 | &.left {
68 | right: 58%;
69 |
70 | i {
71 | @include transform-origin( 0% 50% );
72 | }
73 |
74 | @include arrowTransform( $angle, 0, -1px );
75 |
76 | &:hover {
77 | @include arrowTransform( $angleHover, 0, -1px );
78 | }
79 |
80 | &:active {
81 | @include arrowTransform( $angleActive, 1px, -1px );
82 | }
83 |
84 | &[data-state=disabled] {
85 | @include arrowTransform( 0deg, -5px, 0 );
86 |
87 | &:hover {
88 | @include arrowTransform( 0deg, -5px, 0 );
89 | }
90 | }
91 | }
92 |
93 | &.right {
94 | left: 58%;
95 |
96 | i {
97 | @include transform-origin( 100% 50% );
98 | }
99 |
100 | @include arrowTransform( $angle, 0, 1px );
101 |
102 | &:hover {
103 | @include arrowTransform( $angleHover, 0, 1px );
104 | }
105 |
106 | &:active {
107 | @include arrowTransform( $angleActive, 1px, 1px );
108 | }
109 |
110 | &[data-state=disabled] {
111 | @include arrowTransform( 0deg, 5px, 0 );
112 |
113 | &:hover {
114 | @include arrowTransform( 0deg, 5px, 0 );
115 | }
116 | }
117 | }
118 |
119 | &[data-state=disabled] {
120 | opacity: 0.3;
121 | cursor: default;
122 | }
123 | }
124 |
125 |
126 |
127 | .counter {
128 | text-align: center;
129 | position: absolute;
130 | width: 100%;
131 | top: 50%;
132 | margin-top: -15px;
133 | font-size: 30px;
134 | text-shadow: 0px 2px 0px rgba( 0, 0, 0, 0.2 );
135 | color: #fff;
136 | }
--------------------------------------------------------------------------------
/example/flipside/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Flipside
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
Are you sure you want to do that?
25 |
Yes
26 |
No
27 |
28 |
Delete
29 |
30 |
31 | Try clicking different sides of the button
32 |
33 |
34 |
35 |
36 |
37 | Flipside – A button that seamlessly transitions from action to confirmation
38 |
39 |
44 |
45 |
103 |
104 |
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/example/flipside/script.js:
--------------------------------------------------------------------------------
1 | window.onload = function() {
2 |
3 | var btn = document.querySelector( '.btn' );
4 |
5 | var btnFront = btn.querySelector( '.btn-front' ),
6 | btnYes = btn.querySelector( '.btn-back .yes' ),
7 | btnNo = btn.querySelector( '.btn-back .no' );
8 |
9 | btnFront.addEventListener( 'click', function( event ) {
10 | var mx = event.clientX - btn.offsetLeft,
11 | my = event.clientY - btn.offsetTop;
12 |
13 | var w = btn.offsetWidth,
14 | h = btn.offsetHeight;
15 |
16 | var directions = [
17 | { id: 'top', x: w/2, y: 0 },
18 | { id: 'right', x: w, y: h/2 },
19 | { id: 'bottom', x: w/2, y: h },
20 | { id: 'left', x: 0, y: h/2 }
21 | ];
22 |
23 | directions.sort( function( a, b ) {
24 | return distance( mx, my, a.x, a.y ) - distance( mx, my, b.x, b.y );
25 | } );
26 |
27 | btn.setAttribute( 'data-direction', directions.shift().id );
28 | btn.classList.add( 'is-open' );
29 | } );
30 |
31 | btnYes.addEventListener( 'click', function( event ) {
32 | btn.classList.remove( 'is-open' );
33 | } );
34 |
35 | btnNo.addEventListener( 'click', function( event ) {
36 | btn.classList.remove( 'is-open' );
37 | } );
38 |
39 | function distance( x1, y1, x2, y2 ) {
40 | var dx = x1-x2;
41 | var dy = y1-y2;
42 | return Math.sqrt( dx*dx + dy*dy );
43 | }
44 |
45 | };
--------------------------------------------------------------------------------
/example/flipside/style.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Roboto:400,700);
2 | html, body {
3 | width: 100%;
4 | height: 100%;
5 | margin: 0;
6 | -webkit-user-select: none;
7 | -moz-user-select: none;
8 | -ms-user-select: none;
9 | user-select: none; }
10 |
11 | body {
12 | display: -ms-flexbox;
13 | display: flex;
14 | font-family: Roboto, "Helvetica Neue", sans-serif;
15 | font-size: 18px;
16 | perspective: 1000px;
17 | background-color: #f5f5f5;
18 | -ms-flex-direction: column;
19 | flex-direction: column;
20 | -ms-flex-pack: center;
21 | justify-content: center;
22 | -ms-flex-align: center;
23 | align-items: center; }
24 |
25 | .description {
26 | margin-top: 50px;
27 | text-align: center;
28 | color: #999;
29 | transition: opacity 0.3s ease; }
30 |
31 | .description a {
32 | color: #4A9DF6;
33 | text-decoration: none; }
34 |
35 | .btn.is-open ~ .description {
36 | opacity: 0; }
37 |
38 | .btn {
39 | display: block;
40 | position: relative;
41 | width: 200px;
42 | height: 80px;
43 | transition: width 0.8s cubic-bezier(0.23, 1, 0.32, 1), height 0.8s cubic-bezier(0.23, 1, 0.32, 1), transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275);
44 | transform-style: preserve-3d;
45 | transform-origin: 50% 50%;
46 | text-align: center; }
47 |
48 | .btn-front {
49 | position: absolute;
50 | display: block;
51 | width: 100%;
52 | height: 100%;
53 | line-height: 80px;
54 | background-color: #F44336;
55 | color: #fff;
56 | cursor: pointer;
57 | backface-visibility: hidden;
58 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
59 | transition: background 0.15s ease, line-height 0.8s cubic-bezier(0.23, 1, 0.32, 1); }
60 | .btn-front:hover {
61 | background-color: #f77066; }
62 |
63 | .btn-back {
64 | position: absolute;
65 | width: 100%;
66 | height: 100%;
67 | background-color: #eee;
68 | color: #222;
69 | transform: translateZ(-2px) rotateX(180deg);
70 | overflow: hidden;
71 | transition: box-shadow 0.8s ease; }
72 | .btn-back p {
73 | margin-top: 27px;
74 | margin-bottom: 25px; }
75 | .btn-back button {
76 | padding: 12px 20px;
77 | width: 30%;
78 | margin: 0 5px;
79 | background-color: transparent;
80 | border: 0;
81 | border-radius: 2px;
82 | font-size: 1em;
83 | cursor: pointer;
84 | -webkit-appearance: none;
85 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
86 | transition: background 0.15s ease; }
87 | .btn-back button:focus {
88 | outline: 0; }
89 | .btn-back button.yes {
90 | background-color: #2196F3;
91 | color: #fff; }
92 | .btn-back button.yes:hover {
93 | background-color: #51adf6; }
94 | .btn-back button.no {
95 | color: #2196F3; }
96 | .btn-back button.no:hover {
97 | background-color: #ddd; }
98 |
99 | .btn[data-direction="left"] .btn-back,
100 | .btn[data-direction="right"] .btn-back {
101 | transform: translateZ(-2px) rotateY(180deg); }
102 |
103 | .btn.is-open {
104 | width: 400px;
105 | height: 160px; }
106 | .btn.is-open .btn-front {
107 | pointer-events: none;
108 | line-height: 160px; }
109 | .btn.is-open .btn-back {
110 | box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4); }
111 |
112 | .btn[data-direction="top"].is-open {
113 | transform: rotateX(180deg); }
114 |
115 | .btn[data-direction="right"].is-open {
116 | transform: rotateY(180deg); }
117 |
118 | .btn[data-direction="bottom"].is-open {
119 | transform: rotateX(-180deg); }
120 |
121 | .btn[data-direction="left"].is-open {
122 | transform: rotateY(-180deg); }
123 |
--------------------------------------------------------------------------------
/example/flipside/style.scss:
--------------------------------------------------------------------------------
1 | $transition-duration: 0.8s;
2 | $transition-easing: cubic-bezier(0.230, 1.000, 0.320, 1.000);
3 | $bounce-easing: cubic-bezier(0.175, 0.885, 0.320, 1.275);
4 | $closed-width: 200px;
5 | $closed-height: 80px;
6 | $opened-width: 400px;
7 | $opened-height: 160px;
8 |
9 | @import url(https://fonts.googleapis.com/css?family=Roboto:400,700);
10 |
11 | html, body {
12 | width: 100%;
13 | height: 100%;
14 | margin: 0;
15 | user-select: none;
16 | }
17 |
18 | body {
19 | display: flex;
20 | font-family: Roboto, "Helvetica Neue", sans-serif;
21 | font-size: 18px;
22 | perspective: 1000px;
23 | background-color: #f5f5f5;
24 | flex-direction: column;
25 | justify-content: center;
26 | align-items: center;
27 | }
28 |
29 | .description {
30 | margin-top: 50px;
31 | text-align: center;
32 | color: #999;
33 | transition: opacity 0.3s ease;
34 | }
35 |
36 | .description a {
37 | color: #4A9DF6;
38 | text-decoration: none;
39 | }
40 |
41 | .btn.is-open ~ .description {
42 | opacity: 0;
43 | }
44 |
45 | .btn {
46 | display: block;
47 | position: relative;
48 | width: $closed-width;
49 | height: $closed-height;
50 | transition: width $transition-duration $transition-easing,
51 | height $transition-duration $transition-easing,
52 | transform $transition-duration $bounce-easing;
53 | transform-style: preserve-3d;
54 | transform-origin: 50% 50%;
55 | text-align: center;
56 | }
57 |
58 | .btn-front {
59 | position: absolute;
60 | display: block;
61 | width: 100%;
62 | height: 100%;
63 | line-height: $closed-height;
64 | background-color: #F44336;
65 | color: #fff;
66 | cursor: pointer;
67 | backface-visibility: hidden;
68 | -webkit-tap-highlight-color: rgba( 0, 0, 0, 0 );
69 | transition: background 0.15s ease,
70 | line-height $transition-duration $transition-easing;
71 |
72 | &:hover {
73 | background-color: lighten(#F44336, 10%);
74 | }
75 | }
76 |
77 | .btn-back {
78 | position: absolute;
79 | width: 100%;
80 | height: 100%;
81 | background-color: #eee;
82 | color: #222;
83 | transform: translateZ(-2px) rotateX(180deg);
84 | overflow: hidden;
85 | transition: box-shadow $transition-duration ease;
86 |
87 | p {
88 | margin-top: 27px;
89 | margin-bottom: 25px;
90 | }
91 |
92 | button {
93 | padding: 12px 20px;
94 | width: 30%;
95 | margin: 0 5px;
96 | background-color: transparent;
97 | border: 0;
98 | border-radius: 2px;
99 | font-size: 1em;
100 | cursor: pointer;
101 | -webkit-appearance: none;
102 | -webkit-tap-highlight-color: rgba( 0, 0, 0, 0 );
103 | transition: background 0.15s ease;
104 | }
105 |
106 | button:focus {
107 | outline: 0;
108 | }
109 |
110 | button.yes {
111 | background-color: #2196F3;
112 | color: #fff;
113 |
114 | &:hover {
115 | background-color: lighten(#2196F3, 10%);
116 | }
117 | }
118 |
119 | button.no {
120 | color: #2196F3;
121 |
122 | &:hover {
123 | background-color: #ddd;
124 | }
125 | }
126 | }
127 |
128 | .btn[data-direction="left"] .btn-back,
129 | .btn[data-direction="right"] .btn-back {
130 | transform: translateZ(-2px) rotateY(180deg);
131 | }
132 |
133 | .btn.is-open {
134 | width: $opened-width;
135 | height: $opened-height;
136 |
137 | .btn-front {
138 | pointer-events: none;
139 | line-height: $opened-height;
140 | }
141 |
142 | .btn-back {
143 | box-shadow: 0 8px 25px rgba(0,0,0,0.4);
144 | }
145 | }
146 |
147 | .btn[data-direction="top"].is-open {
148 | transform: rotateX(180deg);
149 | }
150 |
151 | .btn[data-direction="right"].is-open {
152 | transform: rotateY(180deg);
153 | }
154 |
155 | .btn[data-direction="bottom"].is-open {
156 | transform: rotateX(-180deg);
157 | }
158 |
159 | .btn[data-direction="left"].is-open {
160 | transform: rotateY(-180deg);
161 | }
162 |
--------------------------------------------------------------------------------
/example/monocle/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Monocle
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
136 |
137 |
138 |
139 |
140 |
141 |
146 |
147 |
188 |
189 |
199 |
200 |
201 |
202 |
--------------------------------------------------------------------------------
/example/monocle/script.js:
--------------------------------------------------------------------------------
1 | window.onload = () => {
2 |
3 | const wrapper = document.querySelector( '.page-wrapper' );
4 |
5 | const originalList = document.querySelector( '.list-wrapper' );
6 | const originalListItems = originalList.innerHTML;
7 | originalList.parentNode.removeChild( originalList );
8 |
9 | // Top list
10 | const listA = document.createElement( 'div' );
11 | listA.className = 'list-wrapper list-a';
12 | listA.innerHTML = originalListItems;
13 | wrapper.appendChild( listA );
14 |
15 | // Monocle list
16 | const listB = document.createElement( 'div' );
17 | listB.className = 'list-wrapper list-b';
18 | listB.innerHTML = originalListItems;
19 | wrapper.appendChild( listB );
20 |
21 | // Bottom list
22 | const listC = document.createElement( 'div' );
23 | listC.className = 'list-wrapper list-c';
24 | listC.innerHTML = originalListItems;
25 | wrapper.appendChild( listC );
26 |
27 | const listAInner = listA.querySelector( '.list' );
28 | const listCInner = listC.querySelector( '.list' );
29 | const listBInner = listB.querySelector( '.list' );
30 |
31 | const rowHeight = listA.querySelector( '.list-item' ).offsetHeight;
32 | const listAScrollheight = listAInner.scrollHeight;
33 | const listBScrollheight = listBInner.scrollHeight;
34 |
35 | let listAHeight = 0,
36 | listBHeight = rowHeight * 2,
37 | listCHeight = 0;
38 |
39 | let scrollPosition = 0;
40 |
41 | function init() {
42 |
43 | window.addEventListener( 'resize', layout );
44 | window.addEventListener( 'scroll', syncScrollPosition );
45 |
46 | wrapper.style.visibility = '';
47 |
48 | layout();
49 |
50 | syncScrollPosition();
51 |
52 | }
53 |
54 | function layout() {
55 |
56 | let height = window.innerHeight;
57 |
58 | listAHeight = ( height - listBHeight ) / 2;
59 | listAHeight = Math.floor( listAHeight / rowHeight ) * rowHeight;
60 |
61 | listCHeight = height - ( listAHeight + listBHeight );
62 |
63 | listA.style.height = listAHeight + 'px';
64 | listB.style.height = listBHeight + 'px';
65 | listB.style.top = listAHeight + 'px';
66 | listC.style.height = listCHeight + 'px';
67 |
68 | sync();
69 |
70 | }
71 |
72 | function sync() {
73 |
74 | listAInner.style.top = ( listAHeight + ( -scrollPosition * ( listAScrollheight ) ) ) + 'px';
75 | listBInner.style.top = ( -scrollPosition * ( listBScrollheight - listBHeight ) ) + 'px';
76 | listCInner.style.top = ( -scrollPosition * listAScrollheight ) + 'px';
77 |
78 | }
79 |
80 | function syncScrollPosition( event ) {
81 |
82 | let scrollRange = document.documentElement.scrollHeight - document.documentElement.offsetHeight;
83 |
84 | scrollPosition = window.scrollY / scrollRange;
85 | scrollPosition = Math.max( 0, Math.min( 1, scrollPosition ) );
86 |
87 | sync();
88 |
89 | }
90 |
91 | init();
92 |
93 | };
--------------------------------------------------------------------------------
/example/monocle/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0; }
5 |
6 | html, body {
7 | height: 100%;
8 | width: 100%;
9 | font-family: 'Roboto', Helvetica, sans-serif;
10 | background-color: #222;
11 | color: #222; }
12 |
13 | html {
14 | overflow: auto; }
15 |
16 | body {
17 | height: 500%; }
18 |
19 | .page-wrapper {
20 | position: fixed;
21 | width: 840px;
22 | height: 100%;
23 | left: 50%;
24 | top: 0;
25 | margin-left: -420px;
26 | font-size: 16px;
27 | z-index: 2; }
28 |
29 | .list-wrapper {
30 | position: absolute;
31 | width: 100%;
32 | height: 100%;
33 | overflow: hidden; }
34 |
35 | .list {
36 | position: relative;
37 | width: 420px;
38 | margin: 0 auto;
39 | padding: 0;
40 | list-style: none; }
41 | .list .list-item {
42 | width: 100%;
43 | height: 150px;
44 | padding: 2.1em 1em;
45 | display: flex;
46 | flex-direction: row;
47 | align-items: center;
48 | background-color: #eee;
49 | color: inherit;
50 | text-decoration: none;
51 | cursor: default; }
52 | .list .list-item:nth-child(even) {
53 | background-color: #e5e5e5; }
54 | .list .list-item:nth-child(odd) {
55 | background-color: #f5f5f5; }
56 | .list .list-item:first-child {
57 | border-top-left-radius: 6px;
58 | border-top-right-radius: 6px; }
59 | .list .list-item:last-child {
60 | border-bottom-left-radius: 6px;
61 | border-bottom-right-radius: 6px; }
62 | .list .project-figure {
63 | width: 30%;
64 | flex-shrink: 0;
65 | margin-right: 1em; }
66 | .list .project-figure img {
67 | display: block;
68 | max-width: 100%;
69 | max-height: 100%; }
70 | .list h3 {
71 | margin-bottom: 4px; }
72 | .list h3, .list img, .list p {
73 | cursor: pointer; }
74 |
75 | .list-a {
76 | top: 0; }
77 | .list-a .list-item:last-child {
78 | display: none; }
79 |
80 | .list-b {
81 | z-index: 10;
82 | font-size: 2em;
83 | box-shadow: 0 0 30px rgba(0, 0, 0, 0.6);
84 | border-radius: 6px; }
85 | .list-b .list {
86 | width: 840px; }
87 | .list-b .list-item {
88 | height: 300px; }
89 |
90 | .list-c {
91 | bottom: 0; }
92 | .list-c .list-item:first-child {
93 | display: none; }
94 |
--------------------------------------------------------------------------------
/example/monocle/style.scss:
--------------------------------------------------------------------------------
1 | $textColor: #222;
2 | $rowWidth: 420px;
3 | $rowHeight: 150px;
4 | $rounding: 6px;
5 |
6 | * {
7 | box-sizing: border-box;
8 | margin: 0;
9 | padding: 0;
10 | }
11 |
12 | html, body {
13 | height: 100%;
14 | width: 100%;
15 | font-family: 'Roboto', Helvetica, sans-serif;
16 | background-color: #222;
17 | color: $textColor;
18 | }
19 |
20 | html {
21 | overflow: auto;
22 | }
23 |
24 | body {
25 | height: 500%;
26 | }
27 |
28 | .page-wrapper {
29 | position: fixed;
30 | width: $rowWidth * 2;
31 | height: 100%;
32 | left: 50%;
33 | top: 0;
34 | margin-left: -$rowWidth;
35 | font-size: 16px;
36 | z-index: 2;
37 | }
38 |
39 | .list-wrapper {
40 | position: absolute;
41 | width: 100%;
42 | height: 100%;
43 | overflow: hidden;
44 | }
45 |
46 | .list {
47 | position: relative;
48 | width: $rowWidth;
49 | margin: 0 auto;
50 | padding: 0;
51 | list-style: none;
52 |
53 | .list-item {
54 | width: 100%;
55 | height: $rowHeight;
56 | padding: 2.1em 1em;
57 | display: flex;
58 | flex-direction: row;
59 | align-items: center;
60 | background-color: #eee;
61 | color: inherit;
62 | text-decoration: none;
63 | cursor: default;
64 | }
65 |
66 | .list-item:nth-child(even) {
67 | background-color: #e5e5e5;
68 | }
69 | .list-item:nth-child(odd) {
70 | background-color: #f5f5f5;
71 | }
72 |
73 | .list-item:first-child {
74 | border-top-left-radius: $rounding;
75 | border-top-right-radius: $rounding;
76 | }
77 |
78 | .list-item:last-child {
79 | border-bottom-left-radius: $rounding;
80 | border-bottom-right-radius: $rounding;
81 | }
82 |
83 | .project-figure {
84 | width: 30%;
85 | flex-shrink: 0;
86 | margin-right: 1em;
87 | }
88 |
89 | .project-figure img {
90 | display: block;
91 | max-width: 100%;
92 | max-height: 100%;
93 | }
94 |
95 | h3 {
96 | margin-bottom: 4px;
97 | }
98 |
99 | h3, img, p {
100 | cursor: pointer;
101 | }
102 | }
103 |
104 | .list-a {
105 | top: 0;
106 |
107 | .list-item:last-child {
108 | display: none;
109 | }
110 | }
111 |
112 | .list-b {
113 | z-index: 10;
114 | font-size: 2em;
115 | box-shadow: 0 0 30px rgba( 0, 0, 0, 0.6 );
116 | border-radius: $rounding;
117 |
118 | .list {
119 | width: $rowWidth * 2;
120 | }
121 |
122 | .list-item {
123 | height: $rowHeight * 2;
124 | }
125 | }
126 |
127 | .list-c {
128 | bottom: 0;
129 |
130 | .list-item:first-child {
131 | display: none;
132 | }
133 | }
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css",
3 | "version": "0.0.1",
4 | "description": "Assorted CSS and UI experiments",
5 | "homepage": "http://lab.hakim.se/",
6 | "author": {
7 | "name": "Hakim El Hattab",
8 | "email": "hakim.elhattab@gmail.com",
9 | "web": "http://hakim.se"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git://github.com/hakimel/css.js.git"
14 | },
15 | "dependencies": {},
16 | "devDependencies": {
17 | "grunt-contrib-jshint": "~0.11.3",
18 | "grunt-contrib-cssmin": "~0.14.0",
19 | "grunt-contrib-uglify": "~0.9.2",
20 | "grunt-contrib-watch": "~0.6.1",
21 | "grunt-contrib-connect": "~0.11.2",
22 | "grunt-autoprefixer": "~3.0.3",
23 | "grunt-sass": "~3.1.0",
24 | "node-sass": "~4.13.1",
25 | "grunt": "~1.0.1"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/example/progress-nav/script.js:
--------------------------------------------------------------------------------
1 | window.onload = function() {
2 |
3 | var toc = document.querySelector( '.toc' );
4 | var tocPath = document.querySelector( '.toc-marker path' );
5 | var tocItems;
6 |
7 | // Factor of screen size that the element must cross
8 | // before it's considered visible
9 | var TOP_MARGIN = 0.1,
10 | BOTTOM_MARGIN = 0.2;
11 |
12 | var pathLength;
13 |
14 | var lastPathStart,
15 | lastPathEnd;
16 |
17 | window.addEventListener( 'resize', drawPath, false );
18 | window.addEventListener( 'scroll', sync, false );
19 |
20 | drawPath();
21 |
22 | function drawPath() {
23 |
24 | tocItems = [].slice.call( toc.querySelectorAll( 'li' ) );
25 |
26 | // Cache element references and measurements
27 | tocItems = tocItems.map( function( item ) {
28 | var anchor = item.querySelector( 'a' );
29 | var target = document.getElementById( anchor.getAttribute( 'href' ).slice( 1 ) );
30 |
31 | return {
32 | listItem: item,
33 | anchor: anchor,
34 | target: target
35 | };
36 | } );
37 |
38 | // Remove missing targets
39 | tocItems = tocItems.filter( function( item ) {
40 | return !!item.target;
41 | } );
42 |
43 | var path = [];
44 | var pathIndent;
45 |
46 | tocItems.forEach( function( item, i ) {
47 |
48 | var x = item.anchor.offsetLeft - 5,
49 | y = item.anchor.offsetTop,
50 | height = item.anchor.offsetHeight;
51 |
52 | if( i === 0 ) {
53 | path.push( 'M', x, y, 'L', x, y + height );
54 | item.pathStart = 0;
55 | }
56 | else {
57 | // Draw an additional line when there's a change in
58 | // indent levels
59 | if( pathIndent !== x ) path.push( 'L', pathIndent, y );
60 |
61 | path.push( 'L', x, y );
62 |
63 | // Set the current path so that we can measure it
64 | tocPath.setAttribute( 'd', path.join( ' ' ) );
65 | item.pathStart = tocPath.getTotalLength() || 0;
66 |
67 | path.push( 'L', x, y + height );
68 | }
69 |
70 | pathIndent = x;
71 |
72 | tocPath.setAttribute( 'd', path.join( ' ' ) );
73 | item.pathEnd = tocPath.getTotalLength();
74 |
75 | } );
76 |
77 | pathLength = tocPath.getTotalLength();
78 |
79 | sync();
80 |
81 | }
82 |
83 | function sync() {
84 |
85 | var windowHeight = window.innerHeight;
86 |
87 | var pathStart = pathLength,
88 | pathEnd = 0;
89 |
90 | var visibleItems = 0;
91 |
92 | tocItems.forEach( function( item ) {
93 |
94 | var targetBounds = item.target.getBoundingClientRect();
95 |
96 | if( targetBounds.bottom > windowHeight * TOP_MARGIN && targetBounds.top < windowHeight * ( 1 - BOTTOM_MARGIN ) ) {
97 | pathStart = Math.min( item.pathStart, pathStart );
98 | pathEnd = Math.max( item.pathEnd, pathEnd );
99 |
100 | visibleItems += 1;
101 |
102 | item.listItem.classList.add( 'visible' );
103 | }
104 | else {
105 | item.listItem.classList.remove( 'visible' );
106 | }
107 |
108 | } );
109 |
110 | // Specify the visible path or hide the path altogether
111 | // if there are no visible items
112 | if( visibleItems > 0 && pathStart < pathEnd ) {
113 | if( pathStart !== lastPathStart || pathEnd !== lastPathEnd ) {
114 | tocPath.setAttribute( 'stroke-dashoffset', '1' );
115 | tocPath.setAttribute( 'stroke-dasharray', '1, '+ pathStart +', '+ ( pathEnd - pathStart ) +', ' + pathLength );
116 | tocPath.setAttribute( 'opacity', 1 );
117 | }
118 | }
119 | else {
120 | tocPath.setAttribute( 'opacity', 0 );
121 | }
122 |
123 | lastPathStart = pathStart;
124 | lastPathEnd = pathEnd;
125 |
126 | }
127 |
128 | };
--------------------------------------------------------------------------------
/example/progress-nav/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box; }
3 |
4 | body {
5 | width: 100vw;
6 | height: 100vh;
7 | overflow: auto; }
8 |
9 | body {
10 | padding: 1em 2em 2em 17em;
11 | font-size: 16px;
12 | line-height: 1.6;
13 | font-family: 'Roboto', sans-serif; }
14 |
15 | .toc {
16 | position: fixed;
17 | left: 3em;
18 | top: 5em;
19 | padding: 1em;
20 | width: 14em;
21 | line-height: 2; }
22 | .toc ul {
23 | list-style: none;
24 | padding: 0;
25 | margin: 0; }
26 | .toc ul ul {
27 | padding-left: 2em; }
28 | .toc li a {
29 | display: inline-block;
30 | color: #aaa;
31 | text-decoration: none;
32 | transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1); }
33 | .toc li.visible > a {
34 | color: #111;
35 | transform: translate(5px); }
36 |
37 | .toc-marker {
38 | position: absolute;
39 | top: 0;
40 | left: 0;
41 | width: 100%;
42 | height: 100%;
43 | z-index: -1; }
44 | .toc-marker path {
45 | transition: all 0.3s ease; }
46 |
47 | .contents {
48 | padding: 1em;
49 | max-width: 800px;
50 | font-size: 1.2em;
51 | font-family: 'Frank Ruhl Libre', sans-serif; }
52 | .contents img {
53 | max-width: 100%; }
54 | .contents .code-block {
55 | white-space: pre;
56 | overflow: auto;
57 | max-width: 100%; }
58 | .contents .code-block code {
59 | display: block;
60 | background-color: #f9f9f9;
61 | padding: 10px; }
62 | .contents .code-inline {
63 | background-color: #f9f9f9;
64 | padding: 4px; }
65 | .contents h2
66 | h3 {
67 | padding-top: 1em; }
68 | .contents h2 {
69 | margin-top: 1.2em; }
70 |
71 | @media screen and (max-width: 1200px) {
72 | body {
73 | font-size: 14px; } }
74 |
--------------------------------------------------------------------------------
/example/progress-nav/style.scss:
--------------------------------------------------------------------------------
1 | $menuWidth: 14em;
2 | $menuPaddingLeft: 3em;
3 |
4 | * {
5 | box-sizing: border-box;
6 | }
7 |
8 | body {
9 | width: 100vw;
10 | height: 100vh;
11 | overflow: auto;
12 | }
13 |
14 | body {
15 | padding: 1em 2em 2em $menuWidth+$menuPaddingLeft;
16 | font-size: 16px;
17 | line-height: 1.6;
18 |
19 | font-family: 'Roboto', sans-serif;
20 | }
21 |
22 | .toc {
23 | position: fixed;
24 | left: $menuPaddingLeft;
25 | top: 5em;
26 | padding: 1em;
27 | width: $menuWidth;
28 | line-height: 2;
29 |
30 | ul {
31 | list-style: none;
32 | padding: 0;
33 | margin: 0;
34 | }
35 |
36 | ul ul {
37 | padding-left: 2em;
38 | }
39 |
40 | li a {
41 | display: inline-block;
42 | color: #aaa;
43 | text-decoration: none;
44 | transition: all 0.3s cubic-bezier(0.230, 1.000, 0.320, 1.000);
45 | }
46 |
47 | li.visible>a {
48 | color: #111;
49 | transform: translate( 5px );
50 | }
51 | }
52 |
53 | .toc-marker {
54 | position: absolute;
55 | top: 0;
56 | left: 0;
57 | width: 100%;
58 | height: 100%;
59 | z-index: -1;
60 |
61 | path {
62 | transition: all 0.3s ease;
63 | }
64 | }
65 |
66 | .contents {
67 | padding: 1em;
68 | max-width: 800px;
69 | font-size: 1.2em;
70 | font-family: 'Frank Ruhl Libre', sans-serif;
71 |
72 | img {
73 | max-width: 100%;
74 | }
75 |
76 | .code-block {
77 | white-space: pre;
78 | overflow: auto;
79 | max-width: 100%;
80 |
81 | code {
82 | display: block;
83 | background-color: #f9f9f9;
84 | padding: 10px;
85 | }
86 | }
87 |
88 | .code-inline {
89 | background-color: #f9f9f9;
90 | padding: 4px;
91 | }
92 |
93 | h2
94 | h3 {
95 | padding-top: 1em;
96 | }
97 |
98 |
99 | h2 {
100 | margin-top: 1.2em;
101 | }
102 | }
103 |
104 |
105 | @media screen and (max-width: 1200px) {
106 |
107 | body {
108 | font-size: 14px;
109 | }
110 |
111 | }
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require("gulp");
2 | var sass = require("gulp-sass")(require("sass"));
3 | var postcss = require("gulp-postcss");
4 | var cssvariables = require("postcss-css-variables");
5 | var cleanCSS = require("gulp-clean-css");
6 | var autoprefixer = require("autoprefixer");
7 | var rename = require("gulp-rename");
8 | var wait = require("gulp-wait");
9 | var merge = require("merge2");
10 | var concat = require("gulp-concat");
11 | var uglify = require("gulp-uglify");
12 | var jshint = require("gulp-jshint");
13 | // 错误处理
14 | var plumber = require("gulp-plumber");
15 | var stylish = require("jshint-stylish");
16 |
17 | var del = require("del");
18 | var zip = require("gulp-zip");
19 | var beautify = require("gulp-jsbeautifier");
20 | var browserSync = require("browser-sync").create();
21 |
22 | gulp.task("beautify", () =>
23 | gulp.src(["./*.css", "./*.html", "./*.js"]).pipe(beautify())
24 | );
25 |
26 | // JS检查
27 | gulp.task("lint", function () {
28 | return gulp
29 | .src("./assets/js/index.js")
30 | .pipe(jshint())
31 | .pipe(jshint.reporter("default"));
32 | });
33 |
34 | gulp.task("css", function () {
35 | var sassStream = gulp
36 | .src("./assets/scss/screen.scss")
37 | .pipe(plumber())
38 | .pipe(wait(100))
39 | .pipe(sass({ outputStyle: "expanded" }).on("error", sass.logError))
40 | .pipe(postcss([autoprefixer(), cssvariables({ preserve: true })]));
41 | var cssStream = gulp
42 | .src(
43 | [
44 | "./assets/css/bootstrap.min.css",
45 | "./assets/css/hl-styles/atom-one-dark.min.css",
46 | ],
47 | { allowEmpty: true }
48 | )
49 | .pipe(concat("css-files.css"));
50 | return merge(cssStream, sassStream)
51 | .pipe(concat("app.bundle.min.css"))
52 | .pipe(
53 | cleanCSS({
54 | level: { 1: { specialComments: 0 } },
55 | compatibility: "ie9",
56 | })
57 | )
58 | .pipe(rename("bundle-css.hbs"))
59 | .pipe(gulp.dest("./partials/styles"))
60 | .pipe(browserSync.stream());
61 | });
62 |
63 | gulp.task("ampcss", function () {
64 | return gulp
65 | .src([
66 | "./assets/scss/ampstyle-light.scss",
67 | "./assets/scss/ampstyle-dark.scss",
68 | ])
69 | .pipe(plumber())
70 | .pipe(wait(100))
71 | .pipe(sass({ outputStyle: "expanded" }).on("error", sass.logError))
72 | .pipe(postcss([autoprefixer(), cssvariables()]))
73 | .pipe(
74 | cleanCSS({
75 | level: { 1: { specialComments: 0 } },
76 | compatibility: "ie9",
77 | })
78 | )
79 | .pipe(rename({ extname: ".hbs" }))
80 | .pipe(gulp.dest("./partials/styles"));
81 | });
82 |
83 | gulp.task("concat-js", function () {
84 | return gulp
85 | .src(
86 | [
87 | "./assets/js/vendor/jquery-3.5.1.min.js",
88 | "./assets/js/vendor/jquery.fitvids.js",
89 | // './assets/js/vendor/highlight.pack.js',
90 | "./assets/js/vendor/fuse.min.js",
91 | "./assets/js/vendor/medium-zoom.min.js",
92 | "./assets/js/vendor/clipboard.min.js",
93 | "./assets/js/vendor/jquery.disqusloader.js",
94 | "./assets/js/vendor/jquery.toc.js",
95 | "./assets/js/vendor/lazy.js",
96 | "./assets/js/vendor/prism.js",
97 | "./assets/js/index.js",
98 | ],
99 | { allowEmpty: true }
100 | )
101 | .pipe(plumber())
102 | .pipe(concat("app.bundle.min.js"))
103 | .pipe(
104 | uglify({
105 | compress: {
106 | drop_console: true,
107 | },
108 | })
109 | ) // 压缩成一行
110 | .pipe(gulp.dest("./assets/js"));
111 | });
112 |
113 | gulp.task(
114 | "watch",
115 | gulp.series("css", "ampcss", "concat-js", function () {
116 | browserSync.init({
117 | proxy: "http://localhost:2368",
118 | });
119 | gulp
120 | .watch(
121 | [
122 | "./assets/scss/**/*.scss",
123 | "!./assets/scss/ampstyle-light.scss",
124 | "!./assets/scss/ampstyle-dark.scss",
125 | ],
126 | { allowEmpty: true }
127 | )
128 | .on("change", gulp.series("css"));
129 | gulp
130 | .watch([
131 | "./assets/scss/ampstyle-light.scss",
132 | "./assets/scss/ampstyle-dark.scss",
133 | ])
134 | .on("change", gulp.series("ampcss"));
135 | gulp
136 | .watch(["./assets/js/**/*.js", "!./assets/js/app.bundle.min.js"], {
137 | allowEmpty: true,
138 | })
139 | .on("change", gulp.series("concat-js", browserSync.reload));
140 | gulp.watch("./**/*.hbs").on("change", browserSync.reload);
141 | })
142 | );
143 |
144 | gulp.task("clean", function () {
145 | return del(["./build", "./dist"]);
146 | });
147 |
148 | gulp.task(
149 | "build",
150 | gulp.series("clean", "lint", "css", "concat-js", function () {
151 | var targetDir = "build/";
152 |
153 | return gulp
154 | .src([
155 | "**",
156 | "!assets/scss",
157 | "!assets/scss/**/*",
158 | "!assets/css",
159 | "!assets/css/**/*",
160 | "assets/js/**",
161 | "!assets/js/vendor",
162 | "!assets/js/vendor/**/*",
163 | "!node_modules",
164 | "!node_modules/**",
165 | "!build",
166 | "!build/**",
167 | "!dist",
168 | "!dist/**",
169 | ])
170 | .pipe(gulp.dest(targetDir));
171 | })
172 | );
173 |
174 | gulp.task("zip", function () {
175 | var targetDir = "dist/";
176 | var themeName = require("./package.json").name;
177 | var filename = themeName + ".zip";
178 |
179 | return gulp
180 | .src(["./build/**/*"])
181 | .pipe(zip(filename))
182 | .pipe(gulp.dest(targetDir));
183 | });
184 |
185 | gulp.task("upload", gulp.series("clean", "build", "zip"));
186 |
187 | gulp.task("default", gulp.parallel("watch"));
188 |
--------------------------------------------------------------------------------
/index.hbs:
--------------------------------------------------------------------------------
1 | {{!< default}}
2 | {{! The tag above means - insert everything in this file into the {body} of the default.hbs template }}
3 |
4 |
5 | {{> loop}}
6 |
7 | {{pagination}}
8 |
9 |
--------------------------------------------------------------------------------
/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "0 Post": "0 Post",
3 | "1 Post": "1 Post",
4 | "% Posts": "% Posts",
5 | "Maybe the URL is incorrect, or the page no longer exist.": "Maybe the URL is incorrect, or the page no longer exist.",
6 | "Theme errors": "Theme errors",
7 | "Ref:": "Ref:",
8 | "Message:": "Message:",
9 | "Published in:": "Published in:",
10 | "with the email address": "with the email address",
11 | "Take me back": "Take me back",
12 | "Published with {ghostLink}": "Published with {ghostLink}",
13 | "Toggle Theme": "Toggle Theme",
14 | "featured": "featured",
15 | "1 min read": "1 min read",
16 | "% min read": "% min read",
17 | "Previous Post": "Previous Post",
18 | "Next Post": "Next Post",
19 | "Type to search": "Type to search",
20 | "Share this article": "Share this article",
21 | "Share on Facebook": "Share on Facebook",
22 | "Share on Twitter": "Share on Twitter",
23 | "Share on Linkedin": "Share on Linkedin",
24 | "Share on Pinterest": "Share on Pinterest",
25 | "Permalink": "Permalink",
26 | "Get the permalink": "Get the permalink",
27 | "Link Copied to clipboard": "Link Copied to clipboard",
28 | "Follow me on": "Follow me on",
29 | "Subscribe": "Subscribe",
30 | "Join my newsletter": "Join my newsletter",
31 | "I send posts digest once in a month. No spam ever, I promise.": "I send posts digest once in a month. No spam ever, I promise.",
32 | "This post was collaboration between the following authors": "This post was collaboration between the following authors",
33 | "Load More": "Load More",
34 | "That's all. No more posts to display.": "That's all. No more posts to display.",
35 | "Account": "Account",
36 | "Sign out": "Sign out",
37 | "Sign in": "Sign in",
38 | "Sign up": "Sign up",
39 | "You've successfully subscribed to": "You've successfully subscribed to",
40 | "Great! Next, complete checkout for full access to": "Great! Next, complete checkout for full access to",
41 | "Welcome back! You've successfully signed in.": "Welcome back! You've successfully signed in.",
42 | "Success! Your account is fully activated, you now have access to all content.": "Success! Your account is fully activated, you now have access to all content.",
43 | "Free": "Free",
44 | "0": "0",
45 | "Forever": "Forever",
46 | "Subscribe now": "Subscribe now",
47 | "Monthly": "Monthly",
48 | "/ Month": "/ Month",
49 | "Yearly": "Yearly",
50 | "/ Year": "/ Year",
51 | "You don't have access to this post on": "You don't have access to this post on",
52 | "at the moment, but if you upgrade your account you'll be able to see the whole thing, as well as all the other posts in the archive! Subscribing only takes a few seconds and will give you immediate access.": "at the moment, but if you upgrade your account you'll be able to see the whole thing, as well as all the other posts in the archive! Subscribing only takes a few seconds and will give you immediate access.",
53 | "This post is for paying subscribers only": "This post is for paying subscribers only",
54 | "This post is for subscribers only": "This post is for subscribers only",
55 | "Already have an account?": "Already have an account?",
56 | "Welcome back!": "Welcome back!",
57 | "Sign into your account again for full access": "Sign into your account again for full access",
58 | "Your email address": "Your email address",
59 | "Send login link": "Send login link",
60 | "Great!": "Great!",
61 | "Check your inbox and click the link to complete sign in.": "Check your inbox and click the link to complete sign in.",
62 | "Error!": "Error!",
63 | "Please enter a valid email address!": "Please enter a valid email address!",
64 | "Don't have an account yet?": "Don't have an account yet?",
65 | "Sign up to": "Sign up to",
66 | "free plan!": "free plan!",
67 | "Signup to access free members only articles": "Signup to access free members only articles",
68 | "Check your inbox and click the link to complete sign up.": "Check your inbox and click the link to complete sign up.",
69 | "Choose your subscription plan": "Choose your subscription plan",
70 | "Unlock full access to": "Unlock full access to",
71 | "and see the entire library of members-only content & updates": "and see the entire library of members-only content & updates",
72 | "Nice, you're a paid subscriber!": "Nice, you're a paid subscriber!",
73 | "Hey! You are currently logged in with": "Hey! You are currently logged in with",
74 | "You have an active": "You have an active",
75 | "account with access to all areas.": "account with access to all areas.",
76 | "You're all set, but if you need any help, get in touch with us and we'd be happy to help.": "You're all set, but if you need any help, get in touch with us and we'd be happy to help.",
77 | "Return to home page": "Return to home page",
78 | "Nice, you're a subscriber!": "Nice, you're a subscriber!",
79 | "You have subscribed to free updates from": "You have subscribed to free updates from",
80 | "Subscribe to paid plan to unlock full access.": "Subscribe to paid plan to unlock full access."
81 | }
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/halfrost/Prometheus/b09016e8015685116602bd58435e18d518223c9b/logo.png
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "冰霜之地",
3 | "name": "Halfrost's Field | 冰霜之地",
4 | "icons": [
5 | {
6 | "src": "assets/images/apple-icon.png",
7 | "sizes": "180x180",
8 | "type": "image/png",
9 | "density": "3.0",
10 | "purpose": "any maskable"
11 | },
12 | {
13 | "src": "assets/images/apple-touch-icon.png",
14 | "sizes": "60x60",
15 | "type": "image/png",
16 | "purpose": "any maskable"
17 | },
18 | {
19 | "src": "assets/images/apple-touch-icon-76x76.png",
20 | "sizes": "76x76",
21 | "type": "image/png",
22 | "purpose": "any maskable"
23 | },
24 | {
25 | "src": "assets/images/apple-touch-icon-120x120.png",
26 | "sizes": "120x120",
27 | "type": "image/png",
28 | "purpose": "any maskable"
29 | },
30 | {
31 | "src": "assets/images/apple-touch-icon-152x152.png",
32 | "sizes": "152x152",
33 | "type": "image/png",
34 | "purpose": "any maskable"
35 | },
36 | {
37 | "src": "assets/images/favicon.png",
38 | "sizes": "1024x1024",
39 | "type": "image/png",
40 | "purpose": "any maskable"
41 | }
42 | ],
43 | "start_url": "/",
44 | "display": "standalone",
45 | "orientation": "portrait",
46 | "background_color": "#FFFFFF",
47 | "theme_color": "#FFFFFF"
48 | }
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "prometheus",
3 | "description": "Minimal personal blog theme",
4 | "demo": "http://advant.gbjsolution.com",
5 | "homepage": "https://halfrost.com",
6 | "version": "5.0.0",
7 | "engines": {
8 | "ghost": ">=4.0.0"
9 | },
10 | "screenshots": {
11 | "desktop": "assets/screenshot-desktop.jpg",
12 | "mobile": "assets/screenshot-mobile.jpg"
13 | },
14 | "author": {
15 | "name": "GBJ solution",
16 | "email": "gbjsolution@gmail.com",
17 | "url": "https://gbjsolution.com"
18 | },
19 | "gpm": {
20 | "type": "theme",
21 | "categories": [
22 | "Minimal",
23 | "Personal Blogs",
24 | "Magazine Layouts"
25 | ]
26 | },
27 | "keywords": [
28 | "ghost",
29 | "theme",
30 | "ghost-theme",
31 | "personal",
32 | "minimal"
33 | ],
34 | "config": {
35 | "posts_per_page": 6,
36 | "card_assets": {
37 | "exclude": [
38 | "bookmark",
39 | "gallery"
40 | ]
41 | },
42 | "image_sizes": {
43 | "s": {
44 | "width": 300
45 | },
46 | "m": {
47 | "width": 600
48 | },
49 | "l": {
50 | "width": 1000
51 | },
52 | "xl": {
53 | "width": 2000
54 | }
55 | }
56 | },
57 | "devDependencies": {
58 | "autoprefixer": "^9.8.5",
59 | "browser-sync": "^2.26.14",
60 | "del": "^4.1.1",
61 | "gulp": "^4.0.2",
62 | "gulp-clean-css": "^4.3.0",
63 | "gulp-concat": "^2.6.1",
64 | "gulp-jsbeautifier": "^3.0.1",
65 | "gulp-jshint": "^2.1.0",
66 | "gulp-plumber": "^1.2.1",
67 | "gulp-postcss": "^8.0.0",
68 | "gulp-rename": "^1.4.0",
69 | "gulp-sass": "^5.1.0",
70 | "gulp-uglify": "^3.0.2",
71 | "gulp-wait": "0.0.2",
72 | "gulp-zip": "^5.0.2",
73 | "jshint": "^2.11.1",
74 | "jshint-stylish": "^2.2.1",
75 | "merge2": "^1.4.1",
76 | "postcss-css-variables": "^0.13.0",
77 | "sass": "^1.77.1"
78 | },
79 | "dependencies": {
80 | "localtunnel": "^2.0.1"
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/page.hbs:
--------------------------------------------------------------------------------
1 | {{!< default}}
2 | {{! The tag above means - insert everything in this file into the {body} of the default.hbs template }}
3 | {{#post}}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
16 |
17 | {{content}}
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | {{/post}}
26 |
--------------------------------------------------------------------------------
/partials/about-author.hbs:
--------------------------------------------------------------------------------
1 | {{#has author="count:>1"}}{{t "This post was collaboration between the following authors"}}
{{/has}}
2 |
3 | {{#foreach authors}}
4 |
5 |
6 | {{#if profile_image}}
7 |
8 | {{else}}
9 |
{{> icons/user}}
10 | {{/if}}
11 |
12 |
13 |
14 |
15 |
16 | {{{bio}}}
17 |
18 |
19 |
20 |
21 | {{/foreach}}
22 |
--------------------------------------------------------------------------------
/partials/api-key.hbs:
--------------------------------------------------------------------------------
1 | b9128c11336148e47e60317d83
--------------------------------------------------------------------------------
/partials/disqus-comment.hbs:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/partials/footer-simple.hbs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/partials/header.hbs:
--------------------------------------------------------------------------------
1 | {{!--