Initial commit, patched theme and main pages

This commit is contained in:
OctoSpacc 2023-12-02 23:00:23 +01:00
commit e4461a0b6f
181 changed files with 27306 additions and 0 deletions

14
.github/ISSUE_TEMPLATE/Copyright.yml vendored Normal file
View File

@ -0,0 +1,14 @@
name: "Copyright Issue"
description: "Create a ticket regarding matters of copyright on the content provided by the website."
title: "[Copyright] - <Title>"
labels:
- "Copyright"
body:
- type: textarea
id: description
attributes:
label: "Description"
description: "Provide a comprehensive explanation of the copyright issue, as well as any required information for us to evaluate your claims and handle your request. If and only if you have to provide sensitive information, we can arrange for moving the conversation to a private channel."
placeholder: "Provide a comprehensive explanation of the copyright issue, as well as any required information for us to evaluate your claims and handle your request. If and only if you have to provide sensitive information, we can arrange for moving the conversation to a private channel."
validations:
required: true

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1 @@
blank_issues_enabled: true

47
.github/workflows/jekyll.yml vendored Normal file
View File

@ -0,0 +1,47 @@
name: Deploy Jekyll site to Pages
on:
push:
branches: ["main"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Ruby
uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0
with:
ruby-version: '3.1'
bundler-cache: true
cache-version: 0
- name: Setup Pages
id: pages
uses: actions/configure-pages@v3
- name: Build with Jekyll
run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
env:
JEKYLL_ENV: production
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
.idea
.DS_Store
.sass-cache
Gemfile.lock
package-json.lock
_site
node_modules
_drafts

6
404.html Normal file
View File

@ -0,0 +1,6 @@
---
layout: 404
title: 404
description: The page you are looking for couldn't be found.
permalink: /404.html
---

9
Gemfile Normal file
View File

@ -0,0 +1,9 @@
source "https://rubygems.org"
gem "kramdown"
gem "kramdown-parser-gfm"
gem "rouge"
gem "jekyll"
gem "jekyll-paginate"
gem "jekyll-paginate-content"
gem "json"

6
_authors/guest.md Normal file
View File

@ -0,0 +1,6 @@
---
layout: "author"
photo: "/assets/img/uploads/profile.png"
name: "guest"
display_name: "Guest"
---

11
_authors/octt.md Normal file
View File

@ -0,0 +1,11 @@
---
layout: "author"
photo: "https://gitlab.com/uploads/-/system/user/avatar/6083316/avatar.png"
name: "octt"
display_name: "Octt"
position: "The One"
bio: "Cute but not so small loli, half-spider web developer, and hacker with cat ears."
github_username: "octospacc"
telegram_username: "ioctt"
website_url: "https://hub.octt.eu.org"
---

99
_config.yml Normal file
View File

@ -0,0 +1,99 @@
# Site Settings
name: "Sala Museo Games"
title: "Sala Museo Games | Where art is your new play"
description: "Sala Museo Games invites you to explore the interactive realm where gaming meets art. Immerse yourself in a curated collection of timeless video games, seamlessly playable online. Rediscover classics and embrace new adventures—where every click is a brushstroke in the canvas of digital entertainment. Welcome to the Museum Room, where art is your new play."
tags:
- "blog"
- "games"
show_hero: true
menu:
- title: "Home"
url: "/"
- title: "About"
url: "/about"
- title: "Contact"
url: "https://github.com/GamingShitposting/SalaMuseoGames/issues/new/choose"
type: "external"
- title: "Contribute (GitHub)"
url: "https://github.com/GamingShitposting/SalaMuseoGames"
type: "external"
- title: "Feed"
url: "/feed.xml"
email: "gamingshitposting@github.com"
date_format: "%Y.%m.%d"
# Social Media Settings
# Remove the item if you don't need it
github_username: "GamingShitposting"
telegram_username: "gamingshitpost"
# Posts Settings
show_time_bar: false
show_modal_on_exit: false
show_modal_on_finish_post: true
two_columns_layout: true
# Advanced Settings
baseurl: "/SalaMuseoGames" # the subpath of your site, e.g. /blog
url: "https://gamingshitposting.github.io" # the base hostname & protocol for your site
language: "en"
categories_folder: "category"
sent_message_url: "/contact/message-sent/"
# Build settings
markdown: kramdown
highlighter: rouge
permalink: /:year/:month/:day/:title/
collections:
authors:
output: true
paginate_path: "/page/:num/"
show_get_theme_btn: false
use_logo: false
# Content paginator
paginate_content:
enabled: true
debug: false
collections:
- posts
auto: false
separator: "--page-break--"
permalink: "/:num/"
seo_canonical: true
properties:
part:
is_generated: true
last:
is_generated: true
single:
is_generated: true
# SASS
sass:
style: compressed
# Plugins
plugins:
- jekyll-paginate
- jekyll-paginate-content
# Exclude my node related stuff
exclude: [
'vendor',
'package.json',
'package-lock.json',
'src',
'node_modules',
'initpost.sh',
'Gemfile',
'Gemfile.lock',
'gulpfile.js',
'README.md'
]
# Theme
version: "Beta"

79
_includes/author.html Normal file
View File

@ -0,0 +1,79 @@
{% assign author = site.authors | where: "name", page.author | first %}
{% if author %}
<section class="author">
<div class="details">
{% if author.photo %}
<img class="img-rounded" src="{{ author.photo }}" alt="{{ author.display_name }}">
{% else %}
<img class="img-rounded" src="/assets/img/user.jpg" alt="{{ author.display_name }}">
{% endif %}
<p class="def">{{ site.translations.text.author | default: "Author" }}</p>
<h3 class="name">
<a href="{{ author.url }}">{{ author.display_name }}</a>
</h3>
<p class="desc">{{ author.bio }}</p>
<p>
{% if author.website_url %}
<a href="{{ author.website_url }}" title="Website">
<img src="{{ site.baseurl }}/assets/img/icons/fa-globe.svg"/>
</a>
{% endif %}
{% if author.github_username %}
<a href="https://github.com/{{ author.github_username }}" title="Github">
<svg><use xlink:href="#icon-github"></use></svg>
</a>
{% endif %}
{% if author.facebook_username %}
<a href="https://www.facebook.com/{{ author.facebook_username }}" title="Facebook">
<svg><use xlink:href="#icon-facebook"></use></svg>
</a>
{% endif %}
{% if author.twitter_username %}
<a href="https://twitter.com/{{ author.twitter_username }}" title="Twitter">
<svg><use xlink:href="#icon-twitter"></use></svg>
</a>
{% endif %}
{% if author.medium_username %}
<a href="https://medium.com/@{{ author.medium_username }}" title="Medium">
<svg><use xlink:href="#icon-medium"></use></svg>
</a>
{% endif %}
{% if author.instagram_username %}
<a href="https://www.instagram.com/{{ author.instagram_username }}" title="Instagram">
<svg><use xlink:href="#icon-instagram"></use></svg>
</a>
{% endif %}
{% if author.linkedin_username %}
<a href="https://www.linkedin.com/in/{{ author.linkedin_username }}" title="LinkedIn">
<svg><use xlink:href="#icon-linkedin"></use></svg>
</a>
{% endif %}
{% if author.telegram_username %}
<a href="https://t.me/{{ author.telegram_username }}" title="Telegram">
<img src="{{ site.baseurl }}/assets/img/icons/telegram.svg"/>
</a>
{% endif %}
</p>
</div>
</section>
{% include page-author-urls.html %}
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "Person",
"name": "{{ author.display_name }}",
{% if author.photo %}
"image": "{{ author.photo }}",
{% else %}
"image": {{ "/assets/img/user.jpg" | prepend: site.baseurl | prepend: site.url }},
{% endif %}
"jobTitle": "{{ author.position }}",
"url": "{{ author.url | prepend: site.baseurl | prepend: site.url }}",
"sameAs": [
{{ author_urls | split: "," | join: "," }}
]
}
</script>
{% endif %}

48
_includes/comments.html Normal file
View File

@ -0,0 +1,48 @@
{% if site.disqus_username %}
<section class="comments">
<h3>{{ site.translations.text.comments | default: "Comments" }}</h3>
<div id="disqus_thread"></div>
</section>
<script type="text/javascript">
var disqus_loaded = false;
function load_disqus()
{
disqus_loaded = true;
var disqus_shortname = '{{site.disqus_username}}';
var disqus_title = '{{page.title.replace("'", "\\'")}}';
var disqus_url = '{{page.url}}';
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
var ldr = document.getElementById('disqus_loader');
};
window.onscroll = function(e) {
if ((window.innerHeight + window.scrollY) >= (document.body.offsetHeight - 800)) {
//hit bottom of page
if (disqus_loaded==false)
load_disqus()
}
};
</script>
{% else %}
<script src="https://giscus.app/client.js"
data-repo="GamingShitposting/SalaMuseoGames"
data-repo-id="R_kgDOK0pJIQ"
data-category="Announcements"
data-category-id="DIC_kwDOK0pJIc4Cbcpu"
data-mapping="pathname"
data-strict="1"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="top"
data-theme="noborder_gray"
data-lang="en"
crossorigin="anonymous"
async>
</script>
{% endif %}

4
_includes/date.html Normal file
View File

@ -0,0 +1,4 @@
{% assign months = "January,February,March,April,May,June,July,August,September,October,November,December" | split: "," %}
{% assign month_number = include.date | date: "%-m" | minus: 1 %}
{{ months[month_number] }} {{ include.date | date: "%-d" }}, {{ include.date | date: "%Y" }}

9
_includes/emulator.html Normal file
View File

@ -0,0 +1,9 @@
<p>
<button onclick="(function(ctx){
ctx.parentElement.scrollIntoView();
ctx.parentElement.querySelector('iframe.AppFrame').focus();
})(this)">Focus</button>
{% if include.platform == 'nds' %}
<iframe class="AppFrame" src="https://octospacc.gitlab.io/Web-Archives-Misc/Repo/DeSmuME/#RomUrl={{ include.rom_binary }}"></iframe>
{% endif %}
</p>

0
_includes/extra-css.html Normal file
View File

0
_includes/extra-js.html Normal file
View File

78
_includes/footer.html Normal file
View File

@ -0,0 +1,78 @@
<footer>
<p>
{% if site.github_username %}
<a href="https://github.com/{{ site.github_username }}" title="Github">
<svg><use xlink:href="#icon-github"></use></svg>
</a>
{% endif %}
{% if site.facebook_username %}
<a href="https://www.facebook.com/{{ site.facebook_username }}" title="Facebook">
<svg><use xlink:href="#icon-facebook"></use></svg>
</a>
{% endif %}
{% if site.twitter_username %}
<a href="https://twitter.com/{{ site.twitter_username }}" title="Twitter">
<svg><use xlink:href="#icon-twitter"></use></svg>
</a>
{% endif %}
{% if site.medium_username %}
<a href="https://medium.com/@{{ site.medium_username }}" title="Medium">
<svg><use xlink:href="#icon-medium"></use></svg>
</a>
{% endif %}
{% if site.instagram_username %}
<a href="https://www.instagram.com/{{ site.instagram_username }}" title="Instagram">
<svg><use xlink:href="#icon-instagram"></use></svg>
</a>
{% endif %}
{% if site.linkedin_username %}
<a href="https://www.linkedin.com/in/{{ site.linkedin_username }}" title="LinkedIn">
<svg><use xlink:href="#icon-linkedin"></use></svg>
</a>
{% endif %}
{% if site.telegram_username %}
<a href="https://t.me/{{ site.telegram_username }}" title="Telegram">
<img src="{{ site.baseurl }}/assets/img/icons/telegram.svg"/>
</a>
{% endif %}
</p>
{% include links.html %}
<p>
Site theme based on <a href="https://github.com/thiagorossener/jekflix-template" target="_blank">Jekflix</a>, originally made with <svg class="love"><use xlink:href="#icon-heart"></use></svg> by <a href="https://rossener.com" target="_blank" class="creator">Thiago Rossener</a>
</p>
</footer>
{% include site-social-urls.html %}
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "Organization",
"name": "{{ site.name }}",
"description": "{{ site.description }}",
"url": "{{ site.url }}{{site.baseurl}}/",
"logo": {
"@type": "ImageObject",
"url": "{{ site.url }}{{site.baseurl}}/assets/img/icons/mediumtile.png",
"width": "600",
"height": "315"
},
"sameAs": [
{{ social_urls | split: "," | join: "," }}
]
}
</script>
<!-- Include the script that allows Netlify CMS login -->
<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
<!-- Include the website scripts -->
<script src="{{ '/assets/js/scripts.min.js' | prepend: site.baseurl }}"></script>
<!-- Include Google Analytics script -->
{% include stats.html %}
<!-- Include extra scripts -->
{% include extra-js.html %}

109
_includes/head.html Normal file
View File

@ -0,0 +1,109 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% assign title = '' %}
{% if page.layout == 'author' %}
{% assign title = page.display_name %}
{% elsif page.title %}
{% assign title = page.title | append: " | " | append: site.name %}
{% else %}
{% assign title = site.title %}
{% endif %}
{% assign image = '' %}
{% if page.image %}
{% assign image = page.image %}
{% else %}
{% assign image = "/assets/img/blog-image.png" | prepend: site.baseurl | prepend: site.url %}
{% endif %}
{% assign description = '' %}
{% if page.description %}
{% assign description = page.description | strip_html | strip_newlines | truncate: 160 %}
{% else %}
{% assign description = site.description %}
{% endif %}
{% assign url = '' %}
{% if paginator.page_trail %}
{% assign url = paginator.first_page_path | replace:'index.html','' | prepend: site.baseurl | prepend: site.url %}
{% else %}
{% assign url = page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url %}
{% endif %}
<title>{{ title }}</title>
<meta name="description" content="{{ description }}">
{% if page.tags %}
<meta name="keywords" content="{{ page.tags | join: ', ' }}">
{% endif %}
<!-- Social: Twitter -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ title }}">
<meta name="twitter:description" content="{{ description }}">
{% if image contains '://' %}
<meta property="twitter:image" content="{{ image }}">
{% else %}
<meta property="twitter:image" content="{{ image | prepend: site.url }}">
{% endif %}
{% if site.twitter_username %}
<meta name="twitter:site" content="@{{ site.twitter_username }}">
{% endif %}
<!-- Social: Facebook / Open Graph -->
<meta property="og:url" content="{{ url }}">
<meta property="og:title" content="{{ title }}">
<meta property="og:image" content="{{ image }}">
<meta property="og:description" content="{{ description }}">
<meta property="og:site_name" content="{{ site.title }}">
<!-- Favicon -->
<link rel="shortcut icon" href="{{ site.baseurl }}/favicon.ico" type="image/x-icon" />
<!-- Apple Touch Icons -->
<link rel="apple-touch-icon" href="{{ site.baseurl }}/assets/img/icons/apple-touch-icon.png" />
<link rel="apple-touch-icon" sizes="57x57" href="/assets/img/icons/apple-touch-icon-57x57.png" />
<link rel="apple-touch-icon" sizes="72x72" href="/assets/img/icons/apple-touch-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="114x114" href="/assets/img/icons/apple-touch-icon-114x114.png" />
<link rel="apple-touch-icon" sizes="144x144" href="/assets/img/icons/apple-touch-icon-144x144.png" />
<link rel="apple-touch-icon" sizes="60x60" href="/assets/img/icons/apple-touch-icon-60x60.png" />
<link rel="apple-touch-icon" sizes="120x120" href="/assets/img/icons/apple-touch-icon-120x120.png" />
<link rel="apple-touch-icon" sizes="76x76" href="/assets/img/icons/apple-touch-icon-76x76.png" />
<link rel="apple-touch-icon" sizes="152x152" href="/assets/img/icons/apple-touch-icon-152x152.png" />
<!-- Windows 8 Tile Icons -->
<meta name="application-name" content="{{ site.name }}">
<meta name="msapplication-TileColor" content="#141414">
<meta name="msapplication-square70x70logo" content="smalltile.png" />
<meta name="msapplication-square150x150logo" content="mediumtile.png" />
<meta name="msapplication-wide310x150logo" content="widetile.png" />
<meta name="msapplication-square310x310logo" content="largetile.png" />
<!-- Android Lolipop Theme Color -->
<meta name="theme-color" content="#141414">
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Titillium+Web:300,400,700" rel="stylesheet">
<link rel="stylesheet" href="{{ '/assets/css/styles.css' | prepend: site.baseurl }}">
<link rel="canonical" href="{{ url }}">
<link rel="alternate" type="application/rss+xml" title="{{ site.title }}" href="{{ '/feed.xml' | prepend: site.baseurl | prepend: site.url }}" />
<!-- Include extra styles -->
{% include extra-css.html %}
<!-- JavaScript enabled/disabled -->
<script>
document.querySelector('html').classList.remove('no-js');
</script>
<script>
window.site_config = {
baseurl: "{{ site.baseurl }}",
};
</script>
</head>

27
_includes/header.html Normal file
View File

@ -0,0 +1,27 @@
<header class="bar-header">
<a id="menu" role="button">
<svg id="open" class="icon-menu"><use xlink:href="#icon-menu"></use></svg>
</a>
<h1 class="logo">
<a href="{{ site.baseurl }}/">
{% if site.use_logo %}
{% include logo.html %}
{% else %}
{{ site.name }} <span class="version">{{ site.version }}</span>
{% endif %}
</a>
</h1>
<a id="search" class="dosearch" role="button">
<svg class="icon-search"><use xlink:href="#icon-search"></use></svg>
</a>
{% if site.show_get_theme_btn %}
<a href="https://github.com/thiagorossener/jekflix-template" class="get-theme" role="button">
Get this theme!
</a>
{% endif %}
</header>
<div id="mask" class="overlay"></div>
{% include menu.html %}
{% include search.html %}

9
_includes/links.html Normal file
View File

@ -0,0 +1,9 @@
<ul>
{% for item in site.menu %}
{% if item.title and item.url %}
<li>
<a href="{% if item.type != 'external' %}{{ site.baseurl }}{% endif %}{{ item.url }}">{{ item.title }}</a>
</li>
{% endif %}
{% endfor %}
</ul>

31
_includes/loader.html Normal file
View File

@ -0,0 +1,31 @@
<svg width="50" height="50" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" class="loader">
<defs>
<linearGradient x1="0%" y1="100%" x2="100%" y2="100%" id="a">
<stop stop-color="currentColor" stop-opacity="0" offset="0%"/>
<stop stop-color="currentColor" stop-opacity=".631" offset="63.146%"/>
<stop stop-color="currentColor" offset="100%"/>
</linearGradient>
</defs>
<g fill="none" fill-rule="evenodd">
<g transform="translate(1 1)">
<path d="M0,18.0000525 C0,27.9411416 8.05885836,36 18.0000525,36 C27.9411416,36 36,27.9411416 36,18.0000525" id="Oval-2" stroke="url(#a)" stroke-width="2">
<animateTransform
attributeName="transform"
type="rotate"
from="360 18 18"
to="0 18 18"
dur="1.9s"
repeatCount="indefinite" />
</path>
<circle fill="currentColor" cx="36" cy="18" r="1">
<animateTransform
attributeName="transform"
type="rotate"
from="360 18 18"
to="0 18 18"
dur="1.9s"
repeatCount="indefinite" />
</circle>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

3
_includes/logo.html Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 279 41">
<path fill="currentColor" d="M13.62,32 L16.02,32 L16.02,41 L0.24,41 L0.24,32 L2.64,32 L2.64,9.98 L0.24,9.98 L0.24,0.98 L25.02,0.98 L31.38,7.4 L31.38,17.66 L28.74,20.3 L31.38,22.88 L31.38,32 L33.78,32 L33.78,41 L20.4,41 L20.4,26.12 L19.14,24.8 L13.62,24.8 L13.62,32 Z M13.62,15.8 L19.14,15.8 L20.4,14.48 L20.4,11.3 L19.14,9.98 L13.62,9.98 L13.62,15.8 Z M37.08,7.4 L43.5,0.98 L61.08,0.98 L67.5,7.4 L67.5,34.58 L61.08,41 L43.5,41 L37.08,34.58 L37.08,7.4 Z M56.52,11.3 L55.2,9.98 L49.38,9.98 L48.06,11.3 L48.06,30.68 L49.38,32 L55.2,32 L56.52,30.68 L56.52,11.3 Z M89.04,25.58 L77.34,25.58 L70.86,19.22 L70.86,7.4 L77.28,0.98 L94.86,0.98 L101.28,7.4 L101.28,15.32 L90.3,15.32 L90.3,11.3 L88.98,9.98 L83.16,9.98 L81.84,11.3 L81.84,15.32 L83.16,16.58 L94.86,16.58 L101.28,23 L101.28,34.58 L94.86,41 L77.28,41 L70.86,34.58 L70.86,26.9 L81.84,26.9 L81.84,30.68 L83.16,32 L88.98,32 L90.3,30.68 L90.3,26.9 L89.04,25.58 Z M122.82,25.58 L111.12,25.58 L104.64,19.22 L104.64,7.4 L111.06,0.98 L128.64,0.98 L135.06,7.4 L135.06,15.32 L124.08,15.32 L124.08,11.3 L122.76,9.98 L116.94,9.98 L115.62,11.3 L115.62,15.32 L116.94,16.58 L128.64,16.58 L135.06,23 L135.06,34.58 L128.64,41 L111.06,41 L104.64,34.58 L104.64,26.9 L115.62,26.9 L115.62,30.68 L116.94,32 L122.76,32 L124.08,30.68 L124.08,26.9 L122.82,25.58 Z M151.8,32 L158.82,32 L158.82,30.38 L167.82,30.38 L167.82,41 L138.42,41 L138.42,32 L140.82,32 L140.82,9.98 L138.42,9.98 L138.42,0.98 L167.82,0.98 L167.82,11.6 L158.82,11.6 L158.82,9.98 L151.8,9.98 L151.8,16.52 L153.42,16.52 L153.42,14.9 L162.42,14.9 L162.42,27.14 L153.42,27.14 L153.42,25.52 L151.8,25.52 L151.8,32 Z M195.36,41 L184.56,23.12 L184.56,32 L186.96,32 L186.96,41 L171.18,41 L171.18,32 L173.58,32 L173.58,9.98 L171.18,9.98 L171.18,0.98 L184.2,0.98 L195.18,19.28 L195.18,9.98 L192.78,9.98 L192.78,0.98 L208.56,0.98 L208.56,9.98 L206.16,9.98 L206.16,32 L208.56,32 L208.56,41 L195.36,41 Z M225.3,32 L232.32,32 L232.32,30.38 L241.32,30.38 L241.32,41 L211.92,41 L211.92,32 L214.32,32 L214.32,9.98 L211.92,9.98 L211.92,0.98 L241.32,0.98 L241.32,11.6 L232.32,11.6 L232.32,9.98 L225.3,9.98 L225.3,16.52 L226.92,16.52 L226.92,14.9 L235.92,14.9 L235.92,27.14 L226.92,27.14 L226.92,25.52 L225.3,25.52 L225.3,32 Z M258.06,32 L260.46,32 L260.46,41 L244.68,41 L244.68,32 L247.08,32 L247.08,9.98 L244.68,9.98 L244.68,0.98 L269.46,0.98 L275.82,7.4 L275.82,17.66 L273.18,20.3 L275.82,22.88 L275.82,32 L278.22,32 L278.22,41 L264.84,41 L264.84,26.12 L263.58,24.8 L258.06,24.8 L258.06,32 Z M258.06,15.8 L263.58,15.8 L264.84,14.48 L264.84,11.3 L263.58,9.98 L258.06,9.98 L258.06,15.8 Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

6
_includes/menu.html Normal file
View File

@ -0,0 +1,6 @@
<aside class="sidebar" id="sidebar">
<nav id="navigation">
<h2>Menu</h2>
{% include links.html %}
</nav>
</aside>

View File

@ -0,0 +1,9 @@
{% assign words = content | number_of_words %}
{% if words < 360 %}
{% assign totalMinutes = 1 %}
{% else %}
{% assign totalMinutes = words | divided_by:180 %}
{% endif %}
{% assign minutesText = totalMinutes | append: ' min to read' %}

35
_includes/modal.html Normal file
View File

@ -0,0 +1,35 @@
<div class="modal{% if include.showOnExit %} exit{% endif %}{% if include.closed %} closed{% endif %}">
<div class="window">
<svg class="close">
<use xlink:href="#icon-close"></use>
</svg>
<div class="header">
<h2>{{ include.title }}</h2>
<p>{{ include.subtitle }}</p>
</div>
<div class="content">
<ul>
{% assign next_posts = site.posts | where_exp:"post","post.is_generated != true" | where_exp:"post","post.path != page.path" %}
{% assign shuffled_array = next_posts | shuffle %}
{% for post in shuffled_array limit:2 %}
<li>
<a href="{{ post.url | prepend: site.baseurl }}">
<figure>
{% if post.optimized_image %}
<img src="{{ post.optimized_image }}">
{% elsif post.image %}
<img src="{{ post.image }}">
{% else %}
<img src="/assets/img/off.jpg">
{% endif %}
</figure>
<h3>{{ post.title }}</h3>
<p>{{ post.description }}</p>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
<div class="mask"></div>
</div>

View File

@ -0,0 +1,6 @@
{% capture weekago %}{{ "now" | date: "%s" | minus: 604800 }}{% endcapture %}
{% capture posttime %}{{ include.date | date: "%s" }}{% endcapture %}
{% if posttime > weekago %}
<div class="new-post-tag">{{ site.translations.text.new_post | default: "New Post" }}</div>
{% endif %}

View File

@ -0,0 +1,25 @@
{% assign author_urls = '' %}
{% if page.website_url %}
{% assign author_urls = author_urls | append: '"' | append: page.website_url | append: '",' %}
{% endif %}
{% if page.github_username %}
{% assign author_urls = author_urls | append: '"https://github.com/' | append: page.github_username | append: '",' %}
{% endif %}
{% if page.facebook_username %}
{% assign author_urls = author_urls | append: '"https://www.facebook.com/' | append: page.facebook_username | append: '",' %}
{% endif %}
{% if page.twitter_username %}
{% assign author_urls = author_urls | append: '"https://twitter.com/' | append: page.twitter_username | append: '",' %}
{% endif %}
{% if page.medium_username %}
{% assign author_urls = author_urls | append: '"https://medium.com/@' | append: page.medium_username | append: '",' %}
{% endif %}
{% if page.instagram_username %}
{% assign author_urls = author_urls | append: '"https://www.instagram.com/' | append: page.instagram_username | append: '",' %}
{% endif %}
{% if page.linkedin_username %}
{% assign author_urls = author_urls | append: '"https://www.linkedin.com/in/' | append: page.linkedin_username | append: '",' %}
{% endif %}
{% if page.telegram_username %}
{% assign author_urls = author_urls | append: '"https://t.me/' | append: page.telegram_username | append: '",' %}
{% endif %}

View File

@ -0,0 +1,14 @@
<!-- Pagination links -->
<div class="pagination pagination-home">
{% if paginator.previous_page %}
<a href="{{ paginator.previous_page_path }}" class="previous" onclick="ga('send', 'event', 'pagination', 'click', 'page previous')">
<svg><use xlink:href="#icon-arrow-right"></use></svg>
</a>
{% endif %}
<span class="page_number ">{{ site.translations.pagination.page | default: "Page" }} {{ paginator.page }} {{ site.translations.pagination.of | default: "of" }} {{ paginator.total_pages }}</span>
{% if paginator.next_page %}
<a href="{{ paginator.next_page_path }}" class="next" onclick="ga('send', 'event', 'pagination', 'click', 'page next')">
<svg><use xlink:href="#icon-arrow-right"></use></svg>
</a>
{% endif %}
</div>

View File

@ -0,0 +1,21 @@
<!-- Pagination links -->
{% if paginator.page_trail %}
{% assign next_posts = site.posts | where_exp:"post","post.is_generated != true" | where_exp:"post","post.path != page.path" | where_exp:"post","post.date <= page.date" %}
<div class="pagination pagination-post {{ include.extra_classes }}">
{% if paginator.is_last != true %}
<a href="{{ paginator.next_page_path }}">
{% if include.progressBar %}
{% include progress-bar.html %}
{% endif %}
<span class="text">{{ site.translations.pagination.next_page | default: "Next Page" }} <svg class="arrow"><use xlink:href="#icon-arrow-right"></use></svg></span>
</a>
{% else if next_posts.first %}
<a href="{{ next_posts.first.url }}">
{% if include.progressBar %}
{% include progress-bar.html finished=true %}
{% endif %}
<span class="text">{{ site.translations.pagination.next_post | default: "Next Post" }} <svg class="arrow"><use xlink:href="#icon-arrow-right"></use></svg></span>
</a>
{% endif %}
</div>
{% endif %}

View File

@ -0,0 +1,8 @@
{% if paginator.total_pages > 1 %}
<div class="progress-bar {% if include.finished %}finished{% endif %}">
{% for i in (1..paginator.total_pages) %}
<div class="bar {% if i <= paginator.page %}completed{% endif %}"></div>
{% endfor %}
<svg class="star"><use xlink:href="#icon-star"></use></svg>
</div>
{% endif %}

3
_includes/read-icon.html Normal file
View File

@ -0,0 +1,3 @@
<div class="read-icon">
<svg><use xlink:href="#icon-read"></use></svg>
</div>

View File

@ -0,0 +1,30 @@
<div class="recommendation">
<div class="message">
<strong>{{ site.translations.recommendation.text | default: "Why don't you check something else next?" }}</strong>
<div>
<button>
<svg><use xlink:href="#icon-arrow-right"></use></svg>
<span>{{ site.translations.recommendation.back_btn | default: "Go back to top" }}</span>
</button>
</div>
</div>
{% if page.next %}
{% assign recommendation = page.next %}
{% else %}
{% assign next_posts = site.posts | where_exp:"post","post.is_generated != true" | where_exp:"post","post.path != page.path" %}
{% assign shuffled_array = next_posts | shuffle %}
{% assign recommendation = shuffled_array.first %}
{% endif %}
<a href="{{ recommendation.url | prepend: site.baseurl }}" class="post-preview">
<div class="image">
{% if recommendation.optimized_image %}
<img src="{{ recommendation.optimized_image }}">
{% elsif recommendation.image %}
<img src="{{ recommendation.image }}">
{% else %}
<img src="/assets/img/off.jpg">
{% endif %}
</div>
<h3 class="title">{{ recommendation.title }}</h3>
</a>
</div>

7
_includes/search.html Normal file
View File

@ -0,0 +1,7 @@
<div class="search-wrapper">
<div class="search-form">
<input type="text" class="search-field" placeholder="{{ site.translations.text.search | default: 'Search' }}">
<svg class="icon-remove-sign"><use xlink:href="#icon-close"></use></svg>
<ul class="search-results search-list"></ul>
</div>
</div>

11
_includes/share.html Normal file
View File

@ -0,0 +1,11 @@
<section class="share">
<h3>{{ site.translations.text.share | default: "Share" }}</h3>
<a aria-label="{{ site.translations.button.share_on_twitter | default: 'Share on Twitter' }}" href="https://twitter.com/intent/tweet?text=&quot;{{ page.description }}&quot;%20{{ site.url }}{{ page.url }}%20via%20&#64;{{ site.twitter_username }}&hashtags={{ page.tags | join: ',' }}"
onclick="window.open(this.href, 'twitter-share', 'width=550,height=235');return false;" title="{{ site.translations.button.share_on_twitter | default: 'Share on Twitter' }}">
<svg class="icon icon-twitter"><use xlink:href="#icon-twitter"></use></svg>
</a>
<a aria-label="{{ site.translations.button.share_on_facebook | default: 'Share on Facebook' }}" href="https://www.facebook.com/sharer/sharer.php?u={{ site.url }}{{ page.url }}"
onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;" title="{{ site.translations.button.share_on_facebook | default: 'Share on Facebook' }}">
<svg class="icon icon-facebook"><use xlink:href="#icon-facebook"></use></svg>
</a>
</section>

View File

@ -0,0 +1,22 @@
{% assign social_urls = '' %}
{% if site.github_username %}
{% assign social_urls = social_urls | append: '"https://github.com/' | append: site.github_username | append: '",' %}
{% endif %}
{% if site.facebook_username %}
{% assign social_urls = social_urls | append: '"https://www.facebook.com/' | append: site.facebook_username | append: '",' %}
{% endif %}
{% if site.twitter_username %}
{% assign social_urls = social_urls | append: '"https://twitter.com/' | append: site.twitter_username | append: '",' %}
{% endif %}
{% if site.medium_username %}
{% assign social_urls = social_urls | append: '"https://medium.com/@' | append: site.medium_username | append: '",' %}
{% endif %}
{% if site.instagram_username %}
{% assign social_urls = social_urls | append: '"https://www.instagram.com/' | append: site.instagram_username | append: '",' %}
{% endif %}
{% if site.linkedin_username %}
{% assign social_urls = social_urls | append: '"https://www.linkedin.com/in/' | append: site.linkedin_username | append: '",' %}
{% endif %}
{% if site.telegram_username %}
{% assign social_urls = social_urls | append: '"https://t.me/' | append: site.telegram_username | append: '",' %}
{% endif %}

13
_includes/stats.html Normal file
View File

@ -0,0 +1,13 @@
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id={{ site.google_analytics }}"></script>
<script>
var host = window.location.hostname;
if (host != 'localhost') {
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{{ site.google_analytics }}');
}
</script>

View File

@ -0,0 +1 @@
<!-- Add your newsletter subscription form here -->

1
_includes/svg-icons.html Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

8
_includes/time-bar.html Normal file
View File

@ -0,0 +1,8 @@
<div class="time-bar" data-minutes="{{ totalMinutes }}">
<span class="time-completed"></span>
<span class="time-remaining"></span>
<div class="bar">
<span class="completed" style="width:0%;"></span>
<span class="remaining" style="width:100%;"></span>
</div>
</div>

1
_includes/toc.html Normal file
View File

@ -0,0 +1 @@
<!-- Add your table of contents here -->

18
_layouts/404.html Normal file
View File

@ -0,0 +1,18 @@
---
layout: default
---
<style type="text/css" media="screen">
.container {
margin: 0px auto;
max-width: 600px;
text-align: center;
padding-top: 60px;
}
</style>
<div class="container">
<img src="/assets/img/404.gif" width="100%" alt="{{ site.translations.error_404.image_alt | default: '404 - Page not found' }}">
<p><strong>{{ site.translations.error_404.title | default: "Page not found :(" }}</strong></p>
<p>{{ site.translations.error_404.message | default: "I'm sorry. We couldn't find the page you are looking for." }}</p>
</div>

50
_layouts/author.html Normal file
View File

@ -0,0 +1,50 @@
---
layout: page
---
<div class="staff">
{% if page.photo %}
<img class="img-rounded" src="{{ page.photo }}" alt="{{ author.display_name }}">
{% else %}
<img class="img-rounded" src="/assets/img/user.jpg" alt="{{ author.display_name }}">
{% endif %}
<h1 class="name">{{ page.display_name }}</h1>
{% if page.position %}
<h2 class="position">{{ page.position }}</h2>
{% endif %}
<p>{{ page.bio }}</p>
<h2>Posts</h2>
<ul>
{% assign filtered_posts = site.posts | where: 'author', page.name | where_exp:"post","post.is_generated != true" %}
{% for post in filtered_posts %}
<li>
<a href="{{ site.baseurl }}{{ post.url }}">{{ post.title }}</a>
</li>
{% endfor %}
</ul>
</div>
{% include page-author-urls.html %}
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "Person",
"name": "{{ page.display_name }}",
{% if page.photo %}
"image": "{{ page.photo }}",
{% else %}
"image": {{ "/assets/img/user.jpg" | prepend: site.baseurl | prepend: site.url }},
{% endif %}
"jobTitle": "{{ page.position }}",
"url": "{{ page.url | prepend: site.baseurl | prepend: site.url }}",
"sameAs": [
{{ author_urls | split: "," | join: "," }}
]
}
</script>

71
_layouts/category.html Normal file
View File

@ -0,0 +1,71 @@
<!DOCTYPE html>
<html lang="{{ site.language }}" class="no-js">
{% include head.html %}
<body class="main-page has-push-menu">
{% include svg-icons.html %}
{% include header.html %}
<section class="content">
<main class="home" id="post" role="main">
<h1 class="title-category">/{{page.title}}</h1>
<div id="grid" class="row flex-grid">
{% assign posts = site.posts | where_exp:"post","post.is_generated != true" %}
{% for post in posts %}
{% if post.category == page.slug %}
<article class="box-item">
<div class="box-body">
{% if post.image %}
<a class="cover" href="{{ post.url | prepend: site.baseurl }}">
{% include loader.html %}
{% if post.optimized_image %}
<img src="/assets/img/placeholder.png" width="100%" data-url="{{ post.optimized_image }}" class="preload">
<noscript>
<img src="{{ post.optimized_image }}" width="100%">
</noscript>
{% elsif post.image %}
<img src="/assets/img/placeholder.png" width="100%" data-url="{{ post.image }}" class="preload">
<noscript>
<img src="{{ post.image }}" width="100%">
</noscript>
{% else %}
<img src="/assets/img/placeholder.png" width="100%" data-url="/assets/img/off.jpg" class="preload">
<noscript>
<img src="/assets/img/off.jpg" width="100%">
</noscript>
{% endif %}
{% include new-post-tag.html date=post.date %}
{% include read-icon.html %}
</a>
{% endif %}
<div class="box-info">
<time datetime="{{ post.date | date_to_xmlschema }}" class="date">
{% include date.html date=post.date %}
</time>
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">
<h2 class="post-title">
{{ post.title }}
</h2>
</a>
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">
<p class="description">{{ post.description }}</p>
</a>
<div class="tags">
{% for tag in post.tags %}
{% if tag != "" %}
<a href="{{ site.baseurl}}/tags/#{{tag | slugify }}">#{{ tag }}</a>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</article>
{% endif %}
{% endfor %}
</div>
</main>
</section>
{% include footer.html %}
</body>
</html>

8
_layouts/compress.html Normal file
View File

@ -0,0 +1,8 @@
---
# Jekyll layout that compresses HTML
# v1.4.0
# http://jch.penibelst.de/
# © 20142015 Anatol Broder
# MIT License
---
{% if site.compress_html.ignore.envs contains jekyll.environment %}{{ content }}{% else %}{% capture _content %}{{ content }}{% endcapture %}{% assign _profile = site.compress_html.profile %}{% if site.compress_html.endings == "all" %}{% assign _endings = "html head body li dt dd p rt rp optgroup option colgroup caption thead tbody tfoot tr td th" | split: " " %}{% else %}{% assign _endings = site.compress_html.endings %}{% endif %}{% for _element in _endings %}{% capture _end %}</{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _end %}{% endfor %}{% if _profile and _endings %}{% assign _profile_endings = _content | size | plus: 1 %}{% endif %}{% assign _pre_befores = _content | split: "<pre" %}{% assign _content = "" %}{% for _pre_before in _pre_befores %}{% assign _pres = _pre_before | split: "</pre>" %}{% case _pres.size %}{% when 2 %}{% capture _content %}{{ _content }}<pre{{ _pres.first }}</pre>{{ _pres.last | split: " " | join: " " }}{% endcapture %}{% when 1 %}{% capture _content %}{{ _content }}{{ _pres.last | split: " " | join: " " }}{% endcapture %}{% endcase %}{% endfor %}{% if _profile %}{% assign _profile_collapse = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.comments == "all" %}{% assign _comments = "<!-- -->" | split: " " %}{% else %}{% assign _comments = site.compress_html.comments %}{% endif %}{% if _comments.size == 2 %}{% assign _comment_befores = _content | split: _comments.first %}{% for _comment_before in _comment_befores %}{% assign _comment_content = _comment_before | split: _comments.last | first %}{% if _comment_content %}{% capture _comment %}{{ _comments.first }}{{ _comment_content }}{{ _comments.last }}{% endcapture %}{% assign _content = _content | remove: _comment %}{% endif %}{% endfor %}{% if _profile %}{% assign _profile_comments = _content | size | plus: 1 %}{% endif %}{% endif %}{% if site.compress_html.clippings == "all" %}{% assign _clippings = "html head title base link meta style body article section nav aside h1 h2 h3 h4 h5 h6 hgroup header footer address p hr blockquote ol ul li dl dt dd figure figcaption main div table caption colgroup col tbody thead tfoot tr td th" | split: " " %}{% else %}{% assign _clippings = site.compress_html.clippings %}{% endif %}{% for _element in _clippings %}{% assign _edges = " <e;<e; </e>;</e>;</e> ;</e>" | replace: "e", _element | split: ";" %}{% assign _content = _content | replace: _edges[0], _edges[1] | replace: _edges[2], _edges[3] | replace: _edges[4], _edges[5] %}{% endfor %}{% if _profile and _clippings %}{% assign _profile_clippings = _content | size | plus: 1 %}{% endif %}{{ _content }}{% if _profile %} <table id="compress_html_profile_{{ site.time | date: "%Y%m%d" }}" class="compress_html_profile"> <thead> <tr> <td>Step <td>Bytes <tbody> <tr> <td>raw <td>{{ content | size }}{% if _profile_endings %} <tr> <td>endings <td>{{ _profile_endings }}{% endif %}{% if _profile_collapse %} <tr> <td>collapse <td>{{ _profile_collapse }}{% endif %}{% if _profile_comments %} <tr> <td>comments <td>{{ _profile_comments }}{% endif %}{% if _profile_clippings %} <tr> <td>clippings <td>{{ _profile_clippings }}{% endif %} </table>{% endif %}{% endif %}

94
_layouts/contact.html Normal file
View File

@ -0,0 +1,94 @@
---
layout: page
---
{% if site.email or site.formspree_form_id %}
<style type="text/css" media="screen">
.container {
margin: 0px auto;
max-width: 600px;
}
</style>
<div class="container">
<h2>{{ site.translations.contact.title | default: "Talk to me" }}</h2>
<div id="form" class="contact-form">
<form accept-charset="UTF-8" method="POST" action="https://formspree.io/{% if site.formspree_form_id %}f/{{ site.formspree_form_id }}{% else %}{{ site.email }}{% endif %}" v-on:submit.prevent="validateBeforeSubmit" ref="contact">
<fieldset>
<input type="hidden" name="_subject" value="{{ site.translations.contact.subject | default: 'New contact!' }}" />
<input type="hidden" name="_next" value="{{ site.url }}{{ site.sent_message_url }}" />
<input type="hidden" name="_language" value="{{ site.language }}" />
<input type="text" name="name" placeholder="{{ site.translations.contact.placeholders.name | default: 'Your name' }}" v-validate="'required'"
:class="{ 'has-error': errors.has('name') }">
<span v-if="errors.has('name')" v-cloak>${ errors.first('name') }</span>
<input type="text" name="email" placeholder="{{ site.translations.contact.placeholders.email | default: 'Your email' }}" v-validate="'required|email'"
:class="{ 'has-error': errors.has('email') }">
<span v-if="errors.has('email')" v-cloak>${ errors.first('email') }</span>
<textarea name="message" onkeyup="adjust_textarea(this)" placeholder="{{ site.translations.contact.placeholders.message | default: 'Your message' }}" v-validate="'required'"
:class="{ 'has-error': errors.has('message') }"></textarea>
<span v-if="errors.has('message')" v-cloak>${ errors.first('message') }</span>
<button type="submit">{{ site.translations.contact.submit_btn | default: "Send" }}</button>
</fieldset>
</form>
</div>
</div>
<script type="text/javascript">
function adjust_textarea(h) {
h.style.height = "200px";
h.style.height = (h.scrollHeight)+"px";
}
</script>
<script src="https://unpkg.com/vue@2.4.2"></script>
<script src="https://unpkg.com/vee-validate@2.0.0-rc.8"></script>
<script type="text/javascript">
Vue.use(VeeValidate);
const dictionary = {
{{ site.translations.contact.errors.locale | default: 'en' }}: {
custom: {
name: {
required: "{{ site.translations.contact.errors.empty_name | default: 'Name is required' }}"
},
email: {
required: "{{ site.translations.contact.errors.empty_email | default: 'Email is required' }}",
email: "{{ site.translations.contact.errors.invalid_email | default: 'Email is invalid' }}"
},
message: {
required: "{{ site.translations.contact.errors.empty_message | default: 'Message is required' }}"
}
}
}
};
VeeValidate.Validator.updateDictionary(dictionary);
VeeValidate.Validator.setLocale("{{ site.translations.contact.errors.locale | default: 'en' }}");
new Vue({
el: '#form',
delimiters: ['${', '}'],
methods: {
validateBeforeSubmit: function () {
this.$validator.validateAll();
if (!this.errors.any()) {
this.$refs.contact.submit();
}
}
}
});
</script>
{% else %}
<script>window.location = "{% if site.url == '' and site.baseurl == '' %}/{% else %}{{ site.url }}{{ site.baseurl }}{% endif %}";</script>
{% endif %}

17
_layouts/default.html Normal file
View File

@ -0,0 +1,17 @@
---
layout: compress
---
<!DOCTYPE html>
<html lang="{{ site.language }}" class="no-js">
{% include head.html %}
<body class="main-page has-push-menu">
{% include svg-icons.html %}
{% include header.html %}
<section class="content">
{{ content }}
</section>
{% include footer.html %}
</body>
</html>

169
_layouts/home.html Normal file
View File

@ -0,0 +1,169 @@
---
layout: main
---
{% if site.paginate %}
{% assign posts = paginator.posts | where_exp:"post","post.is_generated != true" %}
{% else %}
{% assign posts = site.posts | where_exp:"post","post.is_generated != true" %}
{% endif %}
{% if site.show_hero and paginator == nil or paginator.page == 1 %}
{% assign offset = 1 %}
{% else %}
{% assign offset = 0 %}
{% endif %}
<main class="home {% if site.show_hero and paginator == nil or paginator.page == 1 %}no-padding{% endif %}" role="main">
{% if site.show_hero and paginator == nil or paginator.page == 1 %}
<!-- Hero -->
{% assign featured = posts.first %}
<section class="hero" style="background-image: url({{ featured.image }})">
<div class="pixels"></div>
<div class="gradient"></div>
<div class="content">
<time datetime="{{ featured.date | date_to_xmlschema }}" class="date">
{% if site.date_format == nil %}
{{ featured.date | date: "%m.%d.%Y" }}
{% else %}
{{ featured.date | date: site.date_format }}
{% endif %}
</time>
<h1 class="title">{{ featured.title }}</h1>
<p class="description">{{ featured.subtitle }}</p>
<div class="buttons">
<a href="{{ featured.url | prepend: site.baseurl }}" role="button" class="button">
<svg><use xlink:href="#icon-read"></use></svg>
<span>{{ site.translations.button.read_now | default: "Check it Out" }}</span>
</a>
</div>
</div>
</section>
{% endif %}
<!-- Posts -->
<section id="grid" class="row flex-grid">
{% for post in posts offset: offset %}
<article class="box-item">
<span class="category">
<a href="{{ site.baseurl }}/{{ site.categories_folder | default: 'category' }}/{{ post.category }}">
<span>{{ post.category }}</span>
</a>
</span>
<div class="box-body">
<a class="cover" href="{{ post.url | prepend: site.baseurl }}">
{% include loader.html %}
{% if post.optimized_image %}
<img src="/assets/img/placeholder.png" width="100%" data-url="{{ post.optimized_image }}" class="preload">
<noscript>
<img src="{{ post.optimized_image }}" width="100%">
</noscript>
{% elsif post.image %}
<img src="/assets/img/placeholder.png" width="100%" data-url="{{ post.image }}" class="preload">
<noscript>
<img src="{{ post.image }}" width="100%">
</noscript>
{% else %}
<img src="/assets/img/placeholder.png" width="100%" data-url="/assets/img/off.jpg" class="preload">
<noscript>
<img src="/assets/img/off.jpg" width="100%">
</noscript>
{% endif %}
{% include new-post-tag.html date=post.date %}
{% include read-icon.html %}
</a>
<div class="box-info">
<time datetime="{{ post.date | date_to_xmlschema }}" class="date">
{% include date.html date=post.date %}
</time>
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">
<h2 class="post-title">
{{ post.title }}
</h2>
</a>
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">
<p class="description">{{ post.description }}</p>
</a>
<div class="tags">
{% for tag in post.tags %}
{% if tag != "" %}
<a href="{{ site.baseurl}}/tags/#{{tag | slugify }}">#{{ tag }}</a>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</article>
{% endfor %}
</section>
<!-- Pagination -->
{% if site.paginate %}
{% include pagination-home.html %}
{% endif %}
</main>
{% include site-social-urls.html %}
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "WebPage",
"mainEntity": {
"@type": "Blog",
"name": "{{ site.name }}",
"headline": "{{ site.title }}",
"description": "{{ site.description }}",
"url": "{{ site.url }}{{site.baseurl}}/",
"inLanguage": "{{ site.language }}",
"isFamilyFriendly": "true",
"creator": {
"@type": "Organization",
"name": "{{ site.name }}",
"url": "{{ site.url }}{{site.baseurl}}/",
"sameAs": [
{{ social_urls | split: "," | join: "," }}
]
},
"mainEntity": {
"@type": "ItemList",
"itemListElement": [
{% assign limit = 8 %}
{% for post in posts limit: limit %}
{% assign author = site.authors | where: "name", post.author | first %}
{
"@type": "BlogPosting",
"name": "{{ post.title }}",
"headline": "{{ post.subtitle }}",
"description": "{{ post.description }}",
"image": "{{ post.image }}",
"url": "{{ post.url | prepend: site.baseurl | prepend: site.url }}",
"inLanguage": "{{ site.language }}",
"dateCreated": "{{ post.date | date: '%Y-%m-%d/' }}",
"datePublished": "{{ post.date | date: '%Y-%m-%d/' }}",
"dateModified": "{{ post.date | date: '%Y-%m-%d/' }}",
"author": {
"@type": "Person",
"name": "{{ author.display_name }}",
"url": "{{ author.url | prepend: site.baseurl | prepend: site.url }}"
},
"publisher": {
"@type": "Organization",
"name": "{{ site.name }}",
"url": "{{ site.url }}{{site.baseurl}}/",
"logo": {
"@type": "ImageObject",
"url": "{{ site.url }}{{site.baseurl}}/assets/img/blog-image.png",
"width": "600",
"height": "315"
}
},
"mainEntityOfPage": "True",
"genre": "{{ post.category | capitalize }}",
"articleSection": "{{ post.category | capitalize }}",
"keywords": [{{ post.tags | join: '","' | append: '"' | prepend: '"' }}]
}{% if forloop.last == false %},{% endif %}
{% endfor %}
]
}
}
}
</script>

28
_layouts/main.html Normal file
View File

@ -0,0 +1,28 @@
---
layout: compress
---
<!DOCTYPE html>
<html lang="{{ site.language }}" class="no-js">
{% include head.html %}
<body class="main-page has-push-menu">
{% include svg-icons.html %}
{% include header.html %}
<section class="content">
{{ content }}
</section>
{% include footer.html %}
<script>
if (window.netlifyIdentity) {
window.netlifyIdentity.on("init", function(user) {
if (!user) {
window.netlifyIdentity.on("login", function() {
document.location.href = "/admin/";
});
}
});
}
</script>
</body>
</html>

View File

@ -0,0 +1,18 @@
---
layout: default
---
<style type="text/css" media="screen">
.container {
margin: 0px auto;
max-width: 600px;
text-align: center;
padding-top: 60px;
}
</style>
<div class="container">
<img src="/assets/img/message.gif" width="540" alt="{{ site.translations.contact.after_send.title | default: 'Message sent!' }}">
<p><strong>{{ site.translations.contact.after_send.title | default: "Message sent!" }}</strong></p>
<p>{{ site.translations.contact.after_send.message | default: "Thank you for sending me a message. I'm going to answer ASAP." }}</p>
</div>

18
_layouts/minimal.html Normal file
View File

@ -0,0 +1,18 @@
---
layout: compress
---
<!DOCTYPE html>
<html lang="{{ site.language }}" class="no-js">
{% include head.html %}
<body class="has-push-menu">
{% include svg-icons.html %}
{% include header.html %}
<section class="post">
<article id="post" class="post-content fullwidth" role="main">
{{ content }}
</article>
</section>
{% include footer.html %}
</body>
</html>

11
_layouts/page.html Normal file
View File

@ -0,0 +1,11 @@
---
layout: default
---
<div class="post">
<article class="post-content fullwidth">
{{ content }}
</article>
</div>

165
_layouts/post.html Normal file
View File

@ -0,0 +1,165 @@
<!DOCTYPE html>
<html lang="{{ site.language }}" class="no-js">
{% include head.html %}
<body class="main-page has-push-menu">
{% include minutes-to-read.html %}
{% include svg-icons.html %}
{% include header.html %}
<section class="post {% if site.two_columns_layout %}two-columns{% else %}one-column{% endif %}">
<article role="article" class="post-content">
<p class="post-info">
{% if page.date %}
<svg class="icon-calendar" id="date"><use xlink:href="#icon-calendar"></use></svg>
<time class="date" datetime="{{ page.date | date_to_xmlschema }}">
{% include date.html date=page.date %}
</time>
{% endif %}
<svg id="clock" class="icon-clock"><use xlink:href="#icon-clock"></use></svg>
<span>{{ minutesText }}</span>
</p>
<h1 class="post-title">{{ page.title }}</h1>
<p class="post-subtitle">{{ page.subtitle }}</p>
{% if page.image and paginator.activated == nil %}
<img src="{{ page.image }}" alt="Featured image" class="post-cover">
{% endif %}
{% include pagination-post.html progressBar=true %}
{% include toc.html %}
{{ content }}
{% include pagination-post.html %}
</article>
{% if site.two_columns_layout %}
<aside class="see-also">
<h2>{{ site.translations.text.see_also | default: "See also" }}</h2>
<ul>
{% assign next_posts = site.posts | where_exp:"post","post.is_generated != true" | where_exp:"post","post.path != page.path" %}
{% assign shuffled_array = next_posts | shuffle %}
{% for post in shuffled_array limit:3 %}
<li>
<a href="{{ post.url | prepend: site.baseurl }}">
{% if post.optimized_image %}
<img src="{{ post.optimized_image }}">
{% elsif post.image %}
<img src="{{ post.image }}">
{% else %}
<img src="/assets/img/off.jpg">
{% endif %}
<h3>{{ post.title }}</h3>
</a>
</li>
{% endfor %}
</ul>
</aside>
{% endif %}
</section>
<!-- Add time bar only for pages without pagination -->
{% if paginator.activated == nil and site.show_time_bar == true %}
{% include time-bar.html %}
{% include recommendation.html %}
{% endif %}
<!-- Show modal if the post is the last one -->
{% if paginator.is_last and site.show_modal_on_finish_post %}
{% include modal.html title="You made it!" subtitle="Why don't you try another?" %}
{% endif %}
<!-- Show modal before user leaves the page -->
{% if site.show_modal_on_exit %}
{% include modal.html title="Don't go yet!" subtitle="You may also like..." closed=true showOnExit=true %}
{% endif %}
{% include subscription.html %}
{% include share.html %}
{% include author.html %}
{% include comments.html %}
{% include footer.html %}
{% assign author = site.authors | where: "name", post.author | first %}
{% assign author_urls = '' %}
{% if author.github_username %}
{% assign author_urls = author_urls | append: '"https://github.com/' | append: author.github_username | append: '",' %}
{% endif %}
{% if author.facebook_username %}
{% assign author_urls = author_urls | append: '"https://www.facebook.com/' | append: author.facebook_username | append: '",' %}
{% endif %}
{% if author.twitter_username %}
{% assign author_urls = author_urls | append: '"https://twitter.com/' | append: author.twitter_username | append: '",' %}
{% endif %}
{% if author.medium_username %}
{% assign author_urls = author_urls | append: '"https://medium.com/@' | append: author.medium_username | append: '",' %}
{% endif %}
{% if author.instagram_username %}
{% assign author_urls = author_urls | append: '"https://www.instagram.com/' | append: author.instagram_username | append: '",' %}
{% endif %}
{% if author.linkedin_username %}
{% assign author_urls = author_urls | append: '"https://www.linkedin.com/in/' | append: author.linkedin_username | append: '",' %}
{% endif %}
{% if page.math %}
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
}
};
</script>
<script type="text/javascript" id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>
{% endif %}
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BlogPosting",
"name": "{{ page.title }}",
"headline": "{{ page.subtitle }}",
"description": "{{ page.description }}",
"image": "{{ page.image }}",
"url": "{{ page.url | prepend: site.baseurl | prepend: site.url }}",
"articleBody": "{{ content | strip_html | xml_escape | textilize }}",
"wordcount": "{{ content | number_of_words }}",
"inLanguage": "{{ site.language }}",
"dateCreated": "{{ page.date | date: '%Y-%m-%d/' }}",
"datePublished": "{{ page.date | date: '%Y-%m-%d/' }}",
"dateModified": "{{ page.date | date: '%Y-%m-%d/' }}",
"author": {
"@type": "Person",
"name": "{{ author.display_name }}",
{% if author.photo %}
"image": "{{ author.photo }}",
{% else %}
"image": {{ "/assets/img/user.jpg" | prepend: site.baseurl | prepend: site.url }},
{% endif %}
"jobTitle": "{{ author.position }}",
"url": "{{ author.url | prepend: site.baseurl | prepend: site.url }}",
"sameAs": [
{{ author_urls | split: "," | join: "," }}
]
},
"publisher": {
"@type": "Organization",
"name": "{{ site.name }}",
"url": "{{ site.url }}{{site.baseurl}}/",
"logo": {
"@type": "ImageObject",
"url": "{{ site.url }}{{site.baseurl}}/assets/img/blog-image.png",
"width": "600",
"height": "315"
}
},
"mainEntityOfPage": "True",
"genre": "{{ page.category }}",
"articleSection": "{{ page.category }}",
"keywords": [{{ page.tags | join: '","' | append: '"' | prepend: '"' }}]
}
</script>
</body>
</html>

15
_layouts/search.html Normal file
View File

@ -0,0 +1,15 @@
---
---
[
{% assign posts = site.posts | where_exp:"post","post.is_generated != true" %}
{% assign date_format = site.date_format | default: "%m/%d/%Y" %}
{% for post in posts %}
{
"title" : "{{ post.title | escape }}",
"tags" : "{{ post.tags | array_to_sentence_string }}",
"categories" : "{{ post.category }}",
"url" : "{{ site.baseurl }}{{ post.url }}",
"date" : "{{ post.date | date: date_format }}"
} {% unless forloop.last %},{% endunless %}
{% endfor %}
]

38
_layouts/tags.html Normal file
View File

@ -0,0 +1,38 @@
---
layout: minimal
---
{% assign date_format = site.date_format | default: "%m/%d/%Y" %}
<div class="tags">
{% assign tags_list = site.tags %}
{% if tags_list.first[0] == null %}
{% for tag in tags_list %}
<a href="#{{ tag | slugify }}">#{{ tag }}</a>
{% endfor %}
{% else %}
{% for tag in tags_list %}
<a href="#{{ tag[0] | slugify }}">#{{ tag[0] }}</a>
{% endfor %}
{% endif %}
{% assign tags_list = nil %}
</div>
{% for tag in site.tags %}
<a class="post-anchor" id="{{ tag[0] | slugify }}"></a>
<div class="tag-title">
<span>#{{ tag[0] }}</span>
</div>
<ul class="post-list">
{% assign pages_list = tag[1] %}
{% for post in pages_list reversed %}
{% if post.title != null and post.is_generated != true %}
{% if group == null or group == post.group %}
<li><a href="{{ site.url }}{{ site.baseurl }}{{ post.url }}">{{ post.title }}<span class="entry-date"><time datetime="{{ post.date | date_to_xmlschema }}">{{ post.date | date: date_format }}</time></a></li>
{% endif %}
{% endif %}
{% endfor %}
{% assign pages_list = nil %}
{% assign group = nil %}
</ul>
{% endfor %}

View File

@ -0,0 +1,9 @@
module Jekyll
module ShuffleFilter
def shuffle(array)
array.shuffle
end
end
end
Liquid::Template.register_filter(Jekyll::ShuffleFilter)

62
_plugins/tags/figure.rb Normal file
View File

@ -0,0 +1,62 @@
require 'json'
module Jekyll
class RenderFigureTag < Liquid::Tag
def initialize(tag_name, input, tokens)
super
@input = input
end
def render(context)
output = "<figure>"
image = ""
alt = ""
classes = ""
width = ""
height = ""
caption = ""
begin
if( !@input.nil? && !@input.empty? )
jdata = JSON.parse(@input)
if( jdata.key?("image") )
image = jdata["image"].strip
output += "<img src=\"" + image + "\""
if( jdata.key?("alt") )
alt = jdata["alt"].strip
output += " alt=\"" + alt + "\""
end
if( jdata.key?("classes") )
classes = jdata["classes"].strip
output += " class=\"" + classes + "\""
end
if( jdata.key?("width") )
width = jdata["width"].strip
output += " width=\"" + width + "\""
end
if( jdata.key?("height") )
height = jdata["height"].strip
output += " height=\"" + height + "\""
end
output += ">"
end
if( jdata.key?("caption") )
caption = jdata["caption"].strip
output += "<figcaption>" + caption + "</figcaption>"
end
end
rescue
end
output += "</figure>"
return output
end
end
end
Liquid::Template.register_tag('figure', Jekyll::RenderFigureTag)

View File

@ -0,0 +1,62 @@
require 'json'
module Jekyll
class RenderFigureUrlTag < Liquid::Tag
def initialize(tag_name, input, tokens)
super
@input = input
end
def render(context)
output = "<figure>"
image = ""
alt = ""
classes = ""
width = ""
height = ""
caption = ""
begin
if( !@input.nil? && !@input.empty? )
jdata = JSON.parse(@input)
if( jdata.key?("image") )
image = jdata["image"].strip
output += "<img src=\"" + image + "\""
if( jdata.key?("alt") )
alt = jdata["alt"].strip
output += " alt=\"" + alt + "\""
end
if( jdata.key?("classes") )
classes = jdata["classes"].strip
output += " class=\"" + classes + "\""
end
if( jdata.key?("width") )
width = jdata["width"].strip
output += " width=\"" + width + "\""
end
if( jdata.key?("height") )
height = jdata["height"].strip
output += " height=\"" + height + "\""
end
output += ">"
end
if( jdata.key?("caption") )
caption = jdata["caption"].strip
output += "<figcaption>" + caption + "</figcaption>"
end
end
rescue
end
output += "</figure>"
return output
end
end
end
Liquid::Template.register_tag('figure_url', Jekyll::RenderFigureUrlTag)

View File

@ -0,0 +1,51 @@
body.main-page,
body.main-page blockquote *
{
background-color: #141414;
color: #ffffff;
}
body.main-page aside.see-also a,
body.main-page section.author a
{
color: #ffffff;
}
body.main-page > section.share a
{
fill: #808080;
color: #808080;
}
body.main-page > section.author
{
background-color: #1a1a1a;
color: #ffffff;
}
body.main-page > section.author a > img,
footer a > img
{
display: inline-block;
margin-right: 12px;
width: 24px;
height: 24px;
float: none;
border-radius: 999px;
background-color: #808080;
}
body.main-page > section.author a > img,
footer a > img,
body.main-page > section.author a > svg,
footer a > svg
{
vertical-align: middle;
}
iframe.AppFrame
{
height: calc(100vh - 4rem);
border: none;
overflow: hidden;
}

65
_sass/_animations.scss Normal file
View File

@ -0,0 +1,65 @@
.flex-grid article {
opacity: 0;
}
.flex-grid article.shown {
opacity: 1;
}
.flex-grid article.animate {
animation: moveUp 0.65s;
opacity: 1;
}
@keyframes moveUp {
from {
transform: translateY(200px);
}
to {
transform: translateY(0);
}
}
@keyframes shake {
2%,
18% {
transform: translate3d(-1px, 0, 0);
}
4%,
16% {
transform: translate3d(2px, 0, 0);
}
6%,
10%,
14% {
transform: translate3d(-4px, 0, 0);
}
8%,
12% {
transform: translate3d(4px, 0, 0);
}
}
@keyframes zoomIn {
50% {
transform: translate(-50%, -50%) scale(1.1);
}
}
@keyframes pulse {
0% {
transform: scale(0.8);
}
100% {
transform: scale(1);
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

91
_sass/_author.scss Normal file
View File

@ -0,0 +1,91 @@
.author {
background: $lightGray;
display: table;
width: 100%;
padding: rem(40px) 0;
margin: rem(40px) 0;
@include media(">=sm") {
padding: rem(50px) 0;
}
.details {
margin: auto;
max-width: rem(800px);
padding: 0 rem(20px);
@include media("<sm") {
text-align: center;
}
}
svg {
@include size(25, 25);
margin-right: rem(10px);
}
a {
fill: darken($lightGray, 30%);
text-decoration: none;
border: none;
transition: all 0.3s;
&:hover {
fill: $themeColor;
}
}
img {
width: rem(150px);
border-radius: 50%;
display: block;
margin: auto;
@include media(">=sm") {
width: rem(180px);
float: left;
margin-right: 3.125rem;
}
}
.def {
color: gray;
font-size: rem(18px);
@include mainFont(300);
margin: rem(10px);
@include media(">=sm") {
margin: 0;
}
}
.name {
margin: 0;
a {
@include mainFont();
text-decoration: none;
color: black;
font-size: rem(30px);
@include media(">=sm") {
font-size: rem(45px);
}
&:hover {
color: $texts;
}
}
}
.desc {
@include mainFont(300);
margin: rem(10px);
font-size: rem(16px);
line-height: rem(25px);
@include media(">=sm") {
font-size: rem(18px);
}
}
}

3
_sass/_elements.scss Normal file
View File

@ -0,0 +1,3 @@
.img-rounded {
border-radius: 50%;
}

98
_sass/_footer.scss Normal file
View File

@ -0,0 +1,98 @@
.comments {
@include center(rem(800px));
padding: 0 rem(20px);
h3 {
margin: 0 0 rem(30px);
font-size: rem(30px);
}
}
footer {
@include center(rem(800px));
border-top: 1px solid darken($accentDark, 10%);
background: $accentDark;
padding: rem(20px) rem(25px);
margin-top: rem(50px);
margin-bottom: rem(120px);
@include mainFont(300);
@include media(">=sm") {
margin-top: rem(100px);
}
p {
text-decoration: none;
color: $primaryDark;
font-size: rem(16px);
line-height: rem(25px);
}
span {
font-weight: 700;
}
svg {
@include size(28, 28);
display: inline-block;
vertical-align: middle;
margin-right: rem(10px);
@include media(">=sm") {
margin-right: rem(20px);
}
&.love {
@include size(20, 20);
fill: $themeColor;
margin-top: rem(-2px);
margin-left: rem(3px);
margin-right: rem(3px);
}
}
a {
display: inline-block;
fill: #808080;
transition: all 0.3s ease;
text-decoration: none;
color: #808080;
&:hover {
fill: $themeColor;
}
&.creator:hover {
text-decoration: underline;
}
}
ul {
padding: 0;
list-style-type: none;
li {
margin-bottom: rem(10px);
}
a {
text-decoration: none;
font-size: rem(15px);
&:hover {
text-decoration: underline;
}
}
}
}
.main-page {
footer {
background: $primaryDark;
border-top: 1px solid lighten($primaryDark, 10%);
p {
color: $accentDark;
}
}
}

69
_sass/_form.scss Normal file
View File

@ -0,0 +1,69 @@
.contact-form {
@include mainFont();
padding: rem(10px);
fieldset {
border: none;
font-weight: normal;
}
input[type="text"],
input[type="email"],
textarea {
box-sizing: border-box;
outline: none;
display: block;
color: #333333;
width: 100%;
padding: 7px;
border: none;
border-bottom: 1px solid #ddd;
margin-bottom: 10px;
font-family: inherit;
font-size: rem(18px);
height: rem(45px);
&.has-error {
border-color: #f04242;
}
}
textarea {
height: rem(200px);
}
span {
display: block;
font-size: rem(14px);
color: #f04242;
padding-bottom: rem(10px);
}
button[type="submit"] {
display: block;
padding: rem(14px) rem(39px) rem(14px) rem(39px);
color: #ffffff;
background: $themeColor;
font-size: rem(18px);
width: 100%;
border: 1px solid darken($themeColor, 30%);
border-width: 1px 1px 3px;
margin-top: rem(50px);
margin-bottom: rem(10px);
cursor: pointer;
transition: all 0.3s;
outline: none;
&:hover {
background: darken($themeColor, 20%);
}
@include media(">=sm") {
padding: rem(19px) rem(39px) rem(18px) rem(39px);
}
}
[v-cloak] {
display: none;
}
}

3
_sass/_functions.scss Normal file
View File

@ -0,0 +1,3 @@
@function rem($pixels) {
@return ($pixels / 16px) * 1rem;
}

150
_sass/_header.scss Normal file
View File

@ -0,0 +1,150 @@
html,
body {
height: 100%;
}
.bar-header {
background-color: $primaryDark;
padding: rem(10px) rem(15px);
position: fixed;
left: 0;
width: 100%;
z-index: 10;
transition: top 0.5s, left 0.3s ease, background-color 0.5s, box-shadow 0.5s;
@include media(">=sm") {
padding: rem(15px) rem(0px);
}
.logo {
display: inline-block;
margin: 0;
height: rem(32px);
line-height: rem(32px);
a {
display: block;
color: $accentDark;
text-decoration: none;
font-size: rem(32px);
position: relative;
outline: 0;
}
svg {
width: rem(120px);
height: rem(30px);
transition: all .4s;
@include media(">=sm") {
width: rem(205px);
}
}
}
.version {
color: $accentDark;
font-size: rem(10px);
font-weight: normal;
line-height: 1;
position: absolute;
top: 0;
right: 0;
display: block;
transform: translateX(110%);
opacity: 0.3;
}
.icon-menu {
float: left;
cursor: pointer;
margin: rem(5px) rem(20px) rem(5px) 0;
width: rem(20px);
height: rem(20px);
fill: $accentDark;
@include media(">=sm") {
margin: rem(5px) rem(20px) rem(5px) rem(25px);
}
}
.dosearch {
float: right;
width: rem(30px);
height: rem(30px);
cursor: pointer;
margin: 0;
@include media(">=sm") {
margin: 0 rem(20px) 0 0;
}
}
.icon-search {
width: rem(20px);
height: rem(20px);
fill: $accentDark;
margin: rem(5px);
}
.get-theme {
display: none;
font-size: rem(13px);
font-weight: bold;
text-decoration: none;
background-color: $themeColor;
color: $accentDark;
padding: rem(5px) rem(10px);
border-radius: rem(5px);
float: right;
margin: rem(5px) rem(15px) rem(5px) rem(5px);
@include media(">=sm") {
display: inline-block;
}
}
}
body.main-page {
background-color: #141414;
.bar-header {
background-color: rgba(0, 0, 0, 0.85);
}
}
body.light:not(.main-page) {
.bar-header {
box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.1);
background-color: rgba(255, 255, 255, 0.95);
.icon-search,
.icon-menu {
fill: $primaryDark;
}
.logo a,
.version {
color: $primaryDark;
}
}
}
.overlay {
position: fixed;
width: 100%;
height: 100%;
top: 0;
right: 0;
left: 0;
bottom: 0;
pointer-events: none;
background: rgba(0, 0, 0, 0.6);
z-index: 17;
opacity: 0;
transition: all 0.3s;
&.show {
pointer-events: auto;
opacity: 1;
}
}

108
_sass/_hero.scss Normal file
View File

@ -0,0 +1,108 @@
.hero {
position: relative;
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
width: 100%;
height: 100vh;
+#grid {
margin-top: rem(-80px);
}
.gradient,
.pixels {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.pixels {
opacity: 0.8;
background-image: url(../../assets/img/pixels.png);
}
.gradient {
background-image: linear-gradient(0deg, rgba(20, 20, 20, 1) 5%, rgba(0, 0, 0, 0) 30%);
}
.content {
display: flex;
justify-content: center;
flex-direction: column;
position: absolute;
width: 80%;
height: 100%;
padding-left: 10%;
@include media(">=sm") {
width: 50%;
}
.date {
font-size: rem(16px);
color: rgba(255, 255, 255, 0.75);
}
.title {
font-size: rem(40px);
color: #fff;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
margin: rem(10px) 0;
@include media(">=sm") {
font-size: rem(50px);
}
}
.description {
font-size: rem(24px);
color: #fff;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
margin: 0;
@include media(">=sm") {
font-size: rem(26px);
}
}
.buttons {
margin-top: rem(50px);
}
.button {
display: inline-block;
font-size: rem(18px);
font-weight: bold;
color: #fff;
text-decoration: none;
background-color: rgba(0, 0, 0, 0.6);
border-radius: rem(5px);
padding: rem(10px) rem(15px);
transition: all 0.3s;
@include media(">=sm") {
font-size: rem(18px);
}
&:hover {
background-color: rgba(255, 255, 255, 0.5);
box-shadow: 2px 2px 3px 0px rgba(0, 0, 0, 0.2);
}
svg {
width: rem(25px);
height: rem(25px);
margin-right: rem(10px);
vertical-align: middle;
color: $themeColor;
}
span {
vertical-align: middle;
}
}
}
}

140
_sass/_highlight.scss Normal file
View File

@ -0,0 +1,140 @@
pre {
background: #282a36;
width: 100%;
padding: rem(20px) 0;
color: $accentDark;
margin: rem(30px) 0;
font-size: rem(14px);
@include media(">=sm") {
font-size: rem(16px);
padding: rem(40px) 0;
margin: rem(50px) 0;
}
code {
@include center(rem(800px));
padding: 0 rem(20px);
@include media("<sm") {
overflow-x: scroll;
}
}
span {
line-height: 1.5rem;
font-family: "Monaco", "Consolas", "Menlo", monospace;
}
}
.highlight {
margin: rem(20px) 0;
@include media(">=sm") {
word-wrap: break-word;
margin: rem(29px) 0;
}
.hll {
background-color: #282a36;
}
.c, // Comment
.cm, // Comment.Multiline
.cp, // Comment.Preproc
.c1, // Comment.Single
.cs { // Comment.Special
color: #6272a4;
}
.err { // Error
color: #ff5555;
background-color: #282a36;
}
.kc, // Keyword.Constant
.kp, // Keyword.Pseudo
.kr, // Keyword.Reserved
.kt, // Keyword.Type
.no { // Name.Constant
color: #66d9ef;
}
.l, // Literal
.mf, // Literal.Number.Float
.mh, // Literal.Number.Hex
.mi, // Literal.Number.Integer
.mo, // Literal.Number.Oct
.se, // Literal.String.Escape
.il { // Literal.Number.Integer.Long
color: #ae81ff;
}
.p, // Punctuation
.nx { // Name.Other
color: #f7f7f2;
}
.ni, // Name.Entity
.nn, // Name.Namespace
.py, // Name.Property
.nv, // Name.Variable
.w, // Text.Whitespace
.bp, // Name.Builtin.Pseudo
.vc, // Name.Variable.Class
.vg, // Name.Variable.Global
.vi { // Name.Variable.Instance
color: #50fa7b;
}
.nl { // Name.Label
color: #8be9fd;
}
.n, // Name
.nb, // Name.Builtin
.m { // Literal.Number
color: #bd93f9;
}
.nt, // Name.Tag
.k, // Keyword
.kn, // Keyword.Namespace
.kd, // Keyword.Declaration
.o, // Operator
.ow { // Operator.Word
color: #ff79c6;
}
.ge { // Generic.Emph
font-style: italic;
}
.gs { // Generic.Strong
font-weight: bold;
}
.ld, // Literal.Date
.s, // Literal.String
.sb, // Literal.String.Backtick
.sc, // Literal.String.Char
.sd, // Literal.String.Doc
.s2, // Literal.String.Double
.sh, // Literal.String.Heredoc
.si, // Literal.String.Interpol
.sx, // Literal.String.Other
.sr, // Literal.String.Regex
.s1, // Literal.String.Single
.ss, // Literal.String.Symbol
.vglnk { // Link
color: #f1fa8c;
}
.na, // Name.Attribute
.nc, // Name.Class
.nd, // Name.Decorator
.ne, // Name.Exception
.nf { // Name.Function
color: #50fa7b;
}
}

218
_sass/_home.scss Normal file
View File

@ -0,0 +1,218 @@
.home {
@include mainFont(400);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding-top: rem(80px);
@include media(">=sm") {
padding-top: rem(100px);
}
&.no-padding {
padding-top: 0;
}
}
.row {
@include center(100%);
margin: 0px rem($rowMargin);
}
.flex-grid {
display: flex;
flex-flow: row wrap;
}
.title-category {
font-size: rem(32px);
margin: 0 0 rem(40px);
padding: 0 rem(23px);
text-transform: lowercase;
color: #fff;
}
.box-item {
flex: 1 0 $itemMinWidth;
margin: 0 0 rem(30px);
display: inline-block;
min-height: rem(285px);
transition: all 0.3s;
position: relative;
z-index: 1;
@include media(">=sm") {
margin: 0 rem($itemMargin) rem(30px);
}
// Note 1: This complex calc right here is what makes the leftover box items
// have the same width than their siblings.
@for $n from 2 through $maxItemsPerRow {
$resolution: (2 * $rowMargin) + ($n * $itemMinWidth);
@include media(">=#{$resolution}") {
max-width: calc(100%/#{$n} - #{$itemMargin * 2});
}
}
// Note 2: This sets the maximum number of box items per row.
@include media(">=#{(2 * $rowMargin) + ($maxItemsPerRow * $itemMinWidth)}") {
flex: 1 0 calc(100%/#{$maxItemsPerRow} - #{$itemMargin * 2});
}
&:hover {
z-index: 2;
transform: scale(1.1);
img {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
transform: scale(1.05);
}
.box-body {
time,
p {
color: $accentDark;
}
.cover {
.new-post-tag {
background-color: #000;
}
.read-icon {
opacity: 1;
}
}
}
}
a {
text-decoration: none;
display: block;
}
.category {
display: block;
height: rem(36px);
line-height: rem(36px);
text-transform: uppercase;
font-weight: bold;
font-size: rem(18px);
padding: 0 rem(15px);
a {
color: $accentDark;
}
}
.box-body {
img {
width: 100%;
height: auto;
margin: 0 auto;
transition: all 0.2s ease-in-out;
}
time {
font-weight: 300;
font-size: rem(16px);
color: darken($lightGray, 50%);
pointer-events: none;
}
h2 {
margin: rem(10px) 0;
font-size: rem(24px);
@include mainFont(800);
color: $accentDark;
line-height: rem(30px);
}
p {
margin: 0 0 rem(30px);
color: darken($lightGray, 20%);
font-size: rem(17px);
line-height: rem(26px);
}
.tags a {
height: rem(30px);
line-height: rem(26px);
color: $accentDark;
padding: 0 rem(10px);
border: 1px solid $accentDark;
border-radius: 15px;
display: inline-block;
margin: 0 rem(10px) rem(10px) 0;
z-index: 50;
&:hover {
color: $primaryDark;
background: $accentDark;
border-color: $accentDark;
}
}
.cover {
position: relative;
display: block;
.loader {
position: absolute;
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0);
color: $themeColor;
z-index: 1;
}
img {
position: relative;
z-index: 2;
}
.new-post-tag {
text-transform: uppercase;
display: inline-block;
background: $themeColor;
color: #fff;
font-size: rem(13px);
font-weight: 700;
line-height: rem(24px);
padding: 0 rem(8px);
position: absolute;
bottom: rem(8px);
left: 0;
z-index: 3;
}
.read-icon {
opacity: 0;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
align-items: center;
justify-content: center;
content: "";
width: rem(80px);
height: rem(80px);
border-radius: 40px;
position: absolute;
top: 50%;
left: 50%;
margin-top: rem(-40px);
margin-left: rem(-40px);
border: 2px solid #fff;
color: $themeColor;
z-index: 4;
svg {
width: rem(48px);
}
}
}
}
.box-info {
padding: rem(15px);
}
}

45
_sass/_icons.scss Normal file
View File

@ -0,0 +1,45 @@
.icons-home {
text-align: center;
a {
display: inline-block;
padding: rem(15px);
margin: rem(2px);
border-radius: 50%;
border: rem(2px) solid $accentDark;
line-height: 0;
transition: all 0.7s;
.icon {
fill: $accentDark;
@include size(18, 18);
@include media(">=sm") {
@include size();
}
}
&:hover {
background: $accentDark;
.icon {
fill: $texts;
}
}
}
}
.down {
position: absolute;
bottom: 50px;
width: 100%;
display: block;
text-align: center;
.icon {
@include align(both);
@include size(100, 100);
fill: $accentDark;
animation: pulse 1.3s infinite;
}
}

569
_sass/_include-media.scss Normal file
View File

@ -0,0 +1,569 @@
@charset "UTF-8";
// _ _ _ _ _
// (_) | | | | | (_)
// _ _ __ ___| |_ _ __| | ___ _ __ ___ ___ __| |_ __ _
// | | '_ \ / __| | | | |/ _` |/ _ \ | '_ ` _ \ / _ \/ _` | |/ _` |
// | | | | | (__| | |_| | (_| | __/ | | | | | | __/ (_| | | (_| |
// |_|_| |_|\___|_|\__,_|\__,_|\___| |_| |_| |_|\___|\__,_|_|\__,_|
//
// Simple, elegant and maintainable media queries in Sass
// v1.4.9
//
// http://include-media.com
//
// Authors: Eduardo Boucas (@eduardoboucas)
// Hugo Giraudel (@hugogiraudel)
//
// This project is licensed under the terms of the MIT license
////
/// include-media library public configuration
/// @author Eduardo Boucas
/// @access public
////
///
/// Creates a list of global breakpoints
///
/// @example scss - Creates a single breakpoint with the label `phone`
/// $breakpoints: ('phone': 320px);
///
$breakpoints: (
'phone': 320px,
'tablet': 768px,
'desktop': 1024px
) !default;
///
/// Creates a list of static expressions or media types
///
/// @example scss - Creates a single media type (screen)
/// $media-expressions: ('screen': 'screen');
///
/// @example scss - Creates a static expression with logical disjunction (OR operator)
/// $media-expressions: (
/// 'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)'
/// );
///
$media-expressions: (
'screen': 'screen',
'print': 'print',
'handheld': 'handheld',
'landscape': '(orientation: landscape)',
'portrait': '(orientation: portrait)',
'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx)',
'retina3x': '(-webkit-min-device-pixel-ratio: 3), (min-resolution: 350dpi), (min-resolution: 3dppx)'
) !default;
///
/// Defines a number to be added or subtracted from each unit when declaring breakpoints with exclusive intervals
///
/// @example scss - Interval for pixels is defined as `1` by default
/// @include media('>128px') {}
///
/// /* Generates: */
/// @media (min-width: 129px) {}
///
/// @example scss - Interval for ems is defined as `0.01` by default
/// @include media('>20em') {}
///
/// /* Generates: */
/// @media (min-width: 20.01em) {}
///
/// @example scss - Interval for rems is defined as `0.1` by default, to be used with `font-size: 62.5%;`
/// @include media('>2.0rem') {}
///
/// /* Generates: */
/// @media (min-width: 2.1rem) {}
///
$unit-intervals: (
'px': 1,
'em': 0.01,
'rem': 0.1,
'': 0
) !default;
///
/// Defines whether support for media queries is available, useful for creating separate stylesheets
/// for browsers that don't support media queries.
///
/// @example scss - Disables support for media queries
/// $im-media-support: false;
/// @include media('>=tablet') {
/// .foo {
/// color: tomato;
/// }
/// }
///
/// /* Generates: */
/// .foo {
/// color: tomato;
/// }
///
$im-media-support: true !default;
///
/// Selects which breakpoint to emulate when support for media queries is disabled. Media queries that start at or
/// intercept the breakpoint will be displayed, any others will be ignored.
///
/// @example scss - This media query will show because it intercepts the static breakpoint
/// $im-media-support: false;
/// $im-no-media-breakpoint: 'desktop';
/// @include media('>=tablet') {
/// .foo {
/// color: tomato;
/// }
/// }
///
/// /* Generates: */
/// .foo {
/// color: tomato;
/// }
///
/// @example scss - This media query will NOT show because it does not intercept the desktop breakpoint
/// $im-media-support: false;
/// $im-no-media-breakpoint: 'tablet';
/// @include media('>=desktop') {
/// .foo {
/// color: tomato;
/// }
/// }
///
/// /* No output */
///
$im-no-media-breakpoint: 'desktop' !default;
///
/// Selects which media expressions are allowed in an expression for it to be used when media queries
/// are not supported.
///
/// @example scss - This media query will show because it intercepts the static breakpoint and contains only accepted media expressions
/// $im-media-support: false;
/// $im-no-media-breakpoint: 'desktop';
/// $im-no-media-expressions: ('screen');
/// @include media('>=tablet', 'screen') {
/// .foo {
/// color: tomato;
/// }
/// }
///
/// /* Generates: */
/// .foo {
/// color: tomato;
/// }
///
/// @example scss - This media query will NOT show because it intercepts the static breakpoint but contains a media expression that is not accepted
/// $im-media-support: false;
/// $im-no-media-breakpoint: 'desktop';
/// $im-no-media-expressions: ('screen');
/// @include media('>=tablet', 'retina2x') {
/// .foo {
/// color: tomato;
/// }
/// }
///
/// /* No output */
///
$im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
////
/// Cross-engine logging engine
/// @author Hugo Giraudel
/// @access private
////
///
/// Log a message either with `@error` if supported
/// else with `@warn`, using `feature-exists('at-error')`
/// to detect support.
///
/// @param {String} $message - Message to log
///
@function im-log($message) {
@if feature-exists('at-error') {
@error $message;
} @else {
@warn $message;
$_: noop();
}
@return $message;
}
///
/// Wrapper mixin for the log function so it can be used with a more friendly
/// API than `@if im-log('..') {}` or `$_: im-log('..')`. Basically, use the function
/// within functions because it is not possible to include a mixin in a function
/// and use the mixin everywhere else because it's much more elegant.
///
/// @param {String} $message - Message to log
///
@mixin log($message) {
@if im-log($message) {}
}
///
/// Function with no `@return` called next to `@warn` in Sass 3.3
/// to trigger a compiling error and stop the process.
///
@function noop() {}
///
/// Determines whether a list of conditions is intercepted by the static breakpoint.
///
/// @param {Arglist} $conditions - Media query conditions
///
/// @return {Boolean} - Returns true if the conditions are intercepted by the static breakpoint
///
@function im-intercepts-static-breakpoint($conditions...) {
$no-media-breakpoint-value: map-get($breakpoints, $im-no-media-breakpoint);
@if not $no-media-breakpoint-value {
@if im-log('`#{$im-no-media-breakpoint}` is not a valid breakpoint.') {}
}
@each $condition in $conditions {
@if not map-has-key($media-expressions, $condition) {
$operator: get-expression-operator($condition);
$prefix: get-expression-prefix($operator);
$value: get-expression-value($condition, $operator);
// scss-lint:disable SpaceAroundOperator
@if ($prefix == 'max' and $value <= $no-media-breakpoint-value) or
($prefix == 'min' and $value > $no-media-breakpoint-value) {
@return false;
}
} @else if not index($im-no-media-expressions, $condition) {
@return false;
}
}
@return true;
}
////
/// Parsing engine
/// @author Hugo Giraudel
/// @access private
////
///
/// Get operator of an expression
///
/// @param {String} $expression - Expression to extract operator from
///
/// @return {String} - Any of `>=`, `>`, `<=`, `<`, ``, ``
///
@function get-expression-operator($expression) {
@each $operator in ('>=', '>', '<=', '<', '', '') {
@if str-index($expression, $operator) {
@return $operator;
}
}
// It is not possible to include a mixin inside a function, so we have to
// rely on the `im-log(..)` function rather than the `log(..)` mixin. Because
// functions cannot be called anywhere in Sass, we need to hack the call in
// a dummy variable, such as `$_`. If anybody ever raise a scoping issue with
// Sass 3.3, change this line in `@if im-log(..) {}` instead.
$_: im-log('No operator found in `#{$expression}`.');
}
///
/// Get dimension of an expression, based on a found operator
///
/// @param {String} $expression - Expression to extract dimension from
/// @param {String} $operator - Operator from `$expression`
///
/// @return {String} - `width` or `height` (or potentially anything else)
///
@function get-expression-dimension($expression, $operator) {
$operator-index: str-index($expression, $operator);
$parsed-dimension: str-slice($expression, 0, $operator-index - 1);
$dimension: 'width';
@if str-length($parsed-dimension) > 0 {
$dimension: $parsed-dimension;
}
@return $dimension;
}
///
/// Get dimension prefix based on an operator
///
/// @param {String} $operator - Operator
///
/// @return {String} - `min` or `max`
///
@function get-expression-prefix($operator) {
@return if(index(('<', '<=', ''), $operator), 'max', 'min');
}
///
/// Get value of an expression, based on a found operator
///
/// @param {String} $expression - Expression to extract value from
/// @param {String} $operator - Operator from `$expression`
///
/// @return {Number} - A numeric value
///
@function get-expression-value($expression, $operator) {
$operator-index: str-index($expression, $operator);
$value: str-slice($expression, $operator-index + str-length($operator));
@if map-has-key($breakpoints, $value) {
$value: map-get($breakpoints, $value);
} @else {
$value: to-number($value);
}
$interval: map-get($unit-intervals, unit($value));
@if not $interval {
// It is not possible to include a mixin inside a function, so we have to
// rely on the `im-log(..)` function rather than the `log(..)` mixin. Because
// functions cannot be called anywhere in Sass, we need to hack the call in
// a dummy variable, such as `$_`. If anybody ever raise a scoping issue with
// Sass 3.3, change this line in `@if im-log(..) {}` instead.
$_: im-log('Unknown unit `#{unit($value)}`.');
}
@if $operator == '>' {
$value: $value + $interval;
} @else if $operator == '<' {
$value: $value - $interval;
}
@return $value;
}
///
/// Parse an expression to return a valid media-query expression
///
/// @param {String} $expression - Expression to parse
///
/// @return {String} - Valid media query
///
@function parse-expression($expression) {
// If it is part of $media-expressions, it has no operator
// then there is no need to go any further, just return the value
@if map-has-key($media-expressions, $expression) {
@return map-get($media-expressions, $expression);
}
$operator: get-expression-operator($expression);
$dimension: get-expression-dimension($expression, $operator);
$prefix: get-expression-prefix($operator);
$value: get-expression-value($expression, $operator);
@return '(#{$prefix}-#{$dimension}: #{$value})';
}
///
/// Slice `$list` between `$start` and `$end` indexes
///
/// @access private
///
/// @param {List} $list - List to slice
/// @param {Number} $start [1] - Start index
/// @param {Number} $end [length($list)] - End index
///
/// @return {List} Sliced list
///
@function slice($list, $start: 1, $end: length($list)) {
@if length($list) < 1 or $start > $end {
@return ();
}
$result: ();
@for $i from $start through $end {
$result: append($result, nth($list, $i));
}
@return $result;
}
////
/// String to number converter
/// @author Hugo Giraudel
/// @access private
////
///
/// Casts a string into a number
///
/// @param {String | Number} $value - Value to be parsed
///
/// @return {Number}
///
@function to-number($value) {
@if type-of($value) == 'number' {
@return $value;
} @else if type-of($value) != 'string' {
$_: im-log('Value for `to-number` should be a number or a string.');
}
$first-character: str-slice($value, 1, 1);
$result: 0;
$digits: 0;
$minus: ($first-character == '-');
$numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9);
// Remove +/- sign if present at first character
@if ($first-character == '+' or $first-character == '-') {
$value: str-slice($value, 2);
}
@for $i from 1 through str-length($value) {
$character: str-slice($value, $i, $i);
@if not (index(map-keys($numbers), $character) or $character == '.') {
@return to-length(if($minus, -$result, $result), str-slice($value, $i))
}
@if $character == '.' {
$digits: 1;
} @else if $digits == 0 {
$result: $result * 10 + map-get($numbers, $character);
} @else {
$digits: $digits * 10;
$result: $result + map-get($numbers, $character) / $digits;
}
}
@return if($minus, -$result, $result);
}
///
/// Add `$unit` to `$value`
///
/// @param {Number} $value - Value to add unit to
/// @param {String} $unit - String representation of the unit
///
/// @return {Number} - `$value` expressed in `$unit`
///
@function to-length($value, $unit) {
$units: ('px': 1px, 'cm': 1cm, 'mm': 1mm, '%': 1%, 'ch': 1ch, 'pc': 1pc, 'in': 1in, 'em': 1em, 'rem': 1rem, 'pt': 1pt, 'ex': 1ex, 'vw': 1vw, 'vh': 1vh, 'vmin': 1vmin, 'vmax': 1vmax);
@if not index(map-keys($units), $unit) {
$_: im-log('Invalid unit `#{$unit}`.');
}
@return $value * map-get($units, $unit);
}
///
/// This mixin aims at redefining the configuration just for the scope of
/// the call. It is helpful when having a component needing an extended
/// configuration such as custom breakpoints (referred to as tweakpoints)
/// for instance.
///
/// @author Hugo Giraudel
///
/// @param {Map} $tweakpoints [()] - Map of tweakpoints to be merged with `$breakpoints`
/// @param {Map} $tweak-media-expressions [()] - Map of tweaked media expressions to be merged with `$media-expression`
///
/// @example scss - Extend the global breakpoints with a tweakpoint
/// @include media-context(('custom': 678px)) {
/// .foo {
/// @include media('>phone', '<=custom') {
/// // ...
/// }
/// }
/// }
///
/// @example scss - Extend the global media expressions with a custom one
/// @include media-context($tweak-media-expressions: ('all': 'all')) {
/// .foo {
/// @include media('all', '>phone') {
/// // ...
/// }
/// }
/// }
///
/// @example scss - Extend both configuration maps
/// @include media-context(('custom': 678px), ('all': 'all')) {
/// .foo {
/// @include media('all', '>phone', '<=custom') {
/// // ...
/// }
/// }
/// }
///
@mixin media-context($tweakpoints: (), $tweak-media-expressions: ()) {
// Save global configuration
$global-breakpoints: $breakpoints;
$global-media-expressions: $media-expressions;
// Update global configuration
$breakpoints: map-merge($breakpoints, $tweakpoints) !global;
$media-expressions: map-merge($media-expressions, $tweak-media-expressions) !global;
@content;
// Restore global configuration
$breakpoints: $global-breakpoints !global;
$media-expressions: $global-media-expressions !global;
}
////
/// include-media public exposed API
/// @author Eduardo Boucas
/// @access public
////
///
/// Generates a media query based on a list of conditions
///
/// @param {Arglist} $conditions - Media query conditions
///
/// @example scss - With a single set breakpoint
/// @include media('>phone') { }
///
/// @example scss - With two set breakpoints
/// @include media('>phone', '<=tablet') { }
///
/// @example scss - With custom values
/// @include media('>=358px', '<850px') { }
///
/// @example scss - With set breakpoints with custom values
/// @include media('>desktop', '<=1350px') { }
///
/// @example scss - With a static expression
/// @include media('retina2x') { }
///
/// @example scss - Mixing everything
/// @include media('>=350px', '<tablet', 'retina3x') { }
///
@mixin media($conditions...) {
// scss-lint:disable SpaceAroundOperator
@if ($im-media-support and length($conditions) == 0) or
(not $im-media-support and im-intercepts-static-breakpoint($conditions...)) {
@content;
} @else if ($im-media-support and length($conditions) > 0) {
@media #{unquote(parse-expression(nth($conditions, 1)))} {
// Recursive call
@include media(slice($conditions, 2)...) {
@content;
}
}
}
}

90
_sass/_menu.scss Normal file
View File

@ -0,0 +1,90 @@
*,
*:before,
*:after {
box-sizing: border-box;
}
body.has-push-menu,
body.has-push-menu aside,
body.has-push-menu .progress-bar {
transition: all 0.3s ease;
}
body.has-push-menu {
overflow-x: hidden;
position: relative;
left: 0;
&.push-menu-to-right {
left: rem(240px);
.progress-bar {
left: rem(240px);
}
.bar-header {
left: rem(240px);
}
}
}
aside.sidebar {
position: fixed;
width: rem(240px);
height: 100%;
top: 0;
left: rem(-240px);
background-color: $accentDark;
z-index: 20;
@include media(">=sm") {
padding: rem(10px) 0 0;
}
&.open {
left: 0;
}
h2 {
margin: 0 rem(20px) 0;
@include mainFont(400);
font-size: rem(18px);
color: $primaryDark;
border-bottom: 1px solid $primaryDark;
line-height: 50px;
@include media(">=sm") {
font-size: rem(20px);
}
}
nav {
ul {
padding: 0;
margin: rem(5px) 0;
@include media(">=sm") {
margin: rem(10px) 0;
}
li {
margin: 0;
list-style-type: none;
a {
width: 100%;
display: block;
padding: rem(15px) rem(20px);
text-decoration: none;
@include mainFont(300);
color: $primaryDark;
&:hover {
color: $accentDark;
background: $themeColor;
}
}
}
}
}
}

51
_sass/_mixins.scss Normal file
View File

@ -0,0 +1,51 @@
@mixin mainFont($weight: 700) {
font-family: "Titillium Web", "Helvetica Neue", Helvetica, sans-serif;
font-weight: $weight;
font-style: normal;
}
@mixin size($width: 30, $height: 30) {
width: #{$width}px;
height: #{$height}px;
}
@mixin center($max-width: map-get($jeet, 'max-width'), $pad: 0) {
@include clearfix;
width: auto;
max-width: $max-width;
float: none;
display: block;
margin: {
right: auto;
left: auto;
};
padding: {
left: $pad;
right: $pad;
};
}
@mixin align($direction: both) {
position: absolute;
transform-style: preserve-3d;
@if index("horizontal" "h", $direction) {
left: 50%;
transform: translateX(-50%);
} @else if index("vertical" "v", $direction) {
top: 50%;
transform: translateY(-50%);
} @else {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
@mixin clearfix() {
&::after {
content: '';
display: table;
clear: both;
}
}

154
_sass/_modal.scss Normal file
View File

@ -0,0 +1,154 @@
.modal {
.mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
background-color: rgba(0, 0, 0, 0.5);
animation: 1s fadeIn ease both;
}
.window {
position: fixed;
top: 50%;
left: 50%;
z-index: 1001;
transform: translate(-50%, -50%);
width: calc(100% - #{rem(40px)});
max-width: rem(800px);
background-color: #fff;
border-radius: rem(10px);
padding: rem(5px) 0;
box-shadow: 2px 2px 5px 2px rgba(0, 0, 0, 0.3);
animation: 0.3s fadeIn 0.5s ease both;
@include media(">=sm") {
min-width: rem(400px);
}
.close {
position: absolute;
right: rem(-10px);
top: rem(-10px);
width: rem(30px);
height: rem(30px);
fill: #fff;
background-color: $primaryDark;
border-radius: 50%;
border: 2px solid #fff;
padding: rem(5px);
cursor: pointer;
}
.header {
text-align: center;
border-bottom: 1px solid $lightGray;
padding: rem(15px);
h2,
p {
margin: 0;
font-size: rem(13px);
}
}
.content {
max-height: 90vh;
overflow: auto;
padding: rem(10px);
ul {
margin: 0;
padding: 0;
list-style: none;
display: flex;
flex-direction: column;
@include media(">=sm") {
flex-direction: row;
}
li {
flex: 1;
margin: rem(15px);
figure {
position: relative;
margin: 0;
&:after {
content: "Read now";
text-transform: uppercase;
display: inline-block;
background: $themeColor;
color: #fff;
font-size: rem(13px);
font-weight: 700;
line-height: rem(24px);
padding: 0 rem(8px);
position: absolute;
bottom: 10%;
left: -5px;
transition: background 0.2s;
}
}
img {
display: block;
max-width: 100%;
height: auto;
transition: all 0.2s ease-in-out;
position: relative;
}
a {
font-weight: normal;
color: $primaryDark;
text-decoration: none;
transition: all 0.3s;
&:hover {
color: rgba(0, 0, 0, 0.5);
img {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
figure {
&:after {
background: $primaryDark;
}
}
}
}
h3 {
font-size: rem(20px);
margin-bottom: 0;
}
p {
display: none;
@include media(">=sm") {
display: block;
font-size: rem(15px);
line-height: rem(20px);
}
}
}
}
}
}
&.closed {
display: none;
}
&.exit {
.window {
animation: 0.5s fadeIn 0.5s both, 0.5s zoomIn 0.5s both;
}
}
}

9
_sass/_no-js.scss Normal file
View File

@ -0,0 +1,9 @@
.no-js {
.flex-grid article {
opacity: 1;
}
.preload {
display: none;
}
}

238
_sass/_normalize.scss Normal file
View File

@ -0,0 +1,238 @@
// Based on Kouto Swiss normalize function
// https://github.com/leny/kouto-swiss/edit/master/lib/kouto-swiss/reset/normalize.styl
html {
font-family: sans-serif;
line-height: 1.15;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
}
article,
aside,
footer,
header,
nav,
section {
display: block;
}
h1 {
font-size: 2em;
margin: 0.67em 0;
}
figcaption,
figure,
main {
display: block;
}
figure {
margin: 1em 40px;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
pre {
font-family: monospace, monospace;
font-size: 1em;
}
a {
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
a:active,
a:hover {
outline-width: 0;
}
abbr[title] {
border-bottom: none;
text-decoration: underline;
text-decoration: underline dotted;
}
b,
strong {
font-weight: inherit;
}
b,
strong {
font-weight: bolder;
}
code,
kbd,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
dfn {
font-style: italic;
}
mark {
background-color: #ff0;
color: #000;
}
small {
font-size: 80%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
audio,
video {
display: inline-block;
}
audio:not([controls]) {
display: none;
height: 0;
}
img {
border-style: none;
}
svg:not(:root) {
overflow: hidden;
}
button,
input,
optgroup,
select,
textarea {
font-family: sans-serif;
font-size: 100%;
line-height: 1.15;
margin: 0;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html [type="button"]
[type="reset"]
[type="submit"] {
-webkit-appearance: button;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
legend {
box-sizing: border-box;
color: inherit;
display: table;
max-width: 100%;
padding: 0;
white-space: normal;
}
progress {
display: inline-block;
vertical-align: baseline;
}
textarea {
overflow: auto;
}
[type="checkbox"],
[type="radio"] {
box-sizing: border-box;
padding: 0;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
details,
menu {
display: block;
}
summary {
display: list-item;
}
canvas {
display: inline-block;
}
template {
display: none;
}
[hidden] {
display: none;
}

90
_sass/_pagination.scss Normal file
View File

@ -0,0 +1,90 @@
.pagination {
display: flex;
align-items: center;
&.pagination-home {
justify-content: center;
width: 100%;
margin: 0 auto;
a.next,
a.previous {
width: rem(40px);
height: rem(40px);
svg {
width: calc(100% - 20px);
height: calc(100% - 20px);
fill: #fff;
margin: 10px;
transition: all 0.3s ease;
}
&:hover > svg {
fill: $themeColor;
}
}
a.previous {
svg {
transform: rotate(180deg);
}
}
.page_number {
color: #fff;
font-size: rem(17px);
line-height: rem(22px);
margin: 0 rem(10px);
}
}
&.pagination-post {
justify-content: space-between;
padding: rem(15px) rem(20px) rem(30px);
@include media(">=sm") {
@include center(rem(800px));
}
a {
@include mainFont(bold);
font-size: rem(16px);
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
background-color: #fff;
color: $themeColor;
padding: 0 rem(15px);
border: 1px solid $themeColor;
border-radius: 5px;
transition: all 0.3s;
@include media(">=sm") {
font-size: rem(17px);
border: 2px solid $themeColor;
}
&:hover {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
.arrow {
width: rem(14px);
height: rem(14px);
fill: $themeColor;
margin-right: rem(10px);
}
.text {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: rem(15px) 0;
}
}
}
}

713
_sass/_post.scss Normal file
View File

@ -0,0 +1,713 @@
.post {
position: relative;
top: rem(30px);
@include media(">=sm") {
top: rem(50px);
}
}
.post.two-columns {
display: flex;
flex-direction: column;
padding-bottom: rem(40px);
@include media(">=sm") {
max-width: rem(1100px);
flex-direction: row;
margin: 0 auto;
padding: rem(40px) 0;
}
.post-content {
padding-bottom: rem(10px);
@include media(">=sm") {
flex-basis: 70%;
padding: 0 rem(30px) 0 rem(10px);
}
}
}
.post-content {
overflow-x: auto;
padding: rem(40px) 0;
&.fullwidth {
padding: rem(60px) rem(10px) 0;
}
img {
max-width: 100%;
margin: rem(0px) auto;
display: block;
padding: 10px 0;
}
figure {
margin: rem(20px) auto 0;
}
figcaption,
img + em {
display: block;
color: darken($lightGray, 30%);
text-align: center;
@include mainFont(300);
}
p,
h1,
h2,
h3,
h4,
h5,
h6,
ul,
ol,
iframe {
@include center(rem(800px));
@include mainFont(400);
font-size: rem(17px);
line-height: rem(30px);
letter-spacing: 0.025rem;
padding: 0 rem(20px);
margin: rem(20px) auto 0;
@include media(">=sm") {
font-size: rem(20px);
line-height: rem(40px);
margin: rem(29px) auto 0;
}
}
h1.post-title {
line-height: 1.2;
margin: rem(5px) auto rem(10px);
padding-top: 0;
}
p.post-subtitle {
color: darken($lightGray, 30%);
font-size: rem(17px);
margin: rem(10px) auto;
line-height: 1.6;
@include media(">=sm") {
font-size: rem(20px);
}
}
img.post-cover {
padding: 0;
margin-top: rem(20px);
margin-bottom: rem(20px);
@include media(">=sm") {
margin-top: rem(29px);
margin-bottom: rem(29px);
}
}
p.post-info {
@include mainFont(300);
font-size: rem(13px);
letter-spacing: 0;
color: darken($lightGray, 30%);
margin: 0 auto;
@include media(">=sm") {
font-size: rem(15px);
}
span,
time {
vertical-align: middle;
}
time {
margin-right: rem(10px);
@include media(">=sm") {
margin-right: rem(30px);
}
}
}
p,
li {
color: $texts;
code {
font-size: rem(15px);
background: #282a36;
color: #fff;
word-wrap: break-word;
padding: rem(3px) rem(5px);
border-radius: 3px;
@include media(">=sm") {
font-size: rem(17px);
}
}
}
li {
padding: rem(10px) 0;
ul {
margin-bottom: 0;
}
p {
margin-bottom: 0;
margin-top: 0;
}
}
a {
color: $themeColor;
text-decoration: none;
&:hover {
color: #a9a9a9;
}
}
iframe {
margin-top: rem(30px);
width: 100%;
}
h1,
h2,
h3,
h4,
h5,
h6 {
@include mainFont(700);
margin-top: 0;
padding-top: rem(50px);
@include media(">=sm") {
margin-top: 0;
padding-top: rem(60px);
}
}
h1 {
font-size: rem(36px);
line-height: 1.4;
@include media(">=sm") {
font-size: rem(50px);
}
}
h2 {
font-size: rem(28px);
line-height: 1.4;
@include media(">=sm") {
font-size: rem(37px);
}
}
h3 {
font-size: rem(22px);
line-height: 1.4;
@include media(">=sm") {
font-size: rem(27px);
}
}
ul,
ol {
padding-left: rem(60px);
}
ul.post-list {
padding: 0 rem(20px);
@include media(">=sm") {
padding: 0;
}
}
blockquote {
@include center(rem(730px));
border-left: rem(5px) solid $texts;
padding: 0 rem(10px);
margin: rem(30px) auto;
width: 90%;
@include media(">=sm") {
width: 100%;
margin: rem(50px) auto;
padding: 0 rem(30px);
}
p {
font-size: rem(17px);
color: rgba(0, 0, 0, 0.6);
margin: 0;
@include media(">=sm") {
font-size: rem(20px);
}
}
}
hr {
@include center(rem(760px));
border: 1px solid $lightGray;
margin: 50px auto;
}
pre {
overflow-x: auto;
}
table {
@include mainFont(400);
font-size: rem(17px);
line-height: rem(35px);
letter-spacing: 0.025rem;
margin: rem(50px) auto;
border-collapse: collapse;
@include media(">=sm") {
font-size: rem(20px);
}
th,
td {
border: rem(1px) solid #ccc;
padding: rem(5px) rem(10px);
@include media(">=sm") {
border: rem(2px) solid #ccc;
padding: rem(10px) rem(20px);
}
}
}
td > pre {
padding: 0;
margin: 0;
}
td.gutter.gl {
padding-right: rem(25px);
line-height: rem(24px);
}
h1,
h2,
h3,
h4,
h5,
h6 {
position: relative;
.anchor {
display: none;
height: rem(16px);
left: 0;
margin-top: rem(30px);
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
width: rem(16px);
@include media(">=sm") {
display: block;
opacity: 0;
}
img {
padding: 0;
}
}
&:hover .anchor,
.anchor:hover {
opacity: 1;
}
}
}
/* See also */
.see-also {
padding: 0 rem(20px);
@include media(">=sm") {
flex-basis: 30%;
padding: 0 rem(10px);
}
h2 {
font-size: rem(24px);
font-weight: bold;
border-bottom: 1px solid $lightGray;
padding: rem(10px) 0;
@include media(">=sm") {
padding: rem(48px) 0 rem(20px);
}
}
ul {
margin: 0;
padding: 0;
list-style: none;
li {
img {
display: block;
max-width: 100%;
height: auto;
transition: all 0.2s ease-in-out;
}
a {
font-weight: normal;
color: $primaryDark;
text-decoration: none;
transition: all 0.3s;
&:hover {
color: rgba(0, 0, 0, 0.5);
img {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
}
}
}
}
}
/* Progress bar */
.progress-bar {
display: flex;
align-items: center;
width: 100%;
height: 38px;
padding: rem(30px) 0;
border-bottom: 1px solid $themeColor;
background-color: #fff;
transition: bottom 0.5s;
.bar {
position: relative;
flex: 1;
height: rem(10px);
background-color: $themeColor;
opacity: 0.2;
}
.completed {
opacity: 1;
&:last-child {
border-right: 1px solid #fff;
}
}
.star {
position: relative;
width: rem(40px);
height: rem(40px);
animation: 1s pulse cubic-bezier(0.36, 0.07, 0.19, 0.97) alternate infinite;
}
&.finished {
.star {
animation: none;
transform: scale(1.3);
}
}
}
/* Time bar */
.time-bar {
position: fixed;
left: 0;
right: 0;
bottom: -100%;
display: block;
width: 100%;
padding: rem(10px) rem(20px) rem(5px);
transition: bottom 0.5s;
background-color: rgba(0, 0, 0, 0.85);
@include media(">=sm") {
padding: rem(16px) rem(20px) rem(9px);
}
.bar {
display: block;
width: 100%;
padding: rem(8px) rem(60px);
&:after {
clear: both;
display: block;
content: "";
}
}
.completed {
float: left;
display: block;
height: rem(5px);
background-color: $themeColor;
}
.remaining {
float: left;
display: block;
height: rem(5px);
background-color: #ccc;
}
.time-completed,
.time-remaining {
@include mainFont(400);
font-size: rem(18px);
color: #fff;
}
.time-completed {
float: left;
}
.time-remaining {
float: right;
}
}
/* Recommendation */
.recommendation {
@include mainFont(400);
position: fixed;
left: 0;
right: 0;
bottom: -100%;
display: block;
width: 100%;
padding: rem(10px);
transition: bottom 0.5s;
background-color: rgba(0, 0, 0, 0.85);
display: flex;
justify-content: space-between;
@include media(">=sm") {
padding: rem(15px);
}
.message {
display: flex;
flex-direction: column;
justify-content: space-between;
font-size: rem(16px);
color: #fff;
padding-right: rem(20px);
@include media(">=sm") {
font-size: rem(20px);
}
strong {
display: block;
margin: rem(10px) 0;
}
button {
background-color: transparent;
border: 0;
color: #fff;
cursor: pointer;
display: inline-block;
font-size: rem(13px);
text-decoration: none;
outline: 0;
@include media(">=sm") {
font-size: rem(15px);
}
}
svg {
fill: #fff;
width: rem(22px);
height: rem(22px);
transform: rotate(-90deg);
border: 1px solid #fff;
border-radius: 50%;
padding: 5px;
margin-right: 10px;
vertical-align: middle;
@include media(">=sm") {
width: rem(28px);
height: rem(28px);
}
}
span {
vertical-align: middle;
}
}
.post-preview {
display: flex;
align-items: center;
flex-direction: column;
background-color: #000;
padding: rem(5px);
max-width: 35%;
text-decoration: none;
@include media(">=sm") {
flex-direction: row;
padding: rem(5px) rem(50px) rem(5px) rem(5px);
max-width: 50%;
}
&:hover {
.title {
color: rgba(255, 255, 255, 0.5);
}
.image > img {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
}
.image,
.image > img {
display: block;
width: 100%;
max-width: rem(200px);
transition: all 0.3s;
}
.title {
font-size: rem(16px);
color: #fff;
margin: rem(5px) 0;
transition: all 0.3s;
@include media(">=sm") {
font-size: rem(23px);
margin: 0 0 0 rem(20px);
}
}
}
}
.icon-clock,
.icon-calendar {
width: rem(14px);
height: rem(14px);
fill: darken($lightGray, 30%);
vertical-align: middle;
margin-right: rem(3px);
}
/* Tags */
.post-content {
.tags {
@include center(rem(800px));
@include mainFont(400);
font-size: rem(18px);
margin: 0 auto rem(29px);
margin-top: rem(30px);
letter-spacing: 0.025rem;
line-height: rem(40px);
padding: 0 rem(10px);
@include media(">=sm") {
font-size: rem(20px);
padding: 0;
}
a {
font-size: rem(14px);
color: $primaryDark;
display: inline-block;
border: 1px solid $primaryDark;
border-radius: rem(20px);
padding: 0 rem(10px);
margin-right: rem(2px);
margin-bottom: rem(8px);
text-decoration: none;
@include media(">=sm") {
border-width: 2px;
}
&:hover {
color: $accentDark;
background-color: $primaryDark;
}
}
}
.tag-title {
@include mainFont(300);
@include center(rem(800px));
font-size: rem(30px);
margin-top: rem(20px);
padding: 0 rem(10px);
span {
padding: rem(3px) rem(10px);
background-color: $themeColor;
border-radius: rem(5px);
color: #fff;
}
@include media(">=sm") {
font-size: rem(22px);
margin-top: rem(80px);
padding: 0;
}
}
a.post-anchor {
display: block;
height: rem(40px);
@include media(">=sm") {
height: rem(10px);
}
}
ul.post-list {
list-style: none;
margin: rem(25px) auto 0;
padding: 0 rem(10px);
@include media(">=sm") {
padding: 0;
}
a {
display: flex;
justify-content: space-between;
border-bottom: 1px solid darken($lightGray, 10%);
padding: rem(10px) 0;
text-decoration: none;
font-size: rem(18px);
}
.entry-date {
float: right;
@include media("<sm") {
display: none;
}
}
}
}

138
_sass/_search.scss Normal file
View File

@ -0,0 +1,138 @@
.search-wrapper {
position: fixed;
top: 30px;
width: 100%;
padding-right: 5%;
padding-left: 5%;
transform: translateY(-200px);
z-index: 19;
&.active {
transform: translateY(0);
}
}
.search-form {
position: relative;
top: 0;
width: 100%;
transform: translateX(-200px);
transition: all 200ms 100ms cubic-bezier(0, 0.6, 0.4, 1);
opacity: 0;
z-index: 19;
.search-field {
width: 100%;
height: rem(40px);
line-height: rem(30px);
@include mainFont(300);
font-size: rem(20px);
color: $primaryDark;
background-color: $accentDark;
border: 0;
border-radius: rem(20px);
padding: rem(5px) rem(25px);
outline: 0;
}
&:focus {
outline: 0;
}
&.active {
top: 0;
transform: translateX(0);
opacity: 1;
}
.search-list {
position: absolute;
width: 100%;
@include mainFont(300);
display: none;
padding: 0 rem(20px);
margin: rem(20px) 0;
list-style-type: none;
@include media("<sm") {
height: 380px;
overflow: scroll;
}
.active & {
display: block;
}
.entry-date {
float: right;
display: none;
font-size: rem(14px);
@include media(">=sm") {
display: inline;
}
}
.entry-category {
text-transform: uppercase;
background-color: $themeColor;
margin-right: rem(5px);
height: rem(20px);
border-radius: rem(10px);
font-size: rem(12px);
padding: rem(2px) rem(8px);
color: #ffffff;
}
a {
color: $accentDark;
text-decoration: none;
display: block;
padding: rem(15px) 0;
width: 100%;
border-bottom: 1px solid darken($accentDark, 80%);
transition: all 0.3s;
line-height: rem(25px);
&:hover {
color: $themeColor;
.entry-category {
color: #ffffff;
}
}
}
}
.icon-remove-sign {
position: absolute;
top: 0;
right: 0;
display: block;
width: rem(26px);
height: rem(26px);
padding: rem(5px);
fill: $accentDark;
background-color: $themeColor;
border-radius: 13px;
margin: rem(7px);
cursor: pointer;
outline: 0;
z-index: 1;
}
}
.search-overlay {
overflow: hidden;
&:after {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
min-height: 100%;
background-color: $primaryDark;
content: "";
z-index: 18;
}
}

37
_sass/_share.scss Normal file
View File

@ -0,0 +1,37 @@
.share {
@include center(800px);
text-align: center;
border-top: 1px solid $lightGray;
padding-top: rem(20px);
margin-top: rem(10px);
@include media(">=sm") {
margin-top: rem(50px);
}
article & {
border-top: none;
}
svg {
margin: rem(15px);
@include size(35, 35);
}
a {
text-decoration: none;
border: none;
}
.icon {
transition: all 0.3s;
}
.icon-twitter:hover {
fill: #1da1f3;
}
.icon-facebook:hover {
fill: #3b5998;
}
}

38
_sass/_staff.scss Normal file
View File

@ -0,0 +1,38 @@
.staff {
@include media(">=sm") {
@include center(rem(800px));
}
.item:not(:last-child) {
border-bottom: 1px solid $lightGray;
}
img {
width: rem(150px);
margin: 0 rem(20px) rem(20px);
@include media(">=sm") {
width: rem(200px);
margin-bottom: rem(30px);
}
}
h1,
h2,
h3 {
margin-bottom: rem(10px);
&.name {
padding-top: rem(10px);
}
&.position {
font-size: rem(19px);
font-weight: normal;
font-style: italic;
color: #999;
padding-top: 0;
margin-bottom: rem(20px);
}
}
}

7
_sass/_theme.scss Normal file
View File

@ -0,0 +1,7 @@
$theme: (
themeColor: #ff0a16,
primaryDark: #141414,
accentDark: #ffffff,
lightGray: #f2f2f2,
texts: #ffffff
);

7
_sass/_typo.scss Normal file
View File

@ -0,0 +1,7 @@
a {
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
h1, h2, h3, h4 {
@include mainFont();
}

24
_sass/_variables.scss Normal file
View File

@ -0,0 +1,24 @@
/**
* Set up here the general appearance of the theme.
*/
$themeColor: map-get($theme, themeColor) !default;
$primaryDark: map-get($theme, primaryDark) !default;
$accentDark: map-get($theme, accentDark) !default;
$lightGray: map-get($theme, lightGray) !default;
$texts: map-get($theme, texts) !default;
// Breakpoints
$breakpoints: (
sm: 37.5rem
);
// Margins
$rowMargin: 10px;
$itemMargin: 15px;
// Sizes
$itemMinWidth: 300px;
// Settings
$maxItemsPerRow: 6;

1
_sass/jekflix.scss Normal file
View File

@ -0,0 +1 @@
@import "main";

26
_sass/main.scss Normal file
View File

@ -0,0 +1,26 @@
@import "include-media";
@import "normalize";
@import "theme";
@import "variables";
@import "functions";
@import "mixins";
@import "typo";
@import "animations";
@import "icons";
@import "menu";
@import "hero";
@import "search";
@import "elements";
@import "header";
@import "home";
@import "post";
@import "pagination";
@import "share";
@import "highlight";
@import "form";
@import "author";
@import "staff";
@import "modal";
@import "footer";
@import "no-js";
@import "SalaMuseoGames";

310
_sass/preview.scss Normal file
View File

@ -0,0 +1,310 @@
@import "include-media";
@import "normalize";
@import "theme";
@import "variables";
@import "functions";
@import "mixins";
@import "typo";
@import "highlight";
body {
overflow-x: auto;
@include media(">=sm") {
padding: rem(50px) rem(30px);
}
img {
max-width: 100%;
margin: 0 auto rem(20px);
display: block;
padding: 10px 0;
@include media(">=sm") {
margin: 0 auto rem(29px);
}
}
figure {
margin: 0;
}
figcaption,
img + em {
display: block;
color: darken($lightGray, 30%);
text-align: center;
@include mainFont(300);
}
p,
h1,
h2,
h3,
h4,
h5,
h6,
ul,
ol,
iframe,
div[class^="css"] {
@include center(rem(800px));
@include mainFont(400);
font-size: rem(17px);
line-height: rem(30px);
letter-spacing: 0.05rem;
padding: 0 rem(20px);
margin: 0 auto rem(20px);
@include media(">=sm") {
font-size: rem(20px);
line-height: rem(40px);
margin: 0 auto rem(29px);
padding: 0;
}
}
h1.post-title {
margin: 0 auto;
line-height: rem(40px);
@include media(">=sm") {
line-height: rem(60px);
margin: 0 auto rem(10px);
}
}
p.post-subtitle {
color: darken($lightGray, 30%);
font-size: rem(17px);
margin: 0 auto rem(10px);
line-height: rem(30px);
@include media(">=sm") {
font-size: rem(20px);
line-height: rem(40px);
}
}
img.post-cover {
margin-bottom: rem(20px);
@include media(">=sm") {
margin-bottom: rem(29px);
}
}
p.post-info {
@include mainFont(300);
font-size: rem(13px);
letter-spacing: 0;
color: darken($lightGray, 30%);
margin: 0 auto;
@include media(">=sm") {
font-size: rem(16px);
}
span,
time {
vertical-align: middle;
}
time {
margin-right: rem(10px);
@include media(">=sm") {
margin-right: rem(30px);
}
}
svg {
width: rem(15px);
height: rem(15px);
fill: darken($lightGray, 30%);
vertical-align: middle;
margin-right: rem(5px);
}
}
li {
padding: rem(10px) 0;
ul {
margin-bottom: 0;
}
}
p,
li {
color: $texts;
code {
font-size: rem(15px);
color: #bf616a;
word-wrap: break-word;
background: $lightGray;
padding: rem(3px) rem(5px);
border-radius: 3px;
@include media(">=sm") {
font-size: rem(17px);
}
}
}
a {
color: #0000ee;
text-decoration: none;
}
iframe {
margin-top: rem(30px);
width: 100%;
}
h1,
h2,
h3,
h4,
h5,
h6 {
@include mainFont(700);
}
h1 {
font-size: rem(32px);
line-height: 1.4;
@include media(">=sm") {
font-size: rem(47px);
}
}
h2 {
font-size: rem(24px);
line-height: 1.4;
@include media(">=sm") {
font-size: rem(37px);
}
}
h3 {
font-size: rem(20px);
line-height: 1.4;
@include media(">=sm") {
font-size: rem(27px);
}
}
ul,
ol {
padding-left: rem(40px);
}
ul.post-list {
padding: 0;
@include media("<sm") {
padding: 0 rem(20px);
}
}
blockquote {
@include center(rem(730px));
border-left: rem(5px) solid $texts;
padding: 0 rem(10px);
margin: rem(30px) auto;
width: 90%;
@include media(">=sm") {
width: 100%;
margin: rem(50px) auto;
padding: 0 rem(30px);
}
p {
font-size: rem(17px);
color: rgba(0, 0, 0, 0.6);
margin: 0;
@include media(">=sm") {
font-size: rem(20px);
}
}
}
hr {
@include center(rem(760px));
border: 1px solid $lightGray;
margin: 50px auto;
}
hr.page-divider {
@include center(rem(760px));
border: 0;
margin: 50px auto;
position: relative;
height: rem(54px);
&:after {
display: block;
content: "Page divider";
padding: rem(5px) rem(10px);
border: 2px solid $themeColor;
border-radius: rem(5px);
font-size: rem(14px);
font-weight: bold;
color: $themeColor;
text-align: center;
text-transform: uppercase;
}
}
pre {
overflow-x: auto;
position: relative;
&:before {
display: inline-block;
content: "In the website, the code will be highlighted.";
position: absolute;
top: 0;
left: 0;
padding: 0 rem(15px);
@include mainFont(400);
font-size: rem(14px);
background-color: $themeColor;
color: #fff;
}
}
table {
@include mainFont(400);
font-size: rem(17px);
line-height: rem(35px);
letter-spacing: 0.05rem;
margin: rem(50px) auto;
@include media(">=sm") {
font-size: rem(20px);
}
th,
td {
border: rem(1px) solid #ccc;
padding: rem(5px) rem(10px);
@include media(">=sm") {
border: rem(2px) solid #ccc;
padding: rem(10px) rem(20px);
}
}
}
td > pre {
padding: 0;
margin: 0;
}
}
// Helpers
.img-rounded {
border-radius: 50%;
}

515
admin/config.yml Normal file
View File

@ -0,0 +1,515 @@
backend:
name: git-gateway
branch: master
publish_mode: editorial_workflow
media_folder: "assets/img/uploads"
collections:
- label: "Categories"
name: "categories"
folder: "category"
create: true
editor:
preview: false
slug: "{{slug}}"
preview_path: "category/{{slug}}"
extension: "md"
fields:
- label: "Layout"
name: "layout"
widget: "hidden"
default: "category"
- label: "Title"
name: "title"
widget: "string"
- label: "Slug"
name: "slug"
widget: "hidden"
default: "{{slug}}"
- label: "Description"
name: "description"
widget: "string"
required: false
- label: "Posts"
name: "posts"
folder: "_posts"
create: true
slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
preview_path: "{{title}}"
extension: "md"
fields:
- label: "Publish Date"
name: "date"
widget: "datetime"
format: "YYYY-MM-DD HH:mm:ss"
- label: "Layout"
name: "layout"
widget: "hidden"
default: "post"
- label: "Title"
name: "title"
widget: "string"
- label: "Subtitle"
name: "subtitle"
widget: "string"
required: false
- label: "Description"
name: "description"
hint: "This will be used across the pages and for search engines."
widget: "string"
- label: "Featured Image"
name: "image"
widget: "image"
allow_multiple: false
required: false
- label: "Optimized Image"
name: "optimized_image"
widget: "image"
allow_multiple: false
required: false
hint: "You can set an optimized image version to show on the home page"
- label: "Category"
name: "category"
widget: "relation"
collection: "categories"
searchFields: ["title"]
valueField: "slug"
displayFields: ["title"]
- label: "Tags"
name: "tags"
hint: "Separate with commas. These will also be used as keywords for search engines."
widget: "list"
- label: "Author"
name: "author"
widget: "relation"
collection: "authors"
displayFields: [display_name]
searchFields: [display_name]
valueField: "name"
- label: "Paginate"
name: "paginate"
widget: "boolean"
default: false
- label: "Body"
name: "body"
widget: "markdown"
- label: "Pages"
name: "pages"
folder: "pages"
create: true
slug: "{{slug}}"
preview_path: "{{slug}}"
extension: "md"
fields:
- label: "Layout"
name: "layout"
widget: "hidden"
default: "page"
- label: "Show in menu"
name: "menu"
widget: "boolean"
default: true
- label: "Publish Date"
name: "date"
widget: "datetime"
format: "YYYY-MM-DD HH:mm:ss"
- label: "Title"
name: "title"
widget: "string"
- label: "Permalink"
name: "permalink"
widget: "hidden"
default: "/{{slug}}/"
- label: "Description"
name: "description"
hint: "This will be used as description for search engines."
widget: "string"
required: false
- label: "Keywords"
name: "tags"
hint: "Separate with commas. These will also be used as keywords for search engines."
widget: "list"
required: false
- label: "Body"
name: "body"
widget: "markdown"
- label: "Authors"
name: "authors"
folder: "_authors/"
create: true
editor:
preview: false
fields:
- label: "Layout"
name: "layout"
widget: "hidden"
default: "author"
- label: "Photo"
name: "photo"
widget: "image"
required: false
hint: "Use a square picture"
- label: "Short Name"
name: "name"
widget: "string"
- label: "Diplay Name"
name: "display_name"
widget: "string"
- label: "Position"
name: "position"
widget: "string"
required: false
- label: "Bio"
name: "bio"
widget: "text"
- label: "GitHub Username"
name: "github_username"
widget: "string"
required: false
- label: "Facebook Username"
name: "facebook_username"
widget: "string"
required: false
- label: "Twitter Username"
name: "twitter_username"
widget: "string"
required: false
- label: "Instagram Username"
name: "instagram_username"
widget: "string"
required: false
- label: "LinkedIn Username"
name: "linkedin_username"
widget: "string"
required: false
- label: "Medium Username"
name: "medium_username"
widget: "string"
required: false
- label: "Settings"
name: "settings"
editor:
preview: false
delete: false
files:
- label: "Site"
name: "site"
file: "src/yml/site.yml"
fields:
- label: "Name"
name: "name"
widget: "string"
- label: "Title"
name: "title"
widget: "string"
- label: "Description"
name: "description"
widget: "string"
hint: "This will be used as description for search engines."
- label: "Keywords"
name: "tags"
hint: "Separate with commas. These will also be used as keywords for search engines."
widget: "list"
required: false
- label: "Show Hero"
name: "show_hero"
widget: "boolean"
default: true
- label: "Posts per page"
name: "paginate"
widget: "number"
valueType: "int"
required: false
hint: "Leave it blank if you don't want pagination"
- label: "Menu"
name: "menu"
widget: "list"
required: false
fields:
- label: "Title"
name: "title"
widget: "string"
hint: "Text that will show up in the menu"
- label: "URL"
name: "url"
widget: "string"
hint: "Ex: /contact"
- label: "E-mail"
name: "email"
widget: "string"
hint: "Leave it blank if you don't want a contact page"
required: false
- label: "Disqus Username"
name: "disqus_username"
widget: "string"
hint: "Leave it blank if you don't want comments in posts"
required: false
- label: "Social"
name: "social"
file: "src/yml/social.yml"
fields:
- label: "GitHub Username"
name: "github_username"
widget: "string"
required: false
- label: "Facebook Username"
name: "facebook_username"
widget: "string"
required: false
- label: "Twitter Username"
name: "twitter_username"
widget: "string"
required: false
- label: "Instagram Username"
name: "instagram_username"
widget: "string"
required: false
- label: "LinkedIn Username"
name: "linkedin_username"
widget: "string"
required: false
- label: "Medium Username"
name: "medium_username"
widget: "string"
required: false
- label: "Theme"
name: "theme"
file: "src/yml/theme.yml"
fields:
- label: "Theme Color"
name: "themeColor"
widget: "color"
default: "#ff0a16"
- label: "Primary Dark Color"
name: "primaryDark"
widget: "color"
default: "#141414"
- label: "Accent Dark Color"
name: "accentDark"
default: "#ffffff"
widget: "color"
- label: "Light Gray Color"
name: "lightGray"
widget: "color"
default: "#f2f2f2"
- label: "Texts Color"
name: "texts"
widget: "color"
default: "#333333"
- label: "Posts"
name: "posts"
file: "src/yml/posts.yml"
fields:
- label: "Show time bar in posts"
name: "show_time_bar"
widget: "boolean"
default: true
- label: "Show modal on exit"
name: "show_modal_on_exit"
widget: "boolean"
default: false
- label: "Show modal on finish post"
name: "show_modal_on_finish_post"
widget: "boolean"
default: false
- label: "Two columns layout"
name: "two_columns_layout"
widget: "boolean"
default: true
- label: "Translations"
name: "translations"
file: "src/yml/translations.yml"
fields:
- label: "Texts"
name: "texts"
widget: "object"
fields:
- label: "New Post"
name: "new_post"
widget: "string"
required: false
- label: "See also"
name: "seel_also"
widget: "string"
required: false
- label: "Search"
name: "search"
widget: "string"
required: false
- label: "Share"
name: "share"
widget: "string"
required: false
- label: "Comments"
name: "comments"
widget: "string"
required: false
- label: "Buttons"
name: "button"
widget: "object"
fields:
- label: "Read Now"
name: "read_now"
widget: "string"
required: false
- label: "Share on Twitter"
name: "share_on_twitter"
widget: "string"
required: false
- label: "Share on Facebook"
name: "share_on_facebook"
widget: "string"
required: false
- label: "Pagination"
name: "pagination"
widget: "object"
fields:
- label: "Page"
name: "page"
widget: "string"
required: false
- label: "of"
name: "of"
widget: "string"
required: false
- label: "Next Page"
name: "next_page"
widget: "string"
required: false
- label: "Next Post"
name: "next_post"
widget: "string"
required: false
- label: "Recommendation"
name: "recommendation"
widget: "object"
fields:
- label: "Text"
name: "text"
widget: "string"
required: false
- label: "Go back to top"
name: "back_btn"
widget: "string"
required: false
- label: "Error 404"
name: "error_404"
widget: "object"
fields:
- label: "Title"
name: "title"
widget: "string"
required: false
- label: "Message"
name: "message"
widget: "string"
required: false
- label: "Image Alt"
name: "image_alt"
widget: "string"
required: false
- label: "Contact Page"
name: "contact"
widget: "object"
fields:
- label: "Title"
name: "title"
widget: "string"
required: false
- label: "Email Subject Title"
name: "subject"
widget: "string"
required: false
- label: "Submit Button Label"
name: "submit_btn"
widget: "string"
required: false
- label: "Fields Placeholder"
name: "placeholders"
widget: "object"
fields:
- label: "Your Name"
name: "name"
widget: "string"
required: false
- label: "Your Email"
name: "email"
widget: "string"
required: false
- label: "Your Message"
name: "message"
widget: "string"
required: false
- label: "Fields Error"
name: "errors"
widget: "object"
fields:
- label: "Locale"
name: "locale"
widget: "string"
default: "en"
hint: "Ex: en"
- label: "Empty Name"
name: "empty_name"
widget: "string"
hint: "Ex: Insert your name"
required: false
- label: "Empty Email"
name: "empty_email"
widget: "string"
hint: "Ex: Insert your email"
required: false
- label: "Invalid Email"
name: "invalid_email"
widget: "string"
hint: "Ex: Email is invalid"
required: false
- label: "Empty Message"
name: "empty_message"
widget: "string"
hint: "Ex: Insert your message"
required: false
- label: "Contact Feedback Page"
name: "after_send"
widget: "object"
fields:
- label: "Title"
name: "title"
widget: "string"
hint: "Ex: Message sent!"
required: false
- label: "Text"
name: "message"
widget: "string"
hint: "Ex: Thank you for reaching us."
required: false
- label: "Advanced"
name: "advanced"
file: "src/yml/advanced.yml"
fields:
- label: "Base URL"
name: "baseurl"
widget: "string"
hint: "The subpath of your site, e.g. /blog"
- label: "URL"
name: "url"
widget: "string"
hint: "The base hostname and protocol for your site, e.g. https://rossener.com"
- label: "Google Analytics ID"
name: "google_analytics"
widget: "string"
required: false
- label: "Language"
name: "language"
widget: "string"
hint: "Content language, ex: pt-BR, en, fr"
- label: "Categories folder"
name: "categories_folder"
widget: "string"
hint: "Folder where all the categories pages are. Ex: category"
required: false
- label: "Contact Feedback URL"
name: "sent_message_url"
hint: "URL where the user will be redirected for after submit the contact form. Ex: /contact/message-sent/"
required: false

332
admin/index.html Normal file
View File

@ -0,0 +1,332 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Content Manager</title>
</head>
<body>
<!-- Include the script that builds the page and powers Netlify CMS -->
<script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
<!-- Include the script that allows Netlify CMS login -->
<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
<!-- Register Color widget -->
<!-- https://github.com/ekoeryanto/netlify-cms-widgets/tree/master/widgets/color -->
<script src="../assets/js/react.min.js"></script>
<script src="../assets/js/widgets/color/react-color.min.js"></script>
<script src="../assets/js/widgets/color/color.min.js"></script>
<script>
CMS.registerWidget('color', NetlifyCMSWidgetColor.Control);
</script>
<!-- Register Page component -->
<script>
CMS.registerEditorComponent({
// Internal id of the component
id: "page",
// Visible label
label: "Page",
// Fields the user need to fill out when adding an instance of the component
fields: [],
// Pattern to identify a block as being an instance of this component
pattern: /^--page-break--$/,
// Function to extract data elements from the regexp match
fromBlock: function() {
return;
},
// Function to create a text block from an instance of this component
toBlock: function() {
return '--page-break--';
},
// Preview output for this component. Can either be a string or a React component
// (component gives better render performance)
toPreview: function(obj) {
return (
'<hr class="page-divider">'
);
}
});
</script>
<!-- Register Figure component -->
<script>
CMS.registerEditorComponent({
// Internal id of the component
id: "figure",
// Visible label
label: "Figure",
// Fields the user need to fill out when adding an instance of the component
fields: [
{ name: 'image', label: 'Image', widget: 'image', allow_multiple: false },
{ name: 'alt', label: 'Alternative Text', widget: 'string', required: false, hint: "Used for accessibility." },
{ name: 'classes', label: 'Classes', widget: 'string', required: false, hint: 'Add styles to image.'},
{ name: 'width', label: 'Width', widget: 'number', valueType: 'int', required: false },
{ name: 'height', label: 'Height', widget: 'number', valueType: 'int', required: false },
{ name: 'caption', label: 'Caption', widget: 'string', required: false },
],
// Pattern to identify a block as being an instance of this component
pattern: /{%\s*figure\s*{\s*"image"\s*:\s*"(.*?)"\s*,?\s*(?:"alt"\s*:\s*"(.*?)")?\s*,?\s*(?:"classes"\s*:\s*"(.*?)")?\s*,?\s*(?:"width"\s*:\s*"([0-9]*)")?\s*,?\s*(?:"height"\s*:\s*"([0-9]*)")?\s*,?\s*(?:"caption"\s*:\s*"(.*?)")?\s*}\s*%}/,
// Function to extract data elements from the regexp match
fromBlock: function (match) {
return {
image: match[1] || '',
alt: match[2] || '',
classes: match[3] || '',
width: match[4] || '',
height: match[5] || '',
caption: match[6] || '',
};
},
// Function to create a text block from an instance of this component
toBlock: function (obj) {
if (obj.image) {
var image = obj.image ? '"image": "' + obj.image + '"' : '';
var alt = obj.alt ? ', "alt": "' + obj.alt + '"' : '';
var classes = obj.classes ? ', "classes": "' + obj.classes + '"' : '';
var width = obj.width ? ', "width": "' + obj.width + '"' : '';
var height = obj.height ? ', "height": "' + obj.height + '"' : '';
var caption = obj.caption ? ', "caption": "' + obj.caption + '"' : '';
return '{% figure {' + image + alt + classes + width + height + caption + '} %}';
}
return '';
},
// Preview output for this component. Can either be a string or a React component
// (component gives better render performance)
toPreview: function (obj) {
var src = obj.image ? ' src="' + obj.image + '"' : '';
var alt = obj.alt ? ' alt="' + obj.alt + '"' : '';
var classes = obj.classes ? ' class="' + obj.classes + '"' : '';
var width = obj.width ? ' width="' + obj.width + '"' : '';
var height = obj.height ? ' height="' + obj.height + '"' : '';
var caption = obj.caption ? '<figcaption>' + obj.caption + '</figcaption>' : '';
return (
'<figure><img' + src + alt + classes + width + height + '>' + caption + '</figure>'
);
}
});
</script>
<!-- Register Figure Url component -->
<script>
CMS.registerEditorComponent({
// Internal id of the component
id: "figureUrl",
// Visible label
label: "Figure URL",
// Fields the user need to fill out when adding an instance of the component
fields: [
{ name: 'image', label: 'Image URL', widget: 'string'},
{ name: 'alt', label: 'Alternative Text', widget: 'string', required: false, hint: "Used for accessibility." },
{ name: 'classes', label: 'Classes', widget: 'string', required: false, hint: 'Add styles to image.'},
{ name: 'width', label: 'Width', widget: 'number', valueType: 'int', required: false },
{ name: 'height', label: 'Height', widget: 'number', valueType: 'int', required: false },
{ name: 'caption', label: 'Caption', widget: 'string', required: false },
],
// Pattern to identify a block as being an instance of this component
pattern: /{%\s*figure_url\s*{\s*"image"\s*:\s*"(.*?)"\s*,?\s*(?:"alt"\s*:\s*"(.*?)")?\s*,?\s*(?:"classes"\s*:\s*"(.*?)")?\s*,?\s*(?:"width"\s*:\s*"([0-9]*)")?\s*,?\s*(?:"height"\s*:\s*"([0-9]*)")?\s*,?\s*(?:"caption"\s*:\s*"(.*?)")?\s*}\s*%}/,
// Function to extract data elements from the regexp match
fromBlock: function (match) {
return {
image: match[1] || '',
alt: match[2] || '',
classes: match[3] || '',
width: match[4] || '',
height: match[5] || '',
caption: match[6] || '',
};
},
// Function to create a text block from an instance of this component
toBlock: function (obj) {
if (obj.image) {
var image = obj.image ? '"image": "' + obj.image + '"' : '';
var alt = obj.alt ? ', "alt": "' + obj.alt + '"' : '';
var classes = obj.classes ? ', "classes": "' + obj.classes + '"' : '';
var width = obj.width ? ', "width": "' + obj.width + '"' : '';
var height = obj.height ? ', "height": "' + obj.height + '"' : '';
var caption = obj.caption ? ', "caption": "' + obj.caption + '"' : '';
return '{% figure_url {' + image + alt + classes + width + height + caption + '} %}';
}
return '';
},
// Preview output for this component. Can either be a string or a React component
// (component gives better render performance)
toPreview: function (obj) {
var src = obj.image ? ' src="' + obj.image + '"' : '';
var alt = obj.alt ? ' alt="' + obj.alt + '"' : '';
var classes = obj.classes ? ' class="' + obj.classes + '"' : '';
var width = obj.width ? ' width="' + obj.width + '"' : '';
var height = obj.height ? ' height="' + obj.height + '"' : '';
var caption = obj.caption ? '<figcaption>' + obj.caption + '</figcaption>' : '';
return (
'<figure><img' + src + alt + classes + width + height + '>' + caption + '</figure>'
);
}
});
</script>
<!-- Include preview styles -->
<script>
CMS.registerPreviewStyle("https://fonts.googleapis.com/css?family=Titillium+Web:300,400,700");
CMS.registerPreviewStyle("/assets/css/preview.css");
</script>
<!-- Register the Post preview component -->
<script>
var PostPreview = createClass({
render: function() {
function formatDate(rawDate) {
var date = rawDate;
if (typeof date === 'string') {
date = new Date(date);
}
if (date) {
var months = 'January,February,Mark,April,May,June,July,August,September,October,November,December'.split(',');
var monthNumber = date.getMonth();
return months[monthNumber] + ' ' + date.getDate() + ', ' + date.getFullYear();
}
}
// Entry
var entry = this.props.entry;
// Elements
var elements = [];
// Paginate
var paginate = entry.getIn(['data', 'paginate']);
// Post Info
var postInfo = h('p', {'className': 'post-info'}, [
h('svg', {}, [
h('use', {'xlinkHref': '/assets/img/preview-sprite.svg#icon-calendar'})
]),
h('time', {'className': 'date'}, formatDate(entry.getIn(['data', 'date'])))
]);
elements.push(postInfo);
// Post Title
var postTitle = h('h1', {'className': 'post-title'}, entry.getIn(['data', 'title']));
elements.push(postTitle);
// Post Subtitle
var postSubtitle = h('p', {'className': 'post-subtitle'}, entry.getIn(['data', 'subtitle']));
elements.push(postSubtitle);
// Featured Image
if (!paginate) {
var image = entry.getIn(['data', 'image']);
var bg = this.props.getAsset(image);
var featuredImage = h('img', {'className': 'post-cover', 'src': bg.toString()});
elements.push(featuredImage);
}
// Space
if (paginate) {
var space = h('br', {});
elements.push(space);
}
// Body
var body = h('div', {'className': 'text'}, this.props.widgetFor('body'));
elements.push(body);
return h('div', {}, elements);
}
});
CMS.registerPreviewTemplate('posts', PostPreview);
</script>
<!-- Register the Page preview component -->
<script>
var PagePreview = createClass({
render: function() {
// Entry
var entry = this.props.entry;
// Elements
var elements = [];
// Body
var body = h('div', {'className': 'text'}, this.props.widgetFor('body'));
elements.push(body);
return h('div', {}, elements);
}
});
CMS.registerPreviewTemplate('pages', PagePreview);
</script>
<!-- Register Image component -->
<!-- It's not possible to create this element just yet. There are two things needed in order to do so: -->
<!-- 1) Jekyll needs to update kramdown version up to 2.1.0, so we can use the :standlone feature with <figure></figure> -->
<!-- See: https://github.com/gettalong/kramdown/issues/48#issuecomment-455851003 -->
<!-- 2) However, it may not be possible, once Netlify CMS parses using Remark before parse using kramdown -->
<!-- See: https://github.com/netlify/netlify-cms/issues/1464#issuecomment-400470173 -->
<!-- Solution for now: -->
<!-- Keep using <img width="X" height="Y"> with <em></em> for caption -->
<script>
// CMS.registerEditorComponent({
// // Internal id of the component
// id: "image",
// // Visible label
// label: "Image",
// // Fields the user need to fill out when adding an instance of the component
// fields: [
// { name: 'image', label: 'Image', widget: 'image', allow_multiple: false },
// { name: 'alt', label: 'Alternative Text', widget: 'string', required: false, hint: "Used for accessibility." },
// { name: 'title', label: 'Title', widget: 'string', required: false, hint: "Shown on hover." },
// { name: 'width', label: 'Width', widget: 'number', valueType: 'int', required: false },
// { name: 'height', label: 'Height', widget: 'number', valueType: 'int', required: false },
// { name: 'classes', label: 'Classes', widget: 'string', required: false },
// ],
// // Pattern to identify a block as being an instance of this component
// pattern: /^!\[(.*?)\]\((.*?)\s*(?:\"(.*?)\")?\)(?:{:\s*(?:width="([0-9]*)")?\s*(?:height="([0-9]*)?")?\s*(?:class="(.*?)")?})?$/,
// //image "(.*?)"(\s+alt="(.*?)")?(\s+caption="(.*?)")?(\s+([0-9]+)w)?(\s+([0-9]+)h)?
// //image "(.*?)"(\s+alt="(.*?)")?(\s+classes="(.*?)")?(\s+caption="(.*?)")?(\s+([0-9]+)w)?(\s+([0-9]+)h)?
// //<figure>\s*<img\s*src="(\S*)"\s*(?:alt="(.*?)")?\s*(?:class="(.*?)")?\s*(?:width="([0-9]*)")?\s*(?:height="([0-9]*)")?>\s*(?:<figcaption>(.*?)<\/figcaption>)?\s*<\/figure>
// // Function to extract data elements from the regexp match
// fromBlock: function (match) {
// return {
// alt: match[1] || '',
// image: match[2] || '',
// title: match[3] || '',
// width: match[4] || '',
// height: match[5] || '',
// classes: match[6] || ''
// };
// },
// // Function to create a text block from an instance of this component
// toBlock: function (obj) {
// var alt = obj.alt ? obj.alt : '';
// var src = obj.image ? obj.image : '';
// var title = obj.title ? ' "' + obj.title + '"' : '';
// var width = obj.width ? ' width="' + obj.width + '"' : '';
// var height = obj.height ? ' height="' + obj.height + '"' : '';
// var classes = obj.classes ? ' class="' + obj.classes + '"' : '';
// return '![' + alt + '](' + src + title + '){:' + width + height + classes + '}';
// },
// // Preview output for this component. Can either be a string or a React component
// // (component gives better render performance)
// toPreview: function (obj) {
// var src = obj.image ? ' src="' + obj.image + '"' : '';
// var alt = obj.alt ? ' alt="' + obj.alt + '"' : '';
// var title = obj.title ? ' title="' + obj.title + '"' : '';
// var classes = obj.classes ? ' class="' + obj.classes + '"' : '';
// var width = obj.width ? ' width="' + obj.width + '"' : '';
// var height = obj.height ? ' height="' + obj.height + '"' : '';
// return (
// '<img' + src + alt + title + classes + width + height + '>'
// );
// }
// });
</script>
</body>
</html>

3
assets/css/preview.scss Normal file
View File

@ -0,0 +1,3 @@
---
---
@import "preview";

3
assets/css/styles.scss Normal file
View File

@ -0,0 +1,3 @@
---
---
@import "jekflix";

BIN
assets/img/404.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2023 Fonticons, Inc.--><path d="M352 256c0 22.2-1.2 43.6-3.3 64H163.3c-2.2-20.4-3.3-41.8-3.3-64s1.2-43.6 3.3-64H348.7c2.2 20.4 3.3 41.8 3.3 64zm28.8-64H503.9c5.3 20.5 8.1 41.9 8.1 64s-2.8 43.5-8.1 64H380.8c2.1-20.6 3.2-42 3.2-64s-1.1-43.4-3.2-64zm112.6-32H376.7c-10-63.9-29.8-117.4-55.3-151.6c78.3 20.7 142 77.5 171.9 151.6zm-149.1 0H167.7c6.1-36.4 15.5-68.6 27-94.7c10.5-23.6 22.2-40.7 33.5-51.5C239.4 3.2 248.7 0 256 0s16.6 3.2 27.8 13.8c11.3 10.8 23 27.9 33.5 51.5c11.6 26 20.9 58.2 27 94.7zm-209 0H18.6C48.6 85.9 112.2 29.1 190.6 8.4C165.1 42.6 145.3 96.1 135.3 160zM8.1 192H131.2c-2.1 20.6-3.2 42-3.2 64s1.1 43.4 3.2 64H8.1C2.8 299.5 0 278.1 0 256s2.8-43.5 8.1-64zM194.7 446.6c-11.6-26-20.9-58.2-27-94.6H344.3c-6.1 36.4-15.5 68.6-27 94.6c-10.5 23.6-22.2 40.7-33.5 51.5C272.6 508.8 263.3 512 256 512s-16.6-3.2-27.8-13.8c-11.3-10.8-23-27.9-33.5-51.5zM135.3 352c10 63.9 29.8 117.4 55.3 151.6C112.2 482.9 48.6 426.1 18.6 352H135.3zm358.1 0c-30 74.1-93.6 130.9-171.9 151.6c25.5-34.2 45.2-87.7 55.3-151.6H493.4z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Some files were not shown because too many files have changed in this diff Show More