init
This commit is contained in:
commit
c09f092db4
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# Generated files by hugo
|
||||
/public/
|
||||
/resources/_gen/
|
||||
/assets/jsconfig.json
|
||||
hugo_stats.json
|
||||
|
||||
# Executable may be added to repository
|
||||
hugo.exe
|
||||
hugo.darwin
|
||||
hugo.linux
|
||||
|
||||
# Temporary lock file while building
|
||||
/.hugo_build.lock
|
||||
|
||||
content
|
5
archetypes/default.md
Normal file
5
archetypes/default.md
Normal file
@ -0,0 +1,5 @@
|
||||
+++
|
||||
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
|
||||
date = {{ .Date }}
|
||||
draft = true
|
||||
+++
|
1
assets/custom.css
Normal file
1
assets/custom.css
Normal file
@ -0,0 +1 @@
|
||||
/* Add custom CSS */
|
1
assets/custom.js
Normal file
1
assets/custom.js
Normal file
@ -0,0 +1 @@
|
||||
// Add custom JS
|
214
config/_default/hugo.toml
Normal file
214
config/_default/hugo.toml
Normal file
@ -0,0 +1,214 @@
|
||||
### General
|
||||
baseURL = '' # Enter your full production URL
|
||||
languageCode = 'fr-fr' # Default
|
||||
timeZone = 'Europe/Paris' # IANA timezone https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
title = 'RimaRima' # Site title used throughout site
|
||||
|
||||
### SEO, Analytics & 3rd-party
|
||||
enableRobotsTXT = true # To overwrite the theme's robots.txt, add your own in the /layouts/ directory
|
||||
rssLimit = -1 # -1 is unlimited RSS entries
|
||||
# googleAnalytics = '' # Enter GA tracking ID to enable GA4
|
||||
# disqusShortname = '' # Enter Disqus shortname to enable comments
|
||||
|
||||
### Content & Publishing
|
||||
# Please see https://gohugo.io/getting-started/configuration/ for detailed explanations
|
||||
buildDrafts = false # Default
|
||||
buildExpired = false # Default
|
||||
buildFuture = false # Default
|
||||
canonifyURLs = false # Default
|
||||
defaultContentLanguage = 'en' # Default
|
||||
disableAliases = true # Set to true if using server (Netlify, .htaccess) for redirects instead of Hugo
|
||||
disableKinds = [] # Default
|
||||
enableEmoji = true # Use Emojis in content
|
||||
enableGitInfo = false # Default, enable to use git for lastmod (can be overwritten in frontmatter)
|
||||
enableInlineShortcodes = false # Default, false is more security-friendly
|
||||
ignoreFiles = [] # Default
|
||||
# newContentEditor = 'code' # Set VS Code as default editor
|
||||
paginate = 10 # Default
|
||||
paginatePath = 'page' # Default
|
||||
pluralizeListTitles = true # Default
|
||||
publishDir = 'public' # Default
|
||||
relativeURLs = false # Default
|
||||
summaryLength = 70 # Default
|
||||
titleCaseStyle = 'AP' # Default, other options: Chicago (slightly different) or Go (all first letters capitalized)
|
||||
|
||||
### Other
|
||||
archetypeDir = 'archetypes' # Default
|
||||
assetDir = 'assets' # Default
|
||||
contentDir = 'content' # Default
|
||||
dataDir = 'data' # Default
|
||||
disableHugoGeneratorInject = false # Default
|
||||
disableLiveReload = false # Default
|
||||
|
||||
# Use this theme as git submodule
|
||||
theme = 'hugo-liftoff'
|
||||
# Or, use this theme as hugo module
|
||||
# [module]
|
||||
# [[module.imports]]
|
||||
# path = 'hugo-liftoff'
|
||||
|
||||
[taxonomies]
|
||||
tag = 'tags'
|
||||
category = 'categories'
|
||||
series = 'series' # Allows you to create an organized series of posts (e.g. multi-part tutorial)
|
||||
project-type = 'project types' # Categorize projects by type (e.g. client work, personal, open source, etc.)
|
||||
|
||||
[permalinks]
|
||||
[permalinks.page]
|
||||
# e.g. /subsection/example-post instead of /posts/subsection/example-post
|
||||
posts = '/:sections[last]/:slug/' # Removes 'posts' from the permalink structure for posts created under nested sub-sections
|
||||
[permalinks.section]
|
||||
# e.g. /subsection/ instead of /posts/subsection/
|
||||
posts = '/:slug/'
|
||||
|
||||
[markup]
|
||||
defaultMarkdownHandler = 'goldmark' # Default (everything under [markup] is unless otherwise specified)
|
||||
[markup.goldmark]
|
||||
[markup.goldmark.extensions]
|
||||
definitionList = true
|
||||
footnote = true
|
||||
linkify = true
|
||||
linkifyProtocol = 'https'
|
||||
strikethrough = true
|
||||
table = true
|
||||
taskList = true
|
||||
typographer = true
|
||||
[markup.goldmark.parser]
|
||||
autoHeadingID = true
|
||||
autoHeadingIDType = 'github'
|
||||
[markup.goldmark.parser.attribute]
|
||||
block = false
|
||||
title = true
|
||||
[markup.goldmark.renderer]
|
||||
hardWraps = false
|
||||
unsafe = false
|
||||
xhtml = false
|
||||
[markup.highlight]
|
||||
anchorLineNos = false
|
||||
codeFences = true
|
||||
guessSyntax = false
|
||||
hl_Lines = ''
|
||||
lineAnchors = ''
|
||||
lineNoStart = 1
|
||||
lineNos = true # Not the default
|
||||
lineNumbersInTable = false # Not the default
|
||||
noClasses = true
|
||||
noHl = false
|
||||
style = 'monokai'
|
||||
tabWidth = 4
|
||||
[markup.tableOfContents]
|
||||
endLevel = 3
|
||||
ordered = false
|
||||
startLevel = 2
|
||||
|
||||
[related]
|
||||
# Default related posts settings
|
||||
includeNewer = false
|
||||
threshold = 80
|
||||
toLower = false
|
||||
[[related.indices]]
|
||||
name = 'keywords'
|
||||
weight = 100
|
||||
[[related.indices]]
|
||||
name = 'date'
|
||||
weight = 10
|
||||
# Remove if not using tags taxonomy
|
||||
[[related.indices]]
|
||||
name = 'tags'
|
||||
weight = 80
|
||||
|
||||
[sitemap]
|
||||
# Default sitemap settings
|
||||
changefreq = 'monthly'
|
||||
filename = 'sitemap.xml'
|
||||
priority = 0.5
|
||||
|
||||
[frontmatter]
|
||||
# Default frontmatter date settings
|
||||
date = ['date', 'publishDate', 'lastmod']
|
||||
expiryDate = ['expiryDate']
|
||||
lastmod = ['lastmod', ':git', 'date', 'publishDate']
|
||||
publishDate = ['publishDate', 'date']
|
||||
|
||||
[caches]
|
||||
# Default cache settings
|
||||
[caches.assets]
|
||||
dir = ':resourceDir/_gen'
|
||||
maxAge = -1
|
||||
[caches.getcsv]
|
||||
dir = ':cacheDir/:project'
|
||||
maxAge = -1
|
||||
[caches.getjson]
|
||||
dir = ':cacheDir/:project'
|
||||
maxAge = -1
|
||||
[caches.images]
|
||||
dir = ':resourceDir/_gen'
|
||||
maxAge = -1
|
||||
[caches.modules]
|
||||
dir = ':cacheDir/modules'
|
||||
maxAge = -1
|
||||
|
||||
[imaging]
|
||||
# Default image processing settings
|
||||
anchor = 'Smart'
|
||||
bgColor = '#ffffff'
|
||||
hint = 'photo'
|
||||
quality = 75
|
||||
resampleFilter = 'Box'
|
||||
|
||||
### Hugo Pipes
|
||||
[minify]
|
||||
disableCSS = false
|
||||
disableHTML = false
|
||||
disableJS = false
|
||||
disableJSON = false
|
||||
disableSVG = false
|
||||
disableXML = false
|
||||
minifyOutput = false
|
||||
[minify.tdewolff]
|
||||
[minify.tdewolff.css]
|
||||
keepCSS2 = true
|
||||
precision = 0
|
||||
[minify.tdewolff.html]
|
||||
keepComments = false
|
||||
keepConditionalComments = true
|
||||
keepDefaultAttrVals = true
|
||||
keepDocumentTags = true
|
||||
keepEndTags = true
|
||||
keepQuotes = false
|
||||
keepWhitespace = false
|
||||
[minify.tdewolff.js]
|
||||
keepVarNames = false
|
||||
noNullishOperator = false
|
||||
precision = 0
|
||||
[minify.tdewolff.json]
|
||||
keepNumbers = false
|
||||
precision = 0
|
||||
[minify.tdewolff.svg]
|
||||
precision = 0
|
||||
[minify.tdewolff.xml]
|
||||
keepWhitespace = false
|
||||
|
||||
### Netlify settings
|
||||
# add redirects/headers
|
||||
[outputs]
|
||||
home = ["HTML", "RSS", "REDIRECTS", "HEADERS"]
|
||||
|
||||
# remove .{ext} from text/netlify
|
||||
[mediaTypes."text/netlify"]
|
||||
suffixes = [""]
|
||||
delimiter = ""
|
||||
|
||||
# add output format for netlify _redirects
|
||||
[outputFormats.REDIRECTS]
|
||||
mediatype = "text/netlify"
|
||||
baseName = "_redirects"
|
||||
isPlainText = true
|
||||
notAlternative = true
|
||||
|
||||
# add output format for netlify _headers
|
||||
[outputFormats.HEADERS]
|
||||
mediatype = "text/netlify"
|
||||
baseName = "_headers"
|
||||
isPlainText = true
|
||||
notAlternative = true
|
84
config/_default/menus.toml
Normal file
84
config/_default/menus.toml
Normal file
@ -0,0 +1,84 @@
|
||||
[[main]]
|
||||
# Top-level menu entry
|
||||
identifier = "work"
|
||||
name = "Work"
|
||||
url = "/projects/"
|
||||
weight = 1
|
||||
|
||||
[[main]]
|
||||
identifier = "projects"
|
||||
name = "Projects"
|
||||
url = "/projects/"
|
||||
parent = "work"
|
||||
weight = 1
|
||||
|
||||
[[main]]
|
||||
identifier = "about"
|
||||
name = "About"
|
||||
url = "/about/"
|
||||
parent = "work"
|
||||
weight = 2
|
||||
|
||||
[[main]]
|
||||
identifier = "contact"
|
||||
name = "Contact"
|
||||
url = "/contact/"
|
||||
parent = "work"
|
||||
weight = 3
|
||||
|
||||
[[main]]
|
||||
# Top-level menu entry
|
||||
identifier = "writing"
|
||||
name = "Writing"
|
||||
url = "/posts/"
|
||||
weight = 4
|
||||
|
||||
[[main]]
|
||||
identifier = "posts"
|
||||
name = "All Posts"
|
||||
url = "/posts/"
|
||||
parent = "writing"
|
||||
weight = 4
|
||||
|
||||
[[main]]
|
||||
identifier = "subsection"
|
||||
name = "Subsection"
|
||||
url = "/subsection/"
|
||||
# url = "/posts/subsection/" # Remove url param from subsection/_index.md frontmatter to use full permalink
|
||||
parent = "writing"
|
||||
weight = 5
|
||||
|
||||
[[main]]
|
||||
# Top-level menu entry
|
||||
identifier = "explore"
|
||||
name = "Explore"
|
||||
url = "/categories/"
|
||||
weight = 6
|
||||
|
||||
[[main]]
|
||||
identifier = "categories"
|
||||
name = "Categories"
|
||||
url = "/categories/"
|
||||
parent = "explore"
|
||||
weight = 6
|
||||
|
||||
[[main]]
|
||||
identifier = "tags"
|
||||
name = "Tags"
|
||||
url = "/tags/"
|
||||
parent = "explore"
|
||||
weight = 7
|
||||
|
||||
[[main]]
|
||||
identifier = "series"
|
||||
name = "Series"
|
||||
url = "/series/"
|
||||
parent = "explore"
|
||||
weight = 8
|
||||
|
||||
[[main]]
|
||||
identifier = "project-type"
|
||||
name = "Project Types"
|
||||
url = "/project-types/"
|
||||
parent = "explore"
|
||||
weight = 9
|
65
config/_default/params.toml
Normal file
65
config/_default/params.toml
Normal file
@ -0,0 +1,65 @@
|
||||
### SEO, Analytics & 3rd-party
|
||||
netlify_forms = true # add data-netlify attribute to contact and newsletter forms, false to disable Netlify forms
|
||||
# gtm_id = '' # GTM tracking (leave blank to use GA)
|
||||
disallow_search_engines = false # Disallow search engine crawling in robots.txt
|
||||
|
||||
### Content
|
||||
favicon = true # Enable favicon, add your favicon files to /static/ directory
|
||||
# avatar = 'avatar.png' # Custom avatar image in /assets/
|
||||
grayscale_avatar = true # Add a grayscale filter to the avatar image
|
||||
author = 'John Doe' # Default author for <head> meta
|
||||
description = "Personal blog and portfolio site of John Doe." # Add a global meta description to <head>
|
||||
footer_text = "Built with [Hugo Liftoff](https://github.com/wjh18/hugo-liftoff) theme." # Customize footer text
|
||||
fallback_text = "No content available yet. Coming soon." # Fallback text for empty content
|
||||
label_drafts = true # Add a label indicator next to the title of any built drafts (dev only)
|
||||
|
||||
# Customize newsletter text
|
||||
newsletter_header = "This is my custom newsletter header with a captivating title."
|
||||
newsletter_description = "This is my custom newsletter description that tells you why you should sign up."
|
||||
newsletter_submit = "Join now"
|
||||
global_newsletter = false # Enable newsletter site-wide
|
||||
|
||||
# CSS / JavaScript
|
||||
enable_postcss = false # Enable if you're using npm and want to utilize PostCSS processing
|
||||
custom_css = 'custom.css' # Add the specified file to assets before setting this param to avoid errors
|
||||
custom_js = 'custom.js' # Add the specified file to assets before setting this param to avoid errors
|
||||
|
||||
### Web schemas
|
||||
# Open Graph
|
||||
images = ['images/default.png'] # Fallback for Open Graph and Twitter Cards images if none are present in front matter. Enter path to the image.
|
||||
ogLocale = "en_US" # Open graph locale
|
||||
|
||||
# Twitter Cards
|
||||
twitterSite = "johndoestwitter" # Enter your twitter handle without the @
|
||||
twitterCreator = "johndoestwitter" # Enter your twitter handle without the @
|
||||
|
||||
# JSON-LD structured data schemas
|
||||
schemaName = "John Doe" # Enter your name
|
||||
schemaLocale = "en-US" # Structured data locale
|
||||
schemaImage = "images/default.png" # Image for Person structured data schema. Enter path to the image.
|
||||
schemaImageWidth = 453 # Width of the above image
|
||||
schemaImageHeight = 455 # Height of the above image
|
||||
|
||||
### Social
|
||||
# Show social links in footer, home hero section, or about page
|
||||
footer_socials = true
|
||||
home_hero_socials = true
|
||||
about_page_socials = true
|
||||
|
||||
# Enable or disable individual social icons
|
||||
[social.links]
|
||||
twitter = "username"
|
||||
github = "username"
|
||||
stack_overflow = "userid/username" # include user id
|
||||
email = "user@example.com"
|
||||
# linkedin = "username" # Comment out to disable
|
||||
# mastodon_server = "example.social" # include subdomains if relevant, scheme not needed (defaults to https)
|
||||
# mastodon_user = "username" # don't include preceding @
|
||||
|
||||
# Enable or disable individual social share icons in posts
|
||||
[social.share]
|
||||
#facebook = true
|
||||
#linkedin = true
|
||||
#twitter = true
|
||||
#reddit = true
|
||||
#email = true
|
9
config/development/server.toml
Normal file
9
config/development/server.toml
Normal file
@ -0,0 +1,9 @@
|
||||
# Adds custom security headers for development environment only
|
||||
[[headers]]
|
||||
for = '/**'
|
||||
[headers.values]
|
||||
# Content-Security-Policy = 'script-src localhost:1313'
|
||||
Referrer-Policy = 'strict-origin-when-cross-origin'
|
||||
X-Content-Type-Options = 'nosniff'
|
||||
X-Frame-Options = 'DENY'
|
||||
X-XSS-Protection = '1; mode=block'
|
3
config/production/hugo.toml
Normal file
3
config/production/hugo.toml
Normal file
@ -0,0 +1,3 @@
|
||||
### Config for production environment
|
||||
# Includes but overwrites anything in _default/config.toml
|
||||
# Excludes anything in _development/config.toml if it exists
|
3
config/production/params.toml
Normal file
3
config/production/params.toml
Normal file
@ -0,0 +1,3 @@
|
||||
### Params for production environment
|
||||
# Includes but overwrites anything in _default/params.toml
|
||||
# Excludes anything in _development/params.toml if it exists
|
3
hugo.toml
Normal file
3
hugo.toml
Normal file
@ -0,0 +1,3 @@
|
||||
baseURL = ''
|
||||
languageCode = 'fr-fr'
|
||||
title = 'RimaRima'
|
0
static/.keep
Normal file
0
static/.keep
Normal file
12
themes/hugo-liftoff/CONTRIBUTING.md
Normal file
12
themes/hugo-liftoff/CONTRIBUTING.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Contributing
|
||||
|
||||
For any proposed changes or bug reports, please [open an issue](https://github.com/wjh18/hugo-liftoff/issues) first using one of the issue templates. Then feel free to work on it. You're also welcome to tackle any existing issues.
|
||||
|
||||
## How to contribute
|
||||
|
||||
* Fork the project on Github
|
||||
* Clone the fork to your local machine
|
||||
* Create a descriptive branch for the changes
|
||||
* Make and commit your changes to the new branch
|
||||
* Push your changes to the branch
|
||||
* Submit a pull request on Github using the [pull request template](https://github.com/wjh18/hugo-liftoff/blob/master/.github/pull_request_template.md).
|
20
themes/hugo-liftoff/LICENSE
Normal file
20
themes/hugo-liftoff/LICENSE
Normal file
@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Will J. Holmes
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
169
themes/hugo-liftoff/README.md
Normal file
169
themes/hugo-liftoff/README.md
Normal file
@ -0,0 +1,169 @@
|
||||
# Hugo Liftoff
|
||||
|
||||
**Warning: I no longer have time to work on this theme for various reasons. It's unlikely I'll get to your issue and no additional features are planned, although the theme will remain available to the public. Feel free to fork it if you need to make extensive changes. I will consider merging simple bugfix pull requests. Apologies for any inconvenience this may cause. Please see [v3.4.3 release notes](https://github.com/wjh18/hugo-liftoff/releases/tag/v3.4.3) for further details.**
|
||||
|
||||
## About
|
||||
|
||||
Hugo Liftoff is a minimal blog/portfolio theme with a focus on content creation and SEO best practices. It's an ideal choice for technical users jump-starting a personal brand.
|
||||
|
||||
## Documentation
|
||||
|
||||
The full documentation is hosted on this repo's [Github Wiki](https://github.com/wjh18/hugo-liftoff/wiki).
|
||||
|
||||
Please open an issue if you find any mistakes in the docs or have suggestions for improvement.
|
||||
|
||||
## Demo Site
|
||||
|
||||
A working [demo of the theme](https://hugo-liftoff.netlify.app/) is available to the public for evaluation.
|
||||
|
||||
The `exampleSite` content included with the theme, which you're free to copy into your own project, mirrors the content used in the demo. The idea behind this is to help you get started quickly and replicate any features you saw in the demo that you think could be useful in your own project.
|
||||
|
||||
## Notable Features
|
||||
|
||||
* Content subsections with the ability to filter recent posts on homepage by subsection
|
||||
* Series posts taxonomy with single posts that list all posts in the current series
|
||||
* Next/prev links at the end of single posts for subsections or series posts (if enabled)
|
||||
* Light/dark mode toggle using CSS custom properties
|
||||
* Mobile-responsive, collapsible JS menu with automatic submenu support based on menu config
|
||||
* Customizable newsletter with Netlify Forms support and conditional visibility control
|
||||
* And much more...
|
||||
|
||||
## Overview of Features
|
||||
|
||||
Below are the current features of this theme. Features labeled *optional* or *frontmatter* can be enabled/disabled in config or frontmatter, respectively.
|
||||
|
||||
### Netlify
|
||||
|
||||
* Custom headers / redirects with Netlify (optional)
|
||||
* Netlify forms support for newsletter opt-in and contact page (optional)
|
||||
* Sample `netlify.toml` file for streamlined deployment
|
||||
|
||||
### 3rd Party
|
||||
|
||||
* Google Analytics v4
|
||||
* Google Tag Manager as an alternative to GA (optional)
|
||||
* Disqus comments (optional)
|
||||
* Disable comments on a per-page basis (optional) (frontmatter)
|
||||
|
||||
### Newsletter
|
||||
|
||||
* Newsletter opt-in with Netlify Forms support (optional) (frontmatter)
|
||||
* Global display of newsletter opt-in (optional)
|
||||
* Customizable newsletter header, description and CTA text (optional)
|
||||
* Override global newsletter on a per-page basis (optional) (frontmatter)
|
||||
* Enable or disable newsletter on a per-page basis (frontmatter)
|
||||
|
||||
### Social
|
||||
|
||||
* Native Twitter, Mastodon, Github, Stack Overflow, LinkedIn and email social links with SVG (optional)
|
||||
* Enable or disable social links in footer, homepage hero, and about page (optional)
|
||||
* Enable or disable individual social links (optional)
|
||||
* Facebook, LinkedIn, Twitter, Reddit and email social share icons with SVG for posts (optional)
|
||||
* Enable or disable individual social share icons (optional)
|
||||
|
||||
### SEO / RSS
|
||||
|
||||
* Enhanced Open Graph, Twitter Cards, and Schema.org templates
|
||||
* RSS feed that excludes any pages outside of the posts section
|
||||
* Customizable title and SEO title tags or use title for both (frontmatter)
|
||||
* Customizable summary and meta description or use description for both (frontmatter)
|
||||
* Custom author meta tag (optional) (frontmatter)
|
||||
* Custom title tags and meta descriptions for every page (optional) (frontmatter)
|
||||
* `robots.txt` and `sitemap.xml`
|
||||
* Disable search engine crawling (optional)
|
||||
|
||||
### Series / Subsections
|
||||
|
||||
* Content subsections with the ability to filter recent posts on homepage by subsection (optional)
|
||||
* Series posts taxonomy with single posts that list all posts in the current series (optional)
|
||||
* Next/prev links at the end of single posts for subsections or series posts (if enabled)
|
||||
* Subsection support for posts with custom permalinks for clean SEO URLs (optional)
|
||||
* Mobile-responsive, collapsible JS menu with automatic submenu support based on menu config
|
||||
|
||||
### Homepage
|
||||
|
||||
* Customize hero title and subtitle on homepage (frontmatter)
|
||||
* Customize posts and projects section headings on homepage (frontmatter)
|
||||
|
||||
### Posts & Projects
|
||||
|
||||
* Toggle-able sticky table of contents for posts (frontmatter)
|
||||
* Related posts (frontmatter)
|
||||
* Social share icons for posts (frontmatter)
|
||||
* Reading time and word count for posts
|
||||
* Last modified dates for posts (optional)
|
||||
* Customizable live URL, source URL and tech stack details for projects (frontmatter)
|
||||
* Tag and category taxonomies
|
||||
* Project type taxonomy for categorizing projects
|
||||
* Recent posts and projects on homepage
|
||||
|
||||
### Code snippets
|
||||
|
||||
* Syntax highlighting
|
||||
* One-click copy button and language indicator for code snippets
|
||||
|
||||
### CSS / JS
|
||||
|
||||
* Light/dark mode toggle using CSS custom properties
|
||||
* Add custom CSS / JS in `assets`
|
||||
* CSS and JS minification
|
||||
* Frontend build pipeline with ESBuild and ToCSS
|
||||
* PostCSS processing for autoprefixing (optional)
|
||||
* `npm` completely optional unless using PostCSS / Autoprefixer
|
||||
* Fluid typography scale with CSS `clamp()`
|
||||
* Sourcemaps for SCSS and JS in development
|
||||
|
||||
### Images
|
||||
|
||||
* Image processing with Hugo resources
|
||||
* Feature images for posts and projects from `assets` or page bundle (frontmatter)
|
||||
* Custom homepage hero avatar image (optional)
|
||||
* Disable grayscale avatar filter (optional)
|
||||
* Enable/disable favicons (optional)
|
||||
|
||||
### Archetypes
|
||||
|
||||
* Archetype templates for posts and projects
|
||||
* Page bundle support for archetype templates
|
||||
|
||||
### Markdown Hooks
|
||||
|
||||
* Markdown render hooks for codeblocks, images, headings and links
|
||||
* Language indicator for codeblocks
|
||||
* Add custom CSS class to markdown images via URL fragments
|
||||
* Heading anchor link SVG icon
|
||||
|
||||
### Other Content
|
||||
|
||||
* Create generic single pages quickly with the default single template (optional)
|
||||
* Additional markdown footer text (optional)
|
||||
* Add a label to drafts in development (optional)
|
||||
* Responsive support for common markdown styles like tables
|
||||
* About page with social links (optional)
|
||||
* Contact page with Netlify Forms support (optional)
|
||||
* Customize fallback text for empty content (optional)
|
||||
|
||||
### Hugo Defaults
|
||||
|
||||
* Example `hugo.toml` with the majority of Hugo config defaults included for easy customization
|
||||
* Override config settings based on Hugo environment
|
||||
* Built-in shortcodes
|
||||
* And much more...Hugo has a lot to offer!
|
||||
|
||||
## Planned Features
|
||||
|
||||
The following features are planned for a future release.
|
||||
|
||||
* Real-time site search
|
||||
* Image galleries for projects
|
||||
* i18n support
|
||||
* Additional advanced Google structured data schemas
|
||||
* Custom shortcodes for things like project lists
|
||||
|
||||
## Getting Help
|
||||
|
||||
To submit a bug report, feature request, or usage questions, please open an [issue](https://github.com/wjh18/hugo-liftoff/issues) on Github using one of the issue templates.
|
||||
|
||||
## Contributing
|
||||
|
||||
If you'd like to contribute to the project, fork it and submit a pull request with your changes using the [pull request template](https://github.com/wjh18/hugo-liftoff/blob/master/.github/pull_request_template.md). Please see the [Contribution Guidelines](https://github.com/wjh18/hugo-liftoff/blob/master/CONTRIBUTING.md) for more details.
|
13
themes/hugo-liftoff/archetypes/default.md
Normal file
13
themes/hugo-liftoff/archetypes/default.md
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
title: {{ replace .Name "-" " " | title }}
|
||||
seo_title: {{ replace .Name "-" " " | title }}
|
||||
description:
|
||||
slug: {{ .Name }}
|
||||
author: {{ .Site.Params.author }}
|
||||
|
||||
draft: true
|
||||
date: {{ .Date }}
|
||||
|
||||
newsletter: true
|
||||
---
|
||||
|
28
themes/hugo-liftoff/archetypes/post-bundle/index.md
Normal file
28
themes/hugo-liftoff/archetypes/post-bundle/index.md
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
title: {{ replace .Name "-" " " | title }}
|
||||
seo_title: {{ replace .Name "-" " " | title }}
|
||||
summary:
|
||||
description:
|
||||
slug: {{ .Name }}
|
||||
author: {{ .Site.Params.author }}
|
||||
|
||||
draft: true
|
||||
date: {{ .Date }}
|
||||
lastmod:
|
||||
expiryDate:
|
||||
publishDate:
|
||||
|
||||
feature_image:
|
||||
feature_image_alt:
|
||||
|
||||
categories:
|
||||
tags:
|
||||
series:
|
||||
|
||||
toc: true
|
||||
related: true
|
||||
social_share: true
|
||||
newsletter: true
|
||||
disable_comments: false
|
||||
---
|
||||
|
28
themes/hugo-liftoff/archetypes/posts.md
Normal file
28
themes/hugo-liftoff/archetypes/posts.md
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
title: {{ replace .Name "-" " " | title }}
|
||||
seo_title: {{ replace .Name "-" " " | title }}
|
||||
summary:
|
||||
description:
|
||||
slug: {{ .Name }}
|
||||
author: {{ .Site.Params.author }}
|
||||
|
||||
draft: true
|
||||
date: {{ .Date }}
|
||||
lastmod:
|
||||
expiryDate:
|
||||
publishDate:
|
||||
|
||||
feature_image:
|
||||
feature_image_alt:
|
||||
|
||||
categories:
|
||||
tags:
|
||||
series:
|
||||
|
||||
toc: true
|
||||
related: true
|
||||
social_share: true
|
||||
newsletter: true
|
||||
disable_comments: false
|
||||
---
|
||||
|
26
themes/hugo-liftoff/archetypes/project-bundle/index.md
Normal file
26
themes/hugo-liftoff/archetypes/project-bundle/index.md
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
title: {{ replace .Name "-" " " | title }}
|
||||
seo_title: {{ replace .Name "-" " " | title }}
|
||||
summary:
|
||||
description:
|
||||
slug: {{ .Name }}
|
||||
author: {{ .Site.Params.author }}
|
||||
|
||||
draft: true
|
||||
date: {{ .Date }}
|
||||
lastmod:
|
||||
expiryDate:
|
||||
publishDate:
|
||||
|
||||
feature_image:
|
||||
feature_image_alt:
|
||||
|
||||
project types:
|
||||
|
||||
techstack:
|
||||
live_url:
|
||||
source_url:
|
||||
|
||||
newsletter: true
|
||||
---
|
||||
|
26
themes/hugo-liftoff/archetypes/projects.md
Normal file
26
themes/hugo-liftoff/archetypes/projects.md
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
title: {{ replace .Name "-" " " | title }}
|
||||
seo_title: {{ replace .Name "-" " " | title }}
|
||||
summary:
|
||||
description:
|
||||
slug: {{ .Name }}
|
||||
author: {{ .Site.Params.author }}
|
||||
|
||||
draft: true
|
||||
date: {{ .Date }}
|
||||
lastmod:
|
||||
expiryDate:
|
||||
publishDate:
|
||||
|
||||
feature_image:
|
||||
feature_image_alt:
|
||||
|
||||
project types:
|
||||
|
||||
techstack:
|
||||
live_url:
|
||||
source_url:
|
||||
|
||||
newsletter: true
|
||||
---
|
||||
|
BIN
themes/hugo-liftoff/assets/images/default.png
Normal file
BIN
themes/hugo-liftoff/assets/images/default.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 93 KiB |
3
themes/hugo-liftoff/assets/js/app.js
Normal file
3
themes/hugo-liftoff/assets/js/app.js
Normal file
@ -0,0 +1,3 @@
|
||||
import { switcher, clipboard, toggleToc } from './components/components';
|
||||
import { header } from './layouts/header';
|
||||
import { home } from './pages/home';
|
44
themes/hugo-liftoff/assets/js/components/clipboard.js
Normal file
44
themes/hugo-liftoff/assets/js/components/clipboard.js
Normal file
@ -0,0 +1,44 @@
|
||||
// Adapted from the following tutorials:
|
||||
// https://www.dannyguo.com/blog/how-to-add-copy-to-clipboard-buttons-to-code-blocks-in-hugo/
|
||||
// https://aaronluna.dev/blog/add-copy-button-to-code-blocks-hugo-chroma/
|
||||
// https://logfetch.com/hugo-add-copy-to-clipboard-button/
|
||||
|
||||
const addCopyButtons = (clipboard) => {
|
||||
// 1. Look for pre > code elements in the DOM
|
||||
document.querySelectorAll('.highlight > pre > code').forEach((codeBlock) => {
|
||||
// 2. Create a button that will trigger a copy operation
|
||||
const button = document.createElement('button');
|
||||
const svgCopy = '<svg role="img" aria-hidden="true" aria-labelledby="clipboardCopy" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><title id="clipboardCopy">Copy the code snippet contents</title><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg>';
|
||||
const svgCheck = '<svg role="img" aria-hidden="true" aria-labelledby="clipboardCheckmark" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><title id="clipboardCheckmark">Code snippet contents copied</title><path fill-rule="evenodd" fill="rgb(63, 185, 80)" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path></svg>';
|
||||
button.className = 'clipboard-button';
|
||||
button.type = 'button';
|
||||
button.innerHTML = svgCopy;
|
||||
button.addEventListener('click', () => {
|
||||
let textToCopy = '';
|
||||
let codeBlockChildren = Array.from(codeBlock.children)
|
||||
codeBlockChildren.forEach(function(span) {
|
||||
// lastChild is required to avoid copying line numbers
|
||||
textToCopy += span.lastChild.innerText;
|
||||
});
|
||||
clipboard.writeText(textToCopy).then(
|
||||
() => {
|
||||
button.blur();
|
||||
button.innerHTML = svgCheck;
|
||||
setTimeout(() => (button.innerHTML = svgCopy), 2000);
|
||||
},
|
||||
(error) => (button.innerHTML = 'Error')
|
||||
);
|
||||
});
|
||||
// 3. Append the button directly before the pre tag
|
||||
const pre = codeBlock.parentNode;
|
||||
pre.parentNode.insertBefore(button, pre);
|
||||
});
|
||||
};
|
||||
|
||||
const clipboard = (() => {
|
||||
if (navigator && navigator.clipboard) {
|
||||
addCopyButtons(navigator.clipboard);
|
||||
}
|
||||
})();
|
||||
|
||||
export { clipboard };
|
3
themes/hugo-liftoff/assets/js/components/components.js
Normal file
3
themes/hugo-liftoff/assets/js/components/components.js
Normal file
@ -0,0 +1,3 @@
|
||||
export { switcher } from './switchTheme';
|
||||
export { clipboard } from './clipboard';
|
||||
export { toggleToc } from './toc';
|
46
themes/hugo-liftoff/assets/js/components/switchTheme.js
Normal file
46
themes/hugo-liftoff/assets/js/components/switchTheme.js
Normal file
@ -0,0 +1,46 @@
|
||||
// Adapted from https://github.com/CodyHouse/dark-light-mode-switch
|
||||
|
||||
function switchTheme() {
|
||||
let themeSwitch = document.getElementById('themeSwitch');
|
||||
if (themeSwitch) {
|
||||
initTheme();
|
||||
|
||||
themeSwitch.addEventListener('change', () => {
|
||||
resetTheme();
|
||||
});
|
||||
|
||||
function initTheme() {
|
||||
let lsItem = localStorage.getItem('themeSwitch');
|
||||
let darkThemeSelected = false;
|
||||
if (lsItem !== null) {
|
||||
darkThemeSelected = lsItem === 'dark';
|
||||
} else {
|
||||
darkThemeSelected = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
|
||||
themeSwitch.checked = darkThemeSelected;
|
||||
resetTheme();
|
||||
}
|
||||
|
||||
function resetTheme() {
|
||||
if (themeSwitch.checked) {
|
||||
document.body.setAttribute('data-theme', 'dark');
|
||||
localStorage.setItem('themeSwitch', 'dark');
|
||||
} else {
|
||||
document.body.removeAttribute('data-theme');
|
||||
localStorage.setItem('themeSwitch', 'light');
|
||||
}
|
||||
|
||||
// Reset Disqus to match new color scheme
|
||||
if (typeof DISQUS !== "undefined") {
|
||||
DISQUS.reset({ reload: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const switcher = (() => {
|
||||
switchTheme();
|
||||
})();
|
||||
|
||||
export { switcher };
|
12
themes/hugo-liftoff/assets/js/components/toc.js
Normal file
12
themes/hugo-liftoff/assets/js/components/toc.js
Normal file
@ -0,0 +1,12 @@
|
||||
const toggleToc = (() => {
|
||||
let tocToggle = document.getElementById('js-toc-toggle');
|
||||
let tocContents = document.getElementById('js-toc-contents');
|
||||
|
||||
if (tocToggle) {
|
||||
tocToggle.addEventListener('click', () => {
|
||||
tocContents.classList.toggle('toc-contents--active');
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
export { toggleToc };
|
44
themes/hugo-liftoff/assets/js/layouts/header.js
Normal file
44
themes/hugo-liftoff/assets/js/layouts/header.js
Normal file
@ -0,0 +1,44 @@
|
||||
// Show or hide nav on click of menu burger
|
||||
function toggleNav() {
|
||||
let mainMenu = document.getElementById('js-menu');
|
||||
let navBarToggle = document.getElementById('js-navbar-toggle');
|
||||
|
||||
navBarToggle.addEventListener('click', () => {
|
||||
mainMenu.classList.toggle('menu--active');
|
||||
removeSubMenus();
|
||||
});
|
||||
}
|
||||
|
||||
// Show or hide menu items on mobile
|
||||
function toggleMobileMenu() {
|
||||
let menuItems = document.querySelectorAll('.menu-item');
|
||||
|
||||
menuItems.forEach(function(item) {
|
||||
item.addEventListener('click', () => {
|
||||
let subMenu = item.querySelector('.sub-menu');
|
||||
if (subMenu.classList.contains('sub-menu--active')) {
|
||||
subMenu.classList.remove('sub-menu--active');
|
||||
} else {
|
||||
removeSubMenus();
|
||||
subMenu.classList.add('sub-menu--active');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Collapse submenus
|
||||
function removeSubMenus() {
|
||||
let subMenus = document.querySelectorAll('.sub-menu');
|
||||
subMenus.forEach(function(sub) {
|
||||
if (sub.classList.contains('sub-menu--active')) {
|
||||
sub.classList.remove('sub-menu--active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const header = (() => {
|
||||
toggleNav();
|
||||
toggleMobileMenu();
|
||||
})();
|
||||
|
||||
export { header };
|
21
themes/hugo-liftoff/assets/js/pages/home.js
Normal file
21
themes/hugo-liftoff/assets/js/pages/home.js
Normal file
@ -0,0 +1,21 @@
|
||||
function filterPosts() {
|
||||
let selectPosts = document.getElementById('select-posts');
|
||||
let entries = document.querySelectorAll('.post-entry-filter');
|
||||
if (selectPosts) {
|
||||
selectPosts.addEventListener('change', () => {
|
||||
entries.forEach(function(entry) {
|
||||
if (entry.classList.contains(`entry--${selectPosts.value}`) | selectPosts.value === 'all-posts') {
|
||||
entry.style.display = 'block';
|
||||
} else {
|
||||
entry.style.display = 'none';
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const home = (() => {
|
||||
filterPosts();
|
||||
})();
|
||||
|
||||
export { home };
|
30
themes/hugo-liftoff/assets/scss/abstracts/_functions.scss
Normal file
30
themes/hugo-liftoff/assets/scss/abstracts/_functions.scss
Normal file
@ -0,0 +1,30 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// This file contains all application-wide Sass functions.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Native `url(..)` function wrapper
|
||||
/// @param {String} $base - base URL for the asset
|
||||
/// @param {String} $type - asset type folder (e.g. `fonts/`)
|
||||
/// @param {String} $path - asset path
|
||||
/// @return {Url}
|
||||
@function asset($base, $type, $path) {
|
||||
@return url($base + $type + $path);
|
||||
}
|
||||
|
||||
/// Returns URL to an image based on its path
|
||||
/// @param {String} $path - image path
|
||||
/// @param {String} $base [$base-url] - base URL
|
||||
/// @return {Url}
|
||||
/// @require $base-url
|
||||
@function image($path, $base: $base-url) {
|
||||
@return asset($base, 'images/', $path);
|
||||
}
|
||||
|
||||
/// Returns URL to a font based on its path
|
||||
/// @param {String} $path - font path
|
||||
/// @param {String} $base [$base-url] - base URL
|
||||
/// @return {Url}
|
||||
/// @require $base-url
|
||||
@function font($path, $base: $base-url) {
|
||||
@return asset($base, 'fonts/', $path);
|
||||
}
|
60
themes/hugo-liftoff/assets/scss/abstracts/_mixins.scss
Normal file
60
themes/hugo-liftoff/assets/scss/abstracts/_mixins.scss
Normal file
@ -0,0 +1,60 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// This file contains all application-wide Sass mixins.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Event wrapper
|
||||
/// @author Harry Roberts
|
||||
/// @param {Bool} $self [false] - Whether or not to include current selector
|
||||
/// @link https://twitter.com/csswizardry/status/478938530342006784 Original tweet from Harry Roberts
|
||||
@mixin on-event($self: false) {
|
||||
@if $self {
|
||||
&,
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus,
|
||||
&:focus-within {
|
||||
@content;
|
||||
}
|
||||
} @else {
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus,
|
||||
&:focus-within {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Make a context based selector a little more friendly
|
||||
/// @author Kitty Giraudel
|
||||
/// @param {String} $context
|
||||
@mixin when-inside($context) {
|
||||
#{$context} & {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
/// Mixin to manage responsive breakpoints
|
||||
/// @author Kitty Giraudel
|
||||
/// @param {String} $breakpoint - Breakpoint name
|
||||
/// @require $breakpoints
|
||||
@mixin respond-to($breakpoint) {
|
||||
// If the key exists in the map
|
||||
@if map-has-key($breakpoints, $breakpoint) {
|
||||
// Prints a media query based on the value
|
||||
@media (min-width: map-get($breakpoints, $breakpoint)) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
// If the key doesn't exist in the map
|
||||
@else {
|
||||
@warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. "
|
||||
+ "Available breakpoints are: #{map-keys($breakpoints)}.";
|
||||
}
|
||||
}
|
||||
|
||||
@mixin font-size($step) {
|
||||
font-size: var(--font-size-#{$step});
|
||||
line-height: calc(8px + 2ex);
|
||||
}
|
92
themes/hugo-liftoff/assets/scss/abstracts/_variables.scss
Normal file
92
themes/hugo-liftoff/assets/scss/abstracts/_variables.scss
Normal file
@ -0,0 +1,92 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// This file contains all application-wide Sass variables.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
:root, [data-theme="default"] {
|
||||
--color-primary: rgb(18, 120, 175);
|
||||
--color-inline-code: hsl(0, 81%, 35%);
|
||||
|
||||
/* color contrasts */
|
||||
--color-bg: rgb(248, 248, 248);
|
||||
--color-contrast-lower: hsl(0, 0%, 95%);
|
||||
--color-contrast-low: hsl(240, 1%, 83%);
|
||||
--color-contrast-medium-low: hsl(240, 1%, 65%);
|
||||
--color-contrast-medium: hsl(240, 1%, 48%);
|
||||
--color-contrast-medium-high: hsl(240, 2%, 34%);
|
||||
--color-contrast-high: hsl(240, 4%, 20%);
|
||||
--color-contrast-higher: black;
|
||||
|
||||
--color-text: var(--color-contrast-high);
|
||||
|
||||
--font-size-sm: clamp(0.8rem, 0.17vw + 0.76rem, 0.89rem);
|
||||
--font-size-base: clamp(1rem, 0.34vw + 0.91rem, 1.19rem);
|
||||
--font-size-md: clamp(1.25rem, 0.61vw + 1.1rem, 1.58rem);
|
||||
--font-size-lg: clamp(1.56rem, 1vw + 1.31rem, 2.11rem);
|
||||
--font-size-xl: clamp(1.95rem, 1.56vw + 1.56rem, 2.81rem);
|
||||
--font-size-xxl: clamp(2.44rem, 2.38vw + 1.85rem, 3.75rem);
|
||||
--font-size-xxxl: clamp(3.05rem, 3.54vw + 2.17rem, 5rem);
|
||||
}
|
||||
|
||||
[data-theme] {
|
||||
background-color: var(--color-bg);
|
||||
color: var(--color-contrast-high);
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
--color-primary: rgb(86, 184, 237);
|
||||
--color-inline-code: hsl(0, 81%, 70%);
|
||||
|
||||
/* color contrasts */
|
||||
--color-bg: rgb(18, 18, 18);
|
||||
--color-contrast-lower: hsl(240, 6%, 15%);
|
||||
--color-contrast-low: hsl(252, 4%, 25%);
|
||||
--color-contrast-medium-low: hsl(240, 2%, 34%);
|
||||
--color-contrast-medium: hsl(240, 1%, 57%);
|
||||
--color-contrast-medium-high: hsl(240, 1%, 65%);
|
||||
--color-contrast-high: hsl(0, 0%, 89%);
|
||||
--color-contrast-higher: white;
|
||||
|
||||
--color-text: var(--color-contrast-high);
|
||||
}
|
||||
|
||||
|
||||
// Fonts
|
||||
|
||||
/// Regular font family
|
||||
/// @type List
|
||||
$text-font-stack: 'Roboto', 'Helvetica Neue Light', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
|
||||
|
||||
/// Code (monospace) font family
|
||||
/// @type List
|
||||
$code-font-stack: 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Monaco', monospace;
|
||||
|
||||
|
||||
// Containers
|
||||
|
||||
/// Container's maximum width
|
||||
/// @type Length
|
||||
$max-width: 1180px;
|
||||
|
||||
|
||||
// Responsiveness
|
||||
|
||||
/// Breakpoints map
|
||||
/// @prop {String} keys - Keys are identifiers mapped to a given length
|
||||
/// @prop {Map} values - Values are actual breakpoints expressed in pixels
|
||||
$breakpoints: (
|
||||
'x-small': 320px,
|
||||
'small': 576px,
|
||||
'medium': 768px,
|
||||
'm-large': 900px,
|
||||
'large': 1024px,
|
||||
'x-large': 1200px,
|
||||
);
|
||||
|
||||
|
||||
// Assets
|
||||
|
||||
/// Relative or absolute URL where all assets are served from
|
||||
/// @type String
|
||||
/// @example scss - When using a CDN
|
||||
/// $base-url: 'https://cdn.example.com/assets/';
|
||||
$base-url: '/assets/';
|
178
themes/hugo-liftoff/assets/scss/base/_base.scss
Normal file
178
themes/hugo-liftoff/assets/scss/base/_base.scss
Normal file
@ -0,0 +1,178 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// This file contains very basic styles.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Set up a decent box model on the root element
|
||||
*/
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make all elements from the DOM inherit from the parent box-sizing
|
||||
* Since `*` has a specificity of 0, it does not override the `html` value
|
||||
* making all elements inheriting from the root box-sizing value
|
||||
* See: https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/
|
||||
*/
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
/* Flex properties on body/main/footer are for floating footer
|
||||
to bottom of page if main content doesn't fill viewport vertically */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
footer {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
|
||||
@include on-event {
|
||||
color: var(--color-text);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
@include font-size('xl');
|
||||
}
|
||||
|
||||
h2 {
|
||||
@include font-size('lg');
|
||||
}
|
||||
|
||||
h3 {
|
||||
@include font-size('md');
|
||||
}
|
||||
|
||||
h4 {
|
||||
@include font-size('base');
|
||||
}
|
||||
|
||||
h5 {
|
||||
@include font-size('sm');
|
||||
}
|
||||
|
||||
h6 {
|
||||
@include font-size('sm');
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
td, th {
|
||||
border: 1px solid var(--color-contrast-medium-low);
|
||||
padding: 10px 20px;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.4rem;
|
||||
}
|
||||
|
||||
th {
|
||||
border: 1px solid var(--color-contrast-medium);
|
||||
background-color: var(--color-contrast-medium-low);
|
||||
color: var(--color-contrast-high);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr:nth-child(even) td {
|
||||
background-color: var(--color-contrast-lower);
|
||||
color: var(--color-contrast-high);
|
||||
}
|
||||
|
||||
tr:nth-child(odd) td {
|
||||
background-color: var(--color-contrast-low);
|
||||
color: var(--color-contrast-high);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
background: var(--color-contrast-lower);
|
||||
border-left: 10px solid var(--color-contrast-low);
|
||||
margin: 1.5em 10px;
|
||||
padding: 0.7em 10px;
|
||||
quotes: "\201C" "\201D";
|
||||
|
||||
p {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
&::before {
|
||||
color: var(--color-contrast-low);
|
||||
content: open-quote;
|
||||
font-size: 4em;
|
||||
line-height: 0.1em;
|
||||
margin-right: 0.25em;
|
||||
vertical-align: -0.4em;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 1rem;
|
||||
line-height: 1.6rem;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
code {
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
pre:not([style]) {
|
||||
// If no highlighting is applied already
|
||||
background-color:#272822;
|
||||
color:#f8f8f2;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
p > code, li > code {
|
||||
background-color: var(--color-contrast-lower);
|
||||
font-size: 1rem;
|
||||
color: var(--color-inline-code);
|
||||
padding: 2px 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
row-gap: 10px;
|
||||
|
||||
input, textarea {
|
||||
border: 1px solid var(--color-contrast-medium-low);
|
||||
padding: 10px 12px;
|
||||
font-size: 1rem;
|
||||
background-color: var(--color-contrast-lower);
|
||||
color: var(--color-contrast-high);
|
||||
|
||||
@include respond-to('small') {
|
||||
padding: 15px 12px;
|
||||
min-width: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
111
themes/hugo-liftoff/assets/scss/base/_fonts.scss
Normal file
111
themes/hugo-liftoff/assets/scss/base/_fonts.scss
Normal file
@ -0,0 +1,111 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// This file contains all @font-face declarations, if any.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Thin'),
|
||||
url('/fonts/Roboto/Roboto-Thin.ttf') format('truetype');
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Thin Italic'),
|
||||
url('/fonts/Roboto/Roboto-ThinItalic.ttf') format('truetype');
|
||||
font-weight: 100;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Light'),
|
||||
url('/fonts/Roboto/Roboto-Light.ttf') format('truetype');
|
||||
font-weight: 300;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Light Italic'),
|
||||
url('/fonts/Roboto/Roboto-LightItalic.ttf') format('truetype');
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Regular'),
|
||||
url('/fonts/Roboto/Roboto-Regular.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Italic'),
|
||||
url('/fonts/Roboto/Roboto-Italic.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Medium'),
|
||||
url('/fonts/Roboto/Roboto-Medium.ttf') format('truetype');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Italic'),
|
||||
url('/fonts/Roboto/Roboto-MediumItalic.ttf') format('truetype');
|
||||
font-weight: 500;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Bold'),
|
||||
url('/fonts/Roboto/Roboto-Bold.ttf') format('truetype');
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Bold Italic'),
|
||||
url('/fonts/Roboto/Roboto-BoldItalic.ttf') format('truetype');
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Black'),
|
||||
url('/fonts/Roboto/Roboto-Black.ttf') format('truetype');
|
||||
font-weight: 900;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
src: local('Roboto Black Italic'),
|
||||
url('/fonts/Roboto/Roboto-BlackItalic.ttf') format('truetype');
|
||||
font-weight: 900;
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
}
|
69
themes/hugo-liftoff/assets/scss/base/_helpers.scss
Normal file
69
themes/hugo-liftoff/assets/scss/base/_helpers.scss
Normal file
@ -0,0 +1,69 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// This file contains CSS helper classes.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Clear inner floats
|
||||
*/
|
||||
.clearfix::after {
|
||||
clear: both;
|
||||
content: '';
|
||||
display: table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main content containers
|
||||
* 1. Make the container full-width with a maximum width
|
||||
* 2. Center it in the viewport
|
||||
* 3. Leave some space on the edges, especially valuable on small screens
|
||||
*/
|
||||
.container {
|
||||
max-width: $max-width; /* 1 */
|
||||
margin-left: auto; /* 2 */
|
||||
margin-right: auto; /* 2 */
|
||||
padding-left: 16px; /* 3 */
|
||||
padding-right: 16px; /* 3 */
|
||||
width: 100%; /* 1 */
|
||||
|
||||
@include respond-to('small') {
|
||||
padding-left: 20px; /* 3 */
|
||||
padding-right: 20px; /* 3 */
|
||||
}
|
||||
|
||||
&--sm {
|
||||
@extend .container;
|
||||
max-width: 768px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide text while making it readable for screen readers
|
||||
* 1. Needed in WebKit-based browsers because of an implementation bug;
|
||||
* See: https://code.google.com/p/chromium/issues/detail?id=457146
|
||||
*/
|
||||
.hide-text {
|
||||
overflow: hidden;
|
||||
padding: 0; /* 1 */
|
||||
text-indent: 101%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide element while making it readable for screen readers
|
||||
* Shamelessly borrowed from HTML5Boilerplate:
|
||||
* https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css#L119-L133
|
||||
*/
|
||||
.visually-hidden {
|
||||
border: 0;
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 50px 0;
|
||||
}
|
31
themes/hugo-liftoff/assets/scss/base/_typography.scss
Normal file
31
themes/hugo-liftoff/assets/scss/base/_typography.scss
Normal file
@ -0,0 +1,31 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// This file contains typography styles.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Basic typography style for copy text
|
||||
*/
|
||||
body {
|
||||
color: var(--color-text);
|
||||
font: normal 125% / 1.4 $text-font-stack;
|
||||
}
|
||||
|
||||
.summary-text {
|
||||
font-weight: 300;
|
||||
@include font-size('base');
|
||||
color: var(--color-contrast-medium-high);
|
||||
}
|
||||
|
||||
.meta-text {
|
||||
color: var(--color-contrast-medium);
|
||||
@include font-size('sm');
|
||||
font-weight: 400;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px 15px;
|
||||
}
|
||||
|
||||
.fallback-text {
|
||||
color: var(--color-contrast-medium);
|
||||
@include font-size('md');
|
||||
}
|
40
themes/hugo-liftoff/assets/scss/components/_buttons.scss
Normal file
40
themes/hugo-liftoff/assets/scss/components/_buttons.scss
Normal file
@ -0,0 +1,40 @@
|
||||
.btn-group {
|
||||
display: flex;
|
||||
column-gap: 15px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
%btn {
|
||||
border: 1px solid var(--color-primary);
|
||||
padding: 0.4rem 0.7rem;
|
||||
display: inline-block;
|
||||
@include font-size('base');
|
||||
|
||||
@include respond-to('small') {
|
||||
padding: 0.5rem 0.8rem;
|
||||
}
|
||||
|
||||
@include on-event() {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
@extend %btn;
|
||||
background-color: var(--color-primary);
|
||||
color: var(--color-contrast-lower);
|
||||
|
||||
&:hover {
|
||||
background: transparent;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@extend %btn;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-primary);
|
||||
color: var(--color-contrast-lower);
|
||||
}
|
||||
}
|
44
themes/hugo-liftoff/assets/scss/components/_clipboard.scss
Normal file
44
themes/hugo-liftoff/assets/scss/components/_clipboard.scss
Normal file
@ -0,0 +1,44 @@
|
||||
// Adapted from the following tutorials:
|
||||
// https://logfetch.com/hugo-add-copy-to-clipboard-button/
|
||||
|
||||
.clipboard-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
padding: 2px 7px 5px 7px;
|
||||
margin: 5px;
|
||||
color: #767676;
|
||||
border-color: #767676;
|
||||
background-color: #ededed;
|
||||
border: 1px solid;
|
||||
border-radius: 6px;
|
||||
z-index: 1;
|
||||
opacity: 0;
|
||||
transition: 0.1s;
|
||||
}
|
||||
|
||||
.clipboard-button > svg {
|
||||
fill: #767676;
|
||||
}
|
||||
|
||||
.clipboard-button:hover {
|
||||
cursor: pointer;
|
||||
border-color: #696969;
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.clipboard-button:hover > svg {
|
||||
fill: #696969;
|
||||
}
|
||||
|
||||
.clipboard-button:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.highlight:hover > .clipboard-button {
|
||||
opacity: 1;
|
||||
transition: 0.2s;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
.code-language {
|
||||
position: relative;
|
||||
padding: 6px 15px;
|
||||
border-radius: 5px;
|
||||
background-color: #272822;
|
||||
color: #7f7f7f;
|
||||
z-index: 1000;
|
||||
top: 25px;
|
||||
@include font-size('base');
|
||||
}
|
||||
|
||||
.highlight > pre {
|
||||
padding: 20px;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
.draft::after {
|
||||
content: 'Draft';
|
||||
color: rgb(201, 8, 8);
|
||||
border: 1px solid rgb(201, 8, 8);
|
||||
border-radius: 5px;
|
||||
@include font-size('sm');
|
||||
padding: 2px 5px;
|
||||
font-weight: 300;
|
||||
}
|
19
themes/hugo-liftoff/assets/scss/components/_markdown.scss
Normal file
19
themes/hugo-liftoff/assets/scss/components/_markdown.scss
Normal file
@ -0,0 +1,19 @@
|
||||
.markdown {
|
||||
@include font-size('base');
|
||||
|
||||
p > img, figure > img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
@include font-size('sm');
|
||||
color: var(--color-contrast-medium);
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
16
themes/hugo-liftoff/assets/scss/components/_newsletter.scss
Normal file
16
themes/hugo-liftoff/assets/scss/components/_newsletter.scss
Normal file
@ -0,0 +1,16 @@
|
||||
.newsletter-header {
|
||||
color: var(--color-contrast-high);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.newsletter-desc {
|
||||
color: var(--color-contrast-medium-high);
|
||||
@include font-size('base');
|
||||
}
|
||||
|
||||
#newsletter-form {
|
||||
|
||||
input {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
26
themes/hugo-liftoff/assets/scss/components/_page-header.scss
Normal file
26
themes/hugo-liftoff/assets/scss/components/_page-header.scss
Normal file
@ -0,0 +1,26 @@
|
||||
.page-header {
|
||||
background-color: var(--color-contrast-lower);
|
||||
padding: 30px;
|
||||
margin: 0 0 50px 0;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.page-header--c {
|
||||
@extend .page-header;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.page-header-title {
|
||||
margin: 0;
|
||||
color: var(--color-contrast-high);
|
||||
font-weight: 500;
|
||||
@include font-size('lg');
|
||||
}
|
||||
|
||||
.page-header-desc {
|
||||
margin: 0;
|
||||
margin-top: 15px;
|
||||
color: var(--color-contrast-medium);
|
||||
font-weight: 400;
|
||||
@include font-size('base');
|
||||
}
|
37
themes/hugo-liftoff/assets/scss/components/_pagination.scss
Normal file
37
themes/hugo-liftoff/assets/scss/components/_pagination.scss
Normal file
@ -0,0 +1,37 @@
|
||||
.pagination {
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
gap: 15px 10px;
|
||||
margin-top: 50px;
|
||||
padding: 0;
|
||||
@include font-size('base');
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: var(--color-contrast-medium-high);
|
||||
padding: 8px 15px;
|
||||
background-color: var(--color-contrast-lower);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
@include on-event {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.page-item {
|
||||
|
||||
&.disabled > a {
|
||||
color: var(--color-contrast-low);
|
||||
cursor:unset;
|
||||
}
|
||||
|
||||
&.active > a {
|
||||
background-color: var(--color-primary);
|
||||
color: var(--color-contrast-lower);
|
||||
}
|
||||
}
|
29
themes/hugo-liftoff/assets/scss/components/_socials.scss
Normal file
29
themes/hugo-liftoff/assets/scss/components/_socials.scss
Normal file
@ -0,0 +1,29 @@
|
||||
.social-links {
|
||||
width: 100%;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.social-icons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 15px 40px;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
&--share {
|
||||
@extend .social-icons;
|
||||
justify-content: flex-start;
|
||||
gap: 10px 15px;
|
||||
li {
|
||||
border: 1px solid var(--color-contrast-medium-low);
|
||||
border-radius: 100px;
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
105
themes/hugo-liftoff/assets/scss/components/_switch-theme.scss
Normal file
105
themes/hugo-liftoff/assets/scss/components/_switch-theme.scss
Normal file
@ -0,0 +1,105 @@
|
||||
:root {
|
||||
/* style */
|
||||
--switch-width: 48px;
|
||||
--switch-height: 24px;
|
||||
--switch-padding: 3px;
|
||||
/* animation */
|
||||
--switch-animation-duration: 0.2s;
|
||||
}
|
||||
|
||||
.switch {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
width: 48px;
|
||||
width: var(--switch-width);
|
||||
height: 24px;
|
||||
height: var(--switch-height);
|
||||
border-radius: 50em;
|
||||
padding: 3px 0;
|
||||
padding: var(--switch-padding) 0;
|
||||
|
||||
position: absolute;
|
||||
top: 65px;
|
||||
right: 20px;
|
||||
|
||||
@include respond-to('m-large') {
|
||||
position:relative;
|
||||
top: unset;
|
||||
right: unset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.switch-input, .switch-label {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.switch-input {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
width: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.switch-input:checked + .switch-label {
|
||||
background-color: hsl(228, 74%, 61%);
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.switch-input:checked + .switch-label + .switch-marker {
|
||||
left: calc(100% - 29px);
|
||||
left: calc(100% - var(--switch-height) + var(--switch-padding));
|
||||
}
|
||||
|
||||
.switch-input:focus + .switch-label,
|
||||
.switch-input:active + .switch-label {
|
||||
--color-shadow: hsla(228, 74%, 61%, 0.2);
|
||||
box-shadow: undefined;
|
||||
box-shadow: 0 0 0 3px var(--color-shadow);
|
||||
}
|
||||
|
||||
.switch-input:focus + .switch-label,
|
||||
.switch-input:active + .switch-label {
|
||||
box-shadow: 0 0 0 3px hsla(228, 74%, 61%, 0.2);
|
||||
box-shadow: 0 0 0 3px var(--color-shadow);
|
||||
}
|
||||
|
||||
.switch-label {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: transparent;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
background-color: hsl(240, 1%, 83%);
|
||||
background-color: var(--color-contrast-low);
|
||||
border-radius: inherit;
|
||||
z-index: 1;
|
||||
transition: background 0.2s;
|
||||
transition: background var(--switch-animation-duration);
|
||||
}
|
||||
|
||||
.switch-marker {
|
||||
position: relative;
|
||||
background-color: hsl(0, 0%, 100%);
|
||||
background-color: var(--color-contrast-high);
|
||||
width: 20px;
|
||||
width: calc(var(--switch-height) - var(--switch-padding)*2);
|
||||
height: 20px;
|
||||
height: calc(var(--switch-height) - var(--switch-padding)*2);
|
||||
border-radius: 50%;
|
||||
z-index: 2;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.25);
|
||||
left: 3px;
|
||||
left: var(--switch-padding);
|
||||
transition: left 0.2s;
|
||||
transition: left var(--switch-animation-duration);
|
||||
will-change: left;
|
||||
}
|
52
themes/hugo-liftoff/assets/scss/components/_toc.scss
Normal file
52
themes/hugo-liftoff/assets/scss/components/_toc.scss
Normal file
@ -0,0 +1,52 @@
|
||||
.toc {
|
||||
|
||||
@include respond-to('x-large') {
|
||||
position: sticky;
|
||||
top: 2rem;
|
||||
align-self: start;
|
||||
order: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
height: 90vh;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
.toc-header, .toc-drop-icon {
|
||||
@include font-size('sm');
|
||||
font-weight: 500;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.toc-contents {
|
||||
display: none;
|
||||
@include font-size('sm');
|
||||
|
||||
&--active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@include respond-to('x-large') {
|
||||
display: block;
|
||||
|
||||
&--active {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#js-toc-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
column-gap: 10px;
|
||||
padding: 10px 20px;
|
||||
background-color: var(--color-contrast-lower);
|
||||
border-radius: 20px;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
18
themes/hugo-liftoff/assets/scss/layout/_footer.scss
Normal file
18
themes/hugo-liftoff/assets/scss/layout/_footer.scss
Normal file
@ -0,0 +1,18 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// This file contains all styles related to the footer of the site/application.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
.footer {
|
||||
background-color: var(--color-contrast-lower);
|
||||
}
|
||||
|
||||
.footer-socials {
|
||||
max-width: 300px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.footer-copyright {
|
||||
text-align: center;
|
||||
@include font-size('base');
|
||||
color: var(--color-contrast-medium-high);
|
||||
}
|
128
themes/hugo-liftoff/assets/scss/layout/_header.scss
Normal file
128
themes/hugo-liftoff/assets/scss/layout/_header.scss
Normal file
@ -0,0 +1,128 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// This file contains all styles related to the header of the site.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
.main-nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 15px 0;
|
||||
row-gap: 20px;
|
||||
|
||||
.nav-toggle {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@include respond-to('m-large') {
|
||||
flex-direction: row; /* Horizontal nav on desktop */
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
|
||||
.nav-toggle {
|
||||
display: none; /* Hide nav toggle on desktop */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
@include font-size('md');
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
width: fit-content;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-link {
|
||||
color: var(--color-text);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-contrast-lower);
|
||||
}
|
||||
}
|
||||
|
||||
.menu {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-bottom: 1px solid var(--color-contrast-low);
|
||||
border-top: 1px solid var(--color-contrast-low);
|
||||
|
||||
&--active {
|
||||
display: flex; /* Display mobile menu on click */
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
display: block;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.menu-item--align {
|
||||
@extend .menu-item;
|
||||
align-self: center;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.menu-link {
|
||||
display: flex;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
padding: 1.4rem 1rem;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-primary);
|
||||
color: var(--color-contrast-lower);
|
||||
}
|
||||
}
|
||||
|
||||
.drop-icon {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
@include respond-to('m-large') {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: none;
|
||||
|
||||
.menu-item:hover {
|
||||
.sub-menu {
|
||||
background-color: var(--color-contrast-lower);
|
||||
padding-left: 0;
|
||||
display: block;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sub-menu {
|
||||
display: none;
|
||||
|
||||
&--active {
|
||||
display: block;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.menu-link {
|
||||
font-weight: initial;
|
||||
}
|
||||
|
||||
@include respond-to('m-large') {
|
||||
display: none;
|
||||
position: absolute;
|
||||
box-shadow: rgba(9, 30, 66, 0.25) 0px 4px 8px -2px, rgba(9, 30, 66, 0.08) 0px 0px 0px 1px;
|
||||
|
||||
&--active {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
47
themes/hugo-liftoff/assets/scss/main.scss
Normal file
47
themes/hugo-liftoff/assets/scss/main.scss
Normal file
@ -0,0 +1,47 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
// 1. Configuration and helpers
|
||||
@import
|
||||
'abstracts/variables',
|
||||
'abstracts/functions',
|
||||
'abstracts/mixins';
|
||||
|
||||
// 2. Vendors
|
||||
@import
|
||||
'vendors/normalize';
|
||||
|
||||
// 3. Base stuff
|
||||
@import
|
||||
'base/base',
|
||||
'base/fonts',
|
||||
'base/typography',
|
||||
'base/helpers';
|
||||
|
||||
// 4. Layout-related sections
|
||||
@import
|
||||
'layout/header',
|
||||
'layout/footer';
|
||||
|
||||
// 5. Components
|
||||
@import
|
||||
'components/switch-theme',
|
||||
'components/socials',
|
||||
'components/buttons',
|
||||
'components/newsletter',
|
||||
'components/pagination',
|
||||
'components/draft-label',
|
||||
'components/clipboard',
|
||||
'components/code-highlight',
|
||||
'components/markdown',
|
||||
'components/toc',
|
||||
'components/page-header';
|
||||
|
||||
// 6. Page-specific styles
|
||||
@import
|
||||
'pages/home',
|
||||
'pages/contact',
|
||||
'pages/single',
|
||||
'pages/terms',
|
||||
'pages/errors',
|
||||
'pages/post-list',
|
||||
'pages/project-list';
|
10
themes/hugo-liftoff/assets/scss/pages/_contact.scss
Normal file
10
themes/hugo-liftoff/assets/scss/pages/_contact.scss
Normal file
@ -0,0 +1,10 @@
|
||||
#contact-form {
|
||||
flex-direction: column;
|
||||
row-gap: 15px;
|
||||
max-width: 500px;
|
||||
margin-top: 30px;
|
||||
|
||||
button {
|
||||
align-self: flex-start;
|
||||
}
|
||||
}
|
11
themes/hugo-liftoff/assets/scss/pages/_errors.scss
Normal file
11
themes/hugo-liftoff/assets/scss/pages/_errors.scss
Normal file
@ -0,0 +1,11 @@
|
||||
.error-404 {
|
||||
margin-top: 50px;
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
104
themes/hugo-liftoff/assets/scss/pages/_home.scss
Normal file
104
themes/hugo-liftoff/assets/scss/pages/_home.scss
Normal file
@ -0,0 +1,104 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// This file contains styles that are specific to the home page.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
.hero {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 3rem 5vw;
|
||||
|
||||
@include respond-to('medium') {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
@include respond-to('m-large') {
|
||||
padding: 80px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.hero-info {
|
||||
|
||||
@include respond-to('medium') {
|
||||
flex: 0 1 65%;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-weight: 900;
|
||||
margin-top: 0;
|
||||
@include font-size('xl');
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
color: var(--color-contrast-medium-high);
|
||||
@include font-size('base');
|
||||
}
|
||||
}
|
||||
|
||||
.hero-owner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
row-gap: 20px;
|
||||
|
||||
@include respond-to('medium') {
|
||||
flex: 0 1 35%;
|
||||
}
|
||||
|
||||
.hero-avatar {
|
||||
max-width: 300px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 20px;
|
||||
|
||||
@include respond-to('medium') {
|
||||
max-width: 100%;
|
||||
width: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.home-section-title {
|
||||
|
||||
&::after {
|
||||
background-color: var(--color-contrast-medium);
|
||||
content: "";
|
||||
display: block;
|
||||
height: 2px;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.home-section-posts-title {
|
||||
@extend .home-section-title;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.home-title-dropdown {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 30px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
#select-posts {
|
||||
@include font-size('sm');
|
||||
padding: 0.4rem;
|
||||
border: 1px solid var(--color-contrast-medium-low);
|
||||
border-radius: 5px;
|
||||
color: var(--color-contrast-high);
|
||||
background-color: var(--color-contrast-lower);
|
||||
}
|
||||
|
||||
.see-more {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.see-more-projects {
|
||||
color: var(--color-contrast-medium);
|
||||
font-weight: 300;
|
||||
font-size: var(--font-size-base);
|
||||
}
|
47
themes/hugo-liftoff/assets/scss/pages/_post-list.scss
Normal file
47
themes/hugo-liftoff/assets/scss/pages/_post-list.scss
Normal file
@ -0,0 +1,47 @@
|
||||
.post-entry {
|
||||
margin: 20px 0;
|
||||
max-width: 750px;
|
||||
}
|
||||
|
||||
.post-entry-divider {
|
||||
background-color: var(--color-contrast-low);
|
||||
content: "";
|
||||
display: block;
|
||||
height: 1px;
|
||||
position: relative;
|
||||
max-width: 750px;
|
||||
}
|
||||
|
||||
.post-list-title {
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
@include font-size('md');
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: var(--color-contrast-high);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.post-list-summary {
|
||||
@extend .summary-text;
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
|
||||
.post-list-meta {
|
||||
@extend .meta-text;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.post-list-dates {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.post-list-categories {
|
||||
display: inline-flex;
|
||||
column-gap: 10px;
|
||||
}
|
81
themes/hugo-liftoff/assets/scss/pages/_project-list.scss
Normal file
81
themes/hugo-liftoff/assets/scss/pages/_project-list.scss
Normal file
@ -0,0 +1,81 @@
|
||||
.project-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
gap: 2rem 1rem;
|
||||
|
||||
& > * {
|
||||
flex: 1 1 350px;
|
||||
}
|
||||
}
|
||||
|
||||
.project-entry {
|
||||
border: 1px solid var(--color-contrast-low);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 20px -10px var(--color-contrast-low), 0 0 20px -10px var(--color-contrast-low);
|
||||
max-width: 750px;
|
||||
}
|
||||
|
||||
.project-entry-img {
|
||||
position: relative;
|
||||
border-radius: 10px 10px 0 0;
|
||||
min-height: 1rem;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 20vh;
|
||||
object-fit: cover;
|
||||
border-radius: 10px 10px 0 0;
|
||||
border-bottom: 1px solid var(--color-contrast-low);
|
||||
// Image overlay
|
||||
z-index: -1;
|
||||
position: relative;
|
||||
filter: grayscale(50%);
|
||||
}
|
||||
}
|
||||
|
||||
.project-entry-type {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 0.2rem 0.4rem;
|
||||
background-color: var(--color-bg);
|
||||
border-left: 1px solid var(--color-contrast-low);
|
||||
border-bottom: 1px solid var(--color-contrast-low);
|
||||
border-top-right-radius: 10px;
|
||||
|
||||
a {
|
||||
@include font-size('sm');
|
||||
}
|
||||
}
|
||||
|
||||
.project-entry-info {
|
||||
padding: 1.2rem;
|
||||
|
||||
@include respond-to('small') {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.project-entry-title {
|
||||
margin: 0;
|
||||
font-weight: 400;
|
||||
|
||||
a {
|
||||
color: var(--color-contrast-high);
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.project-list-summary {
|
||||
@extend .summary-text;
|
||||
}
|
||||
|
||||
.project-list-meta {
|
||||
@extend .meta-text;
|
||||
margin-top: 10px;
|
||||
}
|
80
themes/hugo-liftoff/assets/scss/pages/_single.scss
Normal file
80
themes/hugo-liftoff/assets/scss/pages/_single.scss
Normal file
@ -0,0 +1,80 @@
|
||||
.single-feature-img {
|
||||
display: flex;
|
||||
|
||||
img {
|
||||
margin: 30px 0;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
filter: grayscale(50%);
|
||||
}
|
||||
}
|
||||
|
||||
.single-terms {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
justify-content: flex-start;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.single-container {
|
||||
@extend .container;
|
||||
max-width: 900px;
|
||||
}
|
||||
|
||||
.single-container-post {
|
||||
@extend .container;
|
||||
max-width: 900px;
|
||||
|
||||
@include respond-to('x-large') {
|
||||
max-width: $max-width;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 15em;
|
||||
gap: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.single-post-contents {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.series {
|
||||
@include font-size('base');
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.series-this-post {
|
||||
color: var(--color-primary);
|
||||
border: 1px solid var(--color-primary);
|
||||
border-radius: 5px;
|
||||
padding: 0.3rem;
|
||||
@include font-size('sm');
|
||||
font-weight: 500;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.single-next-previous {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
|
||||
& > * {
|
||||
background-color: transparent;
|
||||
border: 1px solid var(--color-contrast-medium-low);
|
||||
border-radius: 12px;
|
||||
padding: 10px;
|
||||
@include font-size('base');
|
||||
max-width: 300px;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
border: 1px solid var(--color-contrast-high);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.related-posts {
|
||||
@include font-size('base');
|
||||
}
|
28
themes/hugo-liftoff/assets/scss/pages/_terms.scss
Normal file
28
themes/hugo-liftoff/assets/scss/pages/_terms.scss
Normal file
@ -0,0 +1,28 @@
|
||||
.terms {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 15px 15px;
|
||||
}
|
||||
|
||||
.term {
|
||||
border: 1px solid var(--color-primary);
|
||||
border-radius: 20px;
|
||||
@include font-size('sm');
|
||||
padding: 0.4rem 0.6rem;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
border: 1px solid var(--color-contrast-high);
|
||||
color: var(--color-contrast-high);
|
||||
}
|
||||
|
||||
@include respond-to('small') {
|
||||
padding: 0.5rem 0.7rem;
|
||||
}
|
||||
}
|
||||
|
||||
.term-count {
|
||||
color: var(--color-contrast-high);
|
||||
margin-left: 2px;
|
||||
}
|
349
themes/hugo-liftoff/assets/scss/vendors/_normalize.scss
vendored
Normal file
349
themes/hugo-liftoff/assets/scss/vendors/_normalize.scss
vendored
Normal file
@ -0,0 +1,349 @@
|
||||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
|
||||
|
||||
/* Document
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Correct the line height in all browsers.
|
||||
* 2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
*/
|
||||
|
||||
html {
|
||||
line-height: 1.15; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/* Sections
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the margin in all browsers.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the `main` element consistently in IE.
|
||||
*/
|
||||
|
||||
main {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the font size and margin on `h1` elements within `section` and
|
||||
* `article` contexts in Chrome, Firefox, and Safari.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
/* Grouping content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in Firefox.
|
||||
* 2. Show the overflow in Edge and IE.
|
||||
*/
|
||||
|
||||
hr {
|
||||
box-sizing: content-box; /* 1 */
|
||||
height: 0; /* 1 */
|
||||
overflow: visible; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/* Text-level semantics
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the gray background on active links in IE 10.
|
||||
*/
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Remove the bottom border in Chrome 57-
|
||||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: none; /* 1 */
|
||||
text-decoration: underline; /* 2 */
|
||||
text-decoration: underline dotted; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||
* all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/* Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the border on images inside links in IE 10.
|
||||
*/
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
/* Forms
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Change the font styles in all browsers.
|
||||
* 2. Remove the margin in Firefox and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 1 */
|
||||
line-height: 1.15; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the overflow in IE.
|
||||
* 1. Show the overflow in Edge.
|
||||
*/
|
||||
|
||||
button,
|
||||
input { /* 1 */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||
* 1. Remove the inheritance of text transform in Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select { /* 1 */
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the inability to style clickable types in iOS and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner border and padding in Firefox.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the focus styles unset by the previous rule.
|
||||
*/
|
||||
|
||||
button:-moz-focusring,
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the padding in Firefox.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
padding: 0.35em 0.75em 0.625em;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the text wrapping in Edge and IE.
|
||||
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||
* 3. Remove the padding so developers are not caught out when they zero out
|
||||
* `fieldset` elements in all browsers.
|
||||
*/
|
||||
|
||||
legend {
|
||||
box-sizing: border-box; /* 1 */
|
||||
color: inherit; /* 2 */
|
||||
display: table; /* 1 */
|
||||
max-width: 100%; /* 1 */
|
||||
padding: 0; /* 3 */
|
||||
white-space: normal; /* 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||
*/
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the default vertical scrollbar in IE 10+.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in IE 10.
|
||||
* 2. Remove the padding in IE 10.
|
||||
*/
|
||||
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||
*/
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the odd appearance in Chrome and Safari.
|
||||
* 2. Correct the outline style in Safari.
|
||||
*/
|
||||
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
outline-offset: -2px; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner padding in Chrome and Safari on macOS.
|
||||
*/
|
||||
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||
* 2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
}
|
||||
|
||||
/* Interactive
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Add the correct display in Edge, IE 10+, and Firefox.
|
||||
*/
|
||||
|
||||
details {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the correct display in all browsers.
|
||||
*/
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/* Misc
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 10+.
|
||||
*/
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 10.
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
4
themes/hugo-liftoff/config.toml
Normal file
4
themes/hugo-liftoff/config.toml
Normal file
@ -0,0 +1,4 @@
|
||||
[module]
|
||||
[module.hugoVersion]
|
||||
extended = true
|
||||
min = "0.115.2"
|
3
themes/hugo-liftoff/go.mod
Normal file
3
themes/hugo-liftoff/go.mod
Normal file
@ -0,0 +1,3 @@
|
||||
module github.com/wjh18/hugo-liftoff/v3
|
||||
|
||||
go 1.20
|
BIN
themes/hugo-liftoff/images/screenshot.png
Normal file
BIN
themes/hugo-liftoff/images/screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 232 KiB |
BIN
themes/hugo-liftoff/images/tn.png
Normal file
BIN
themes/hugo-liftoff/images/tn.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 123 KiB |
9
themes/hugo-liftoff/layouts/404.html
Normal file
9
themes/hugo-liftoff/layouts/404.html
Normal file
@ -0,0 +1,9 @@
|
||||
{{ define "main" }}
|
||||
<article class="error-404 container">
|
||||
<div>
|
||||
<h1>Page Not Found!</h1>
|
||||
<p>The page you requested could not be found.</p>
|
||||
<a class="btn-secondary" href="{{ "/" | relURL }}">‹ Return Home</a>
|
||||
</div>
|
||||
</article>
|
||||
{{ end }}
|
@ -0,0 +1,6 @@
|
||||
{{ $lang := .Attributes.lang | default .Type }}
|
||||
{{ if transform.CanHighlight $lang }}
|
||||
<span class="code-language">{{ $lang }}</span>{{ highlight .Inner $lang }}
|
||||
{{ else }}
|
||||
<pre><code>{{ .Inner }}</code></pre>
|
||||
{{ end }}
|
@ -0,0 +1,10 @@
|
||||
<h{{ .Level }} id="{{ .Anchor | safeURL }}">
|
||||
{{- .Text | safeHTML -}}
|
||||
<a href="#{{ .Anchor | safeURL }}">
|
||||
<svg role="img" aria-labelledby="{{ .Anchor | safeURL }}-IconTitle" fill="var(--color-primary)" height="22" viewBox="0 0 24 24" width="22" xmlns="http://www.w3.org/2000/svg">
|
||||
<title id="{{ .Anchor | safeURL }}-IconTitle">Link to this heading</title>
|
||||
<path d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</h{{ .Level }}>
|
@ -0,0 +1,50 @@
|
||||
<!-- get image URL from Markdown tag -->
|
||||
{{- $src := (.Destination | safeURL) -}}
|
||||
<!-- split # fragment (used for CSS classes) and keep clean URL -->
|
||||
{{- $fragments := (split $src "#") -}}
|
||||
{{- $src = index ($fragments) 0 -}}
|
||||
<!-- resize if wider than .Scratch.Get "imgwidth" -->
|
||||
{{- $imgwidth := .Page.Scratch.Get "imgwidth" | default 800 -}}
|
||||
<!-- get actual filename -->
|
||||
{{- $src = path.Base $src -}}
|
||||
<!-- check if it exists as a page resource -->
|
||||
{{- with (.Page.Resources.ByType "image").GetMatch (printf "**/%s" $src) -}}
|
||||
{{ $resized := . }}
|
||||
{{ if (gt .Width $imgwidth) }}
|
||||
{{ if hugo.IsExtended }}
|
||||
{{- $resized = .Resize (print $imgwidth "x webp") -}}
|
||||
{{ else }}
|
||||
{{- $resized = .Resize (print $imgwidth "x") -}}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<!-- if a JPEG (certain to be opaque) generate a low resolution placeholder to use as background -->
|
||||
{{ $placeholder := "" }}
|
||||
{{- if or (eq .MediaType.SubType "jpg") (eq .MediaType.SubType "jpeg") }}
|
||||
{{ $placeholder = .Resize "48x q20 jpg Gaussian" }}
|
||||
{{ end -}}
|
||||
<!-- if a GIF file, then revert to original to avoid resizing animations; WebP animations don't work -->
|
||||
{{- if (eq .MediaType.SubType "gif") }}
|
||||
{{ $resized = . }}
|
||||
{{ end -}}
|
||||
<img src="{{ $resized.RelPermalink }}"
|
||||
width="{{ $resized.Width }}"
|
||||
height="{{ $resized.Height }}"
|
||||
{{ with $placeholder }}style="
|
||||
background-image: url('data:image/jpg;base64,{{ .Content | base64Encode }}');
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;"{{ end }}
|
||||
alt="{{ $.Text }}" {{ with $.Title }} title="{{ . }}" {{ end }}
|
||||
{{ with index ($fragments ) 1 }}class="{{ . }}" {{ else }}class="single-post-image" {{ end }}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
>
|
||||
<!-- or otherwise simply load the URL -->
|
||||
{{- else -}}
|
||||
<img src="{{ .Destination | safeURL }}"
|
||||
alt="{{ .Text }}" {{ with .Title }} title="{{ . }}" {{ end }}
|
||||
{{ with index ($fragments ) 1 }}class="{{ . }}" {{ else }}class="single-post-image" {{ end }}
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
>
|
||||
{{- end -}}
|
@ -0,0 +1 @@
|
||||
<a href="{{ .Destination | safeURL }}"{{ with .Title }} title="{{ . }}"{{ end }}{{ if strings.HasPrefix .Destination "http" }} target="_blank" rel="noopener"{{ end }}>{{ .Text | safeHTML }}</a>
|
17
themes/hugo-liftoff/layouts/_default/baseof.html
Normal file
17
themes/hugo-liftoff/layouts/_default/baseof.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ .Site.LanguageCode | default "en-US" }}">
|
||||
{{- partial "head/head.html" . -}}
|
||||
<body>
|
||||
{{ if and (not .Site.IsServer) (.Site.Params.gtm_id) }}
|
||||
<!-- Google Tag Manager (noscript) -->
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{ .Site.Params.gtm_id }}" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||
<!-- End Google Tag Manager (noscript) -->
|
||||
{{ end }}
|
||||
{{- partial "header/header.html" . -}}
|
||||
<main class="section">
|
||||
{{- block "main" . }}{{- end }}
|
||||
</main>
|
||||
{{- partial "footer/footer.html" . -}}
|
||||
{{- partial "footer/scripts.html" . -}}
|
||||
</body>
|
||||
</html>
|
31
themes/hugo-liftoff/layouts/_default/list.html
Normal file
31
themes/hugo-liftoff/layouts/_default/list.html
Normal file
@ -0,0 +1,31 @@
|
||||
{{ define "main" -}}
|
||||
<div class="container">
|
||||
<section class="page-header">
|
||||
<h1 class="page-header-title">{{ .Title }}</h1>
|
||||
<p class="page-header-desc">
|
||||
{{- with .Params.Summary -}}
|
||||
{{- . -}}
|
||||
{{- else -}}
|
||||
{{- with .Description -}}
|
||||
{{- . -}}
|
||||
{{- else -}}
|
||||
{{- if eq .Data.Plural "series" -}}
|
||||
Posts in the {{ .Title }} series.
|
||||
{{- else -}}
|
||||
Posts about {{ .Title }}.
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
{{ range (.Paginate .RegularPagesRecursive).Pages }}
|
||||
{{ partial "posts/post-entry.html" . }}
|
||||
<div class="post-entry-divider"></div>
|
||||
{{ else }}
|
||||
{{ partial "general/fallback-text.html" . }}
|
||||
{{ end }}
|
||||
{{ template "_internal/pagination.html" . }}
|
||||
</section>
|
||||
</div>
|
||||
{{ end }}
|
27
themes/hugo-liftoff/layouts/_default/rss.xml
Normal file
27
themes/hugo-liftoff/layouts/_default/rss.xml
Normal file
@ -0,0 +1,27 @@
|
||||
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ with .Site.Title }}{{ . }}{{ else }}{{ .Title }}{{ end }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}</description>
|
||||
<generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
|
||||
<language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
|
||||
<managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
|
||||
<webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
|
||||
<copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
|
||||
<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
|
||||
{{- with .OutputFormats.Get "RSS" -}}
|
||||
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
|
||||
{{- end -}}
|
||||
{{ range where (where .Site.Pages ".Section" "posts") "Kind" "page" }}
|
||||
<item>
|
||||
<title>{{ .Title }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
|
||||
{{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
|
||||
<guid>{{ .Permalink }}</guid>
|
||||
<description>{{ with .Params.Summary }}{{ . | html }}{{ else }}{{ .Description | html }}{{ end }}</description>
|
||||
</item>
|
||||
{{ end }}
|
||||
</channel>
|
||||
</rss>
|
12
themes/hugo-liftoff/layouts/_default/single.html
Normal file
12
themes/hugo-liftoff/layouts/_default/single.html
Normal file
@ -0,0 +1,12 @@
|
||||
{{ define "main" }}
|
||||
<div class="container">
|
||||
<section class="page-header--c">
|
||||
<h1 class="page-header-title">{{ .Title }}</h1>
|
||||
</section>
|
||||
</div>
|
||||
<section class="generic-single">
|
||||
<div class="single-container markdown">
|
||||
{{ .Content }}
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
24
themes/hugo-liftoff/layouts/_default/sitemap.xml
Normal file
24
themes/hugo-liftoff/layouts/_default/sitemap.xml
Normal file
@ -0,0 +1,24 @@
|
||||
{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||
{{ range .Data.Pages }}
|
||||
{{- if .Permalink -}}
|
||||
<url>
|
||||
<loc>{{ .Permalink }}</loc>{{ if not .Lastmod.IsZero }}
|
||||
<lastmod>{{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ end }}{{ with .Sitemap.ChangeFreq }}
|
||||
<changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
|
||||
<priority>{{ .Sitemap.Priority }}</priority>{{ end }}{{ if .IsTranslated }}{{ range .Translations }}
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="{{ .Language.Lang }}"
|
||||
href="{{ .Permalink }}"
|
||||
/>{{ end }}
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="{{ .Language.Lang }}"
|
||||
href="{{ .Permalink }}"
|
||||
/>{{ end }}
|
||||
</url>
|
||||
{{- end -}}
|
||||
{{ end }}
|
||||
</urlset>
|
16
themes/hugo-liftoff/layouts/_default/terms.html
Normal file
16
themes/hugo-liftoff/layouts/_default/terms.html
Normal file
@ -0,0 +1,16 @@
|
||||
{{ define "main" }}
|
||||
<div class="container">
|
||||
<section class="page-header--c">
|
||||
<h1 class="page-header-title">{{ .Title }}</h1>
|
||||
</section>
|
||||
<div class="terms">
|
||||
{{ with .Data.Terms.ByCount }}
|
||||
{{ range . }}
|
||||
<a class="term" href="{{ .Page.Permalink }}">{{ .Page.Title }} <sup class="term-count">{{ .Count }}</sup></a>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
{{ partial "general/fallback-text.html" . }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
15
themes/hugo-liftoff/layouts/about/single.html
Normal file
15
themes/hugo-liftoff/layouts/about/single.html
Normal file
@ -0,0 +1,15 @@
|
||||
{{ define "main" }}
|
||||
<div class="container">
|
||||
<section class="page-header--c">
|
||||
<h1 class="page-header-title">{{ .Title }}</h1>
|
||||
</section>
|
||||
</div>
|
||||
<div class="about">
|
||||
{{ if eq .Site.Params.about_page_socials true }}
|
||||
<div class="container--sm">{{ partial "general/social-links.html" . }}</div>
|
||||
{{ end }}
|
||||
<article class="single-container markdown">
|
||||
{{ .Content }}
|
||||
</article>
|
||||
</div>
|
||||
{{ end }}
|
16
themes/hugo-liftoff/layouts/contact/single.html
Normal file
16
themes/hugo-liftoff/layouts/contact/single.html
Normal file
@ -0,0 +1,16 @@
|
||||
{{ define "main" }}
|
||||
<div class="container">
|
||||
<section class="page-header--c">
|
||||
<h1 class="page-header-title">{{ .Title }}</h1>
|
||||
</section>
|
||||
</div>
|
||||
<div class="contact">
|
||||
<div class="single-container markdown">{{ .Content }}</div>
|
||||
<form id="contact-form" class="single-container" name="contact" method="POST" {{ with .Site.Params.netlify_forms }}data-netlify="{{ . }}"{{ end }}>
|
||||
<input type="text" class="contact-form--input" name="name" placeholder="Your name..." title="Enter your name" required>
|
||||
<input type="email" class="contact-form--input" name="email" placeholder="Your best email..." title="Enter your best email" required>
|
||||
<textarea class="contact-form--textarea" name="message" placeholder="Your message..." title="Enter your message" required></textarea>
|
||||
<button type="submit" id="contact-form--submit" class="btn-primary">Send</button>
|
||||
</form>
|
||||
</div>
|
||||
{{ end }}
|
5
themes/hugo-liftoff/layouts/index.headers
Normal file
5
themes/hugo-liftoff/layouts/index.headers
Normal file
@ -0,0 +1,5 @@
|
||||
/*
|
||||
X-Frame-Options: DENY
|
||||
X-XSS-Protection: 1; mode=block
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: origin-when-cross-origin
|
52
themes/hugo-liftoff/layouts/index.html
Normal file
52
themes/hugo-liftoff/layouts/index.html
Normal file
@ -0,0 +1,52 @@
|
||||
{{ define "main" }}
|
||||
<div class="container">
|
||||
<section class="section hero">
|
||||
<div class="hero-info">
|
||||
<h1 class="hero-title">{{ .Title }}</h1>
|
||||
{{ with .Params.subtitle }}
|
||||
<p class="hero-subtitle">{{. | markdownify}}</p>
|
||||
{{ end }}
|
||||
<div class="btn-group">
|
||||
{{ $p_cta := "" }}
|
||||
{{ with .Params.primary_cta_page }}
|
||||
{{ $p_cta = . }}
|
||||
{{ end }}
|
||||
{{ $s_cta := "" }}
|
||||
{{ with .Params.secondary_cta_page }}
|
||||
{{ $s_cta = . }}
|
||||
{{ end }}
|
||||
<a class="btn-primary"
|
||||
href="{{ with $p_cta }}{{ . | relURL }}{{ else }}{{ "about" | relURL }}{{ end }}">
|
||||
{{ if $p_cta }}{{ with .Site.GetPage $p_cta }}{{ .LinkTitle }}{{ end }}{{ else }}About{{ end }}
|
||||
</a>
|
||||
<a class="btn-secondary"
|
||||
href="{{ with $s_cta }}{{ . | relURL }}{{ else }}{{ "projects" | relURL }}{{ end }}">
|
||||
{{ if $s_cta }}{{ with .Site.GetPage $s_cta }}{{ .LinkTitle }}{{ end }}{{ else }}Projects{{ end }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-owner">
|
||||
{{ $avatar := .Site.Params.avatar }}
|
||||
{{ $default_image := "images/default.png" }}
|
||||
{{ $image := "" }}
|
||||
{{ with $avatar }}
|
||||
{{ $image = resources.Get $avatar }}
|
||||
{{ else }}
|
||||
{{ $image = resources.Get $default_image }}
|
||||
{{ end }}
|
||||
{{ if eq .Site.Params.grayscale_avatar true }}
|
||||
{{ $image = $image | images.Filter (images.Grayscale) }}
|
||||
{{ end }}
|
||||
<img class="hero-avatar"
|
||||
src="{{ $image.RelPermalink }}"
|
||||
width="{{- $image.Width -}}" height="{{- $image.Height -}}"
|
||||
alt="Headshot or avatar belonging to the website owner"/>
|
||||
{{ if eq .Site.Params.home_hero_socials true }}
|
||||
{{ partial "general/social-links.html" . }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</section>
|
||||
{{/* Shortcodes from page content */}}
|
||||
{{ .Content }}
|
||||
</div>
|
||||
{{ end }}
|
7
themes/hugo-liftoff/layouts/index.redirects
Normal file
7
themes/hugo-liftoff/layouts/index.redirects
Normal file
@ -0,0 +1,7 @@
|
||||
# redirects for Netlify - https://www.netlify.com/docs/redirects/
|
||||
{{- range $p := .Site.Pages -}}
|
||||
{{- range .Aliases }}
|
||||
{{ . }} {{ $p.RelPermalink -}}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
# Add custom redirects here
|
18
themes/hugo-liftoff/layouts/partials/footer/footer.html
Normal file
18
themes/hugo-liftoff/layouts/partials/footer/footer.html
Normal file
@ -0,0 +1,18 @@
|
||||
<footer>
|
||||
{{ if (or (.Param "newsletter") (and (.Site.Params.global_newsletter) (not (isset .Params "newsletter")))) }}
|
||||
{{ partial "footer/newsletter.html" . }}
|
||||
{{ end }}
|
||||
<div class="section footer">
|
||||
<p class="footer-copyright">© {{ now.Format "2006" }} ·
|
||||
<a href="{{ .Site.BaseURL }}">{{ .Site.Title }}</a>
|
||||
{{ with .Site.Params.footer_text | markdownify }}
|
||||
<span>· {{ . }}</span>
|
||||
{{ end }}
|
||||
</p>
|
||||
{{ if eq .Site.Params.footer_socials true }}
|
||||
<div class="footer-socials">
|
||||
{{ partial "general/social-links.html" . }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</footer>
|
29
themes/hugo-liftoff/layouts/partials/footer/newsletter.html
Normal file
29
themes/hugo-liftoff/layouts/partials/footer/newsletter.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!-- Reusable template for a newsletter opt-in -->
|
||||
<section class="section">
|
||||
<div class="container--sm">
|
||||
<h2 class="newsletter-header">
|
||||
{{- with .Site.Params.newsletter_header -}}
|
||||
{{- . -}}
|
||||
{{- else -}}
|
||||
Subscribe for Post Updates
|
||||
{{- end -}}
|
||||
</h2>
|
||||
<p class="newsletter-desc">
|
||||
{{- with .Site.Params.newsletter_description -}}
|
||||
{{- . -}}
|
||||
{{- else -}}
|
||||
Enter your email below to get notified of new posts.
|
||||
{{- end -}}
|
||||
</p>
|
||||
<form id="newsletter-form" name="newsletter" method="POST" {{ with .Site.Params.netlify_forms }}data-netlify="{{ . }}"{{ end }}>
|
||||
<input type="email" id="newsletter-form--input" name="email" placeholder="Your best email..." title="Enter your best email" required>
|
||||
<button type="submit" id="newsletter-form--submit" class="btn-primary">
|
||||
{{- with .Site.Params.newsletter_submit -}}
|
||||
{{- . -}}
|
||||
{{- else -}}
|
||||
Subscribe
|
||||
{{- end -}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
34
themes/hugo-liftoff/layouts/partials/footer/scripts.html
Normal file
34
themes/hugo-liftoff/layouts/partials/footer/scripts.html
Normal file
@ -0,0 +1,34 @@
|
||||
{{ $opts := "" }}
|
||||
{{ if hugo.IsProduction }}
|
||||
{{ $opts = dict "targetPath" "main.js" }}
|
||||
{{ else }}
|
||||
{{ $opts = dict "targetPath" "main.js" "sourceMap" "inline" }}
|
||||
{{ end }}
|
||||
{{ $script := resources.Get "js/app.js" | js.Build $opts }}
|
||||
|
||||
{{ $custom := "" }}
|
||||
{{ with .Site.Params.custom_js }}
|
||||
{{ $custom = resources.Get . }}
|
||||
{{/* Only concatenate in production to allow source maps */}}
|
||||
{{ if hugo.IsProduction }}
|
||||
{{ $bundle := slice $script $custom | resources.Concat "main.js" }}
|
||||
{{ $script = $bundle }}
|
||||
{{ else }}
|
||||
<script src="{{ $custom.Permalink }}"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ $final := "" }}
|
||||
{{ if hugo.IsProduction }}
|
||||
{{/* Only rebuild concatenated files in production (in dev there is no concat) */}}
|
||||
{{/* Only minify in production to allow source maps */}}
|
||||
{{ $final = $script | js.Build "main.js" | minify }}
|
||||
{{ else }}
|
||||
{{ $final = $script }}
|
||||
{{ end }}
|
||||
<script src="{{ $final.Permalink }}"></script>
|
||||
|
||||
<!-- Add Google Analytics v4 tag if not using GTM -->
|
||||
{{ if and (not .Site.IsServer) (not .Site.Params.gtm_id) }}
|
||||
{{ template "_internal/google_analytics.html" . }}
|
||||
{{ end }}
|
@ -0,0 +1,7 @@
|
||||
<p class="fallback-text">
|
||||
{{- with .Site.Params.fallback_text -}}
|
||||
{{- . -}}
|
||||
{{- else -}}
|
||||
No content available yet. Coming soon.
|
||||
{{- end -}}
|
||||
</p>
|
@ -0,0 +1,19 @@
|
||||
{{ $images := $.Resources.ByType "image" -}}
|
||||
{{ $custom_file := .Params.feature_image }}
|
||||
{{ $custom_image := $images.GetMatch $custom_file }}
|
||||
{{ $feature_image := $images.GetMatch "*feature*" -}}
|
||||
{{ $img_src := "" }}
|
||||
{{ with $custom_image }}
|
||||
{{ $img_src = .RelPermalink }}
|
||||
{{ else }}
|
||||
{{ with $feature_image }}
|
||||
{{ $img_src = .RelPermalink }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if $img_src }}
|
||||
<img class="feature-image"
|
||||
srcset="{{ $img_src }} 480w, {{ $img_src }} 800w"
|
||||
sizes="(max-width: 600px) 480px, 800px"
|
||||
src="{{ $img_src }}"
|
||||
{{ with $.Params.feature_image_alt }}alt="{{ . }}"{{ else }}alt="Feature image"{{ end }}>
|
||||
{{ end }}
|
@ -0,0 +1,3 @@
|
||||
{{ if and (eq .Params.draft true) (eq .Site.Params.label_drafts true) (.Site.IsServer) }}
|
||||
<span class="draft"></span>
|
||||
{{ end }}
|
@ -0,0 +1,58 @@
|
||||
<!-- Social Share Button HTML -->
|
||||
<div class="social-links">
|
||||
<ul class="social-icons">
|
||||
<!-- Twitter -->
|
||||
{{ with .Site.Params.social.links.twitter }}
|
||||
<li>
|
||||
<a href="https://twitter.com/{{ . }}" target="_blank" rel="noopener" aria-label="Visit Twitter profile" class="social-btn twitter">
|
||||
{{ partial "svg/twitter.svg" }}
|
||||
</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
<!-- Mastodon -->
|
||||
{{ if .Site.Params.social.links.mastodon_user }}
|
||||
<li>
|
||||
<a href="https://{{ with .Site.Params.social.links.mastodon_server }}{{ . }}{{ else }}mastodon.social{{ end }}/@{{ with .Site.Params.social.links.mastodon_user }}{{ . }}{{ end }}" target="_blank" rel="me noopener" aria-label="Visit Mastodon profile" class="social-btn mastodon">
|
||||
{{ partial "svg/mastodon.svg" }}
|
||||
</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
<!-- Github -->
|
||||
{{ with .Site.Params.social.links.github }}
|
||||
<li>
|
||||
<a href="https://github.com/{{ . }}" target="_blank" rel="noopener" aria-label="Visit Github profile" class="social-btn github">
|
||||
{{ partial "svg/github.svg" }}
|
||||
</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
<!-- Stack Overflow -->
|
||||
{{ with .Site.Params.social.links.stack_overflow }}
|
||||
<li>
|
||||
<a href="https://stackoverflow.com/users/{{ . }}" target="_blank" rel="noopener" aria-label="Visit Stack Overflow profile" class="social-btn stack-overflow">
|
||||
{{ partial "svg/stack-overflow.svg" }}
|
||||
</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
<!-- LinkedIn -->
|
||||
{{ with .Site.Params.social.links.linkedin }}
|
||||
<li>
|
||||
<a href="https://www.linkedin.com/in/{{ . }}" target="_blank" rel="noopener" aria-label="Visit LinkedIn profile" class="social-btn linkedin">
|
||||
{{ partial "svg/linkedin.svg" }}
|
||||
</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
<!-- Email -->
|
||||
{{ with .Site.Params.social.links.email }}
|
||||
<li>
|
||||
<a href="mailto:?to={{ . }}" target="_blank" class="social-btn email">
|
||||
{{ partial "svg/email.svg" }}
|
||||
</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
7
themes/hugo-liftoff/layouts/partials/head/favicons.html
Normal file
7
themes/hugo-liftoff/layouts/partials/head/favicons.html
Normal file
@ -0,0 +1,7 @@
|
||||
<!-- Favicon -->
|
||||
{{ if eq .Site.Params.favicon true }}
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
{{ end }}
|
11
themes/hugo-liftoff/layouts/partials/head/gtm.html
Normal file
11
themes/hugo-liftoff/layouts/partials/head/gtm.html
Normal file
@ -0,0 +1,11 @@
|
||||
{{ if not .Site.IsServer }}
|
||||
{{ with .Site.Params.gtm_id }}
|
||||
<!-- Google Tag Manager -->
|
||||
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','{{ . }}');</script>
|
||||
<!-- End Google Tag Manager -->
|
||||
{{ end }}
|
||||
{{ end }}
|
10
themes/hugo-liftoff/layouts/partials/head/head.html
Normal file
10
themes/hugo-liftoff/layouts/partials/head/head.html
Normal file
@ -0,0 +1,10 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
{{ partial "head/resource-hints.html" . }}
|
||||
{{ partial "head/styles.html" . }}
|
||||
{{ partial "head/seo/seo.html" . }}
|
||||
{{ partial "head/favicons.html" . }}
|
||||
{{ partial "head/scripts.html" . }}
|
||||
</head>
|
@ -0,0 +1 @@
|
||||
<!-- Preload fonts, etc. -->
|
4
themes/hugo-liftoff/layouts/partials/head/scripts.html
Normal file
4
themes/hugo-liftoff/layouts/partials/head/scripts.html
Normal file
@ -0,0 +1,4 @@
|
||||
<!-- Google Tag Manager -->
|
||||
{{ if .Site.Params.gtm_id }}
|
||||
{{ partial "head/gtm.html" . }}
|
||||
{{ end }}
|
72
themes/hugo-liftoff/layouts/partials/head/seo/opengraph.html
Normal file
72
themes/hugo-liftoff/layouts/partials/head/seo/opengraph.html
Normal file
@ -0,0 +1,72 @@
|
||||
<meta property="og:locale" content="{{ .Site.Params.ogLocale }}">
|
||||
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}">
|
||||
<meta property="og:title" content="{{- with .Params.seo_title -}}{{- . -}}{{ else }}{{- .Title -}}{{ end }}{{ if (or (and (ne .Type "posts") (ne .Type "projects") (not .IsHome)) (and (not .IsPage) (not .IsHome))) }} | {{ .Site.Title -}}{{ end -}}">
|
||||
<meta property="og:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}">
|
||||
{{ if $.Scratch.Get "paginator" -}}
|
||||
{{ $paginator := .Paginate (where .Site.RegularPages.ByDate.Reverse "Section" "posts" ) -}}
|
||||
<meta property="og:url" content="{{ .Paginator.URL | absURL }}">
|
||||
{{ else -}}
|
||||
<meta property="og:url" content="{{ .Permalink }}">
|
||||
{{ end -}}
|
||||
{{ with .Site.Params.title -}}
|
||||
<meta property="og:site_name" content="{{ . }}">
|
||||
{{ end -}}
|
||||
|
||||
{{ $iso8601 := "2006-01-02T15:04:05-07:00" -}}
|
||||
{{ if .IsPage -}}
|
||||
{{ if not .PublishDate.IsZero -}}
|
||||
<meta property="article:published_time" {{ .PublishDate.Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>
|
||||
{{ else if not .Date.IsZero -}}
|
||||
<meta property="article:published_time" {{ .Date.Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>
|
||||
{{ end -}}
|
||||
{{ if not .Lastmod.IsZero -}}
|
||||
<meta property="article:modified_time" {{ .Lastmod.Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>
|
||||
{{ end -}}
|
||||
{{ else -}}
|
||||
{{ if not .Date.IsZero -}}
|
||||
<meta property="og:updated_time" {{ .Lastmod.Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{ $images := $.Resources.ByType "image" -}}
|
||||
{{ $feature := $images.GetMatch "*feature*" -}}
|
||||
{{ $feature_param := $.Params.feature_image }}
|
||||
{{ $feature_frontmatter := $images.GetMatch $feature_param }}
|
||||
{{ if $feature_frontmatter -}}
|
||||
<meta property="og:image" content="{{ $feature_frontmatter.Permalink }}"/>
|
||||
{{ with $.Params.feature_image_alt }}
|
||||
<meta property="og:image:alt" content="{{ . }}" />
|
||||
{{ end }}
|
||||
{{ else if $feature -}}
|
||||
<meta property="og:image" content="{{ $feature.Permalink }}"/>
|
||||
{{ with $.Params.feature_image_alt }}
|
||||
<meta property="og:image:alt" content="{{ . }}" />
|
||||
{{ end }}
|
||||
{{ else if $.Params.images }}
|
||||
<meta name="og:image" content="{{ index $.Params.images 0 | absURL }}"/>
|
||||
{{ else if $.Site.Params.images }}
|
||||
<meta name="og:image" content="{{ index $.Site.Params.images 0 | absURL }}"/>
|
||||
{{ end }}
|
||||
|
||||
{{ with .Params.audio -}}
|
||||
<meta property="og:audio" content="{{ . | absURL }}">
|
||||
{{ end -}}
|
||||
|
||||
{{ with .Params.videos -}}
|
||||
{{ range . -}}
|
||||
<meta property="og:video" content="{{ . | absURL }}">
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{- /* If it is part of a series, link to related articles */}}
|
||||
{{- $permalink := .Permalink }}
|
||||
{{- $siteSeries := .Site.Taxonomies.series }}
|
||||
{{/* Only add property if taxonomy is enabled */}}
|
||||
{{ if $siteSeries }}
|
||||
{{ with .Params.series }}{{- range $name := . }}
|
||||
{{- $series := index $siteSeries ($name | urlize) }}
|
||||
{{- range $page := first 6 $series.Pages }}
|
||||
{{- if ne $page.Permalink $permalink }}<meta property="og:see_also" content="{{ $page.Permalink }}" />{{ end }}
|
||||
{{- end }}
|
||||
{{ end }}{{ end }}
|
||||
{{ end }}
|
65
themes/hugo-liftoff/layouts/partials/head/seo/seo.html
Normal file
65
themes/hugo-liftoff/layouts/partials/head/seo/seo.html
Normal file
@ -0,0 +1,65 @@
|
||||
<!-- Robots meta -->
|
||||
{{ if eq .Kind "404" -}}
|
||||
<meta name="robots" content="noindex, follow">
|
||||
{{ else -}}
|
||||
{{ with .Params.robots -}}
|
||||
<meta name="robots" content="{{ . }}">
|
||||
{{ else -}}
|
||||
<meta name="robots" content="index, follow">
|
||||
<meta name="googlebot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1">
|
||||
<meta name="bingbot" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1">
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
|
||||
<!-- SEO title from config or front matter -->
|
||||
<!-- Site title gets added EXCEPT on single post and project pages -->
|
||||
<title>
|
||||
{{- $paginator := .Paginate .RegularPagesRecursive }}
|
||||
{{- with .Params.seo_title -}}
|
||||
{{- . -}}
|
||||
{{- else -}}
|
||||
{{- .Title -}}
|
||||
{{- end -}}
|
||||
{{- with $paginator -}}
|
||||
{{ if and (gt $paginator.TotalPages 1) (gt $paginator.PageNumber 1) }}
|
||||
| Page {{ $paginator.PageNumber }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{ if (or (and (ne .Type "posts") (ne .Type "projects") (not .IsHome)) (and (not .IsPage) (not .IsHome))) }} | {{ .Site.Title -}}{{ end -}}
|
||||
</title>
|
||||
|
||||
<!-- Author from config -->
|
||||
{{ with .Params.author -}}
|
||||
<meta name="author" content="{{ . }}">
|
||||
{{ else -}}
|
||||
<meta name="author" content="{{ .Site.Params.author }}">
|
||||
{{ end -}}
|
||||
|
||||
<!-- Description from config or front matter -->
|
||||
{{ with .Description -}}
|
||||
<meta name="description" content="{{ . }}">
|
||||
{{ else -}}
|
||||
<meta name="description" content="{{ .Site.Params.description }}">
|
||||
{{ end -}}
|
||||
|
||||
{{ if $.Scratch.Get "paginator" }}
|
||||
<link rel="canonical" href="{{ .Paginator.URL | absURL }}">
|
||||
{{ if .Paginator.HasPrev -}}
|
||||
<link rel="prev" href="{{ .Paginator.Prev.URL | absURL }}">
|
||||
{{ end -}}
|
||||
{{ if .Paginator.HasNext -}}
|
||||
<link rel="next" href="{{ .Paginator.Next.URL | absURL }}">
|
||||
{{ end -}}
|
||||
{{ else -}}
|
||||
<link rel="canonical" href="{{ .Permalink }}">
|
||||
{{ end -}}
|
||||
|
||||
{{ partial "head/seo/opengraph.html" . }}
|
||||
{{ partial "head/seo/twitter-cards.html" . }}
|
||||
|
||||
<!-- Add rss+xml functionality -->
|
||||
{{- with .OutputFormats.Get "rss" -}}
|
||||
{{ printf `<link rel="%s" type="%s" href="%s" title="%s">` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
|
||||
{{- end -}}
|
||||
|
||||
{{ partial "head/seo/structured-data.html" . }}
|
@ -0,0 +1,159 @@
|
||||
{{ $baseURL := "/" | absURL -}}
|
||||
|
||||
{{ $dot := . -}}
|
||||
{{ $dot.Scratch.Set "path" "" -}}
|
||||
{{ $dot.Scratch.Set "breadcrumb" slice -}}
|
||||
|
||||
{{ $url := replace .Permalink ( printf "%s" .Site.BaseURL) "" -}}
|
||||
{{ $.Scratch.Add "path" .Site.BaseURL -}}
|
||||
|
||||
{{ $.Scratch.Add "breadcrumb" (slice (dict "url" .Site.BaseURL "name" "home" "position" 1 )) -}}
|
||||
{{ range $index, $element := split $url "/" -}}
|
||||
{{ $dot.Scratch.Add "path" $element -}}
|
||||
{{ $.Scratch.Add "path" "/" -}}
|
||||
{{ if ne $element "" -}}
|
||||
{{ $.Scratch.Add "breadcrumb" (slice (dict "url" ($.Scratch.Get "path") "name" . "position" (add $index 2))) -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{ $images := $.Resources.ByType "image" -}}
|
||||
{{ $feature := $images.GetMatch "*feature*" -}}
|
||||
{{ $feature_param := $.Params.feature_image }}
|
||||
{{ $feature_frontmatter := $images.GetMatch $feature_param }}
|
||||
{{ if $feature_frontmatter -}}
|
||||
{{ $.Scratch.Set "primaryImage" $feature_frontmatter.Permalink }}
|
||||
{{ with $.Params.feature_image_alt }}
|
||||
{{ $.Scratch.Set "primaryImageAlt" . }}
|
||||
{{ end }}
|
||||
{{ else if $feature -}}
|
||||
{{ $.Scratch.Set "primaryImage" $feature.Permalink }}
|
||||
{{ with $.Params.feature_image_alt }}
|
||||
{{ $.Scratch.Set "primaryImageAlt" . }}
|
||||
{{ end }}
|
||||
{{ else if $.Params.images }}
|
||||
{{ $.Scratch.Set "primaryImage" ( index $.Params.images 0 | absURL ) }}
|
||||
{{ else if $.Site.Params.images }}
|
||||
{{ $.Scratch.Set "primaryImage" ( index $.Site.Params.images 0 | absURL ) }}
|
||||
{{ end }}
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "Person",
|
||||
"@id": {{ print $baseURL "#/schema/person/1" }},
|
||||
"name": {{ .Site.Params.schemaName }},
|
||||
"url": {{ print $baseURL }},
|
||||
"image": {
|
||||
"@type": "ImageObject",
|
||||
"@id": {{ print $baseURL "#/schema/image/1"}},
|
||||
"url": {{ print $baseURL .Site.Params.schemaImage }},
|
||||
"width": {{- .Site.Params.schemaImageWidth -}},
|
||||
"height": {{- .Site.Params.schemaImageHeight -}},
|
||||
"caption": {{ .Site.Params.schemaName }}
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "WebSite",
|
||||
"@id": {{ print $baseURL "#/schema/website/1" }},
|
||||
"url": {{ print $baseURL }},
|
||||
"name": {{ .Site.Title }},
|
||||
"description": {{ .Site.Params.description }},
|
||||
"publisher": {
|
||||
"@id": {{ print $baseURL "#/schema/person/1" }}
|
||||
}
|
||||
},
|
||||
{
|
||||
{{ if and (ne .Kind "taxonomy") (ne .Kind "term") -}}
|
||||
"@type": "WebPage",
|
||||
{{ else -}}
|
||||
"@type": "CollectionPage",
|
||||
{{ end -}}
|
||||
"@id": {{ .Permalink }},
|
||||
"url": {{ .Permalink }},
|
||||
"name": {{ with .Title }}{{ . }}{{ else }}{{ .Site.Title }}{{ end }},
|
||||
"description": {{ with .Description }}{{ . }}{{ else }}{{ .Site.Params.description }}{{ end }},
|
||||
"isPartOf": {
|
||||
"@id": {{ print $baseURL "#/schema/website/1" }}
|
||||
},
|
||||
"about": {
|
||||
"@id": {{ print $baseURL "#/schema/person/1" }}
|
||||
},
|
||||
"datePublished": {{ with .PublishDate}}{{ .Format "2006-01-02T15:04:05-07:00" }}{{ else }}{{ .Date.Format "2006-01-02T15:04:05-07:00" }}{{ end }},
|
||||
"dateModified": {{ .Lastmod.Format "2006-01-02T15:04:05-07:00" }},
|
||||
"breadcrumb": {
|
||||
"@id": {{ print .Permalink "#/schema/breadcrumb/1" }}
|
||||
},
|
||||
"primaryImageOfPage": {
|
||||
"@id": {{ print .Permalink "#/schema/image/2" }}
|
||||
},
|
||||
"inLanguage": {{ .Site.Params.schemaLocale }},
|
||||
"potentialAction": [{
|
||||
"@type": "ReadAction", "target": [{{ .Permalink }}]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"@type": "BreadcrumbList",
|
||||
"@id": {{ print .Permalink "#/schema/breadcrumb/1" }},
|
||||
"name": "Breadcrumbs",
|
||||
"itemListElement": [{{ $list := $.Scratch.Get "breadcrumb" }}{{ $len := (len $list) }}{{ range $index, $element := $list }}{{ if ne .position 1 }},{{ end }}{
|
||||
"@type": "ListItem",
|
||||
"position": {{ .position }},
|
||||
"item": {
|
||||
{{ if ne (add $index 1) $len -}}
|
||||
"@type": "WebPage",
|
||||
"@id": {{ .url }},
|
||||
"url": {{ .url }},
|
||||
"name": {{ .name | humanize | title }}
|
||||
{{ else -}}
|
||||
"@id": {{ .url }}
|
||||
{{ end -}}
|
||||
}
|
||||
}{{ end }}]
|
||||
},
|
||||
{{ if and (eq .Kind "page") (eq .Section "posts") -}}
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "Article",
|
||||
"@id": {{ print $baseURL "#/schema/article/1" }},
|
||||
"headline": {{ .Title }},
|
||||
"description": {{ .Description }},
|
||||
"isPartOf": {
|
||||
"@id": {{ .Permalink }}
|
||||
},
|
||||
"mainEntityOfPage": {
|
||||
"@id": {{ .Permalink }}
|
||||
},
|
||||
"datePublished": {{ .PublishDate.Format "2006-01-02T15:04:05-07:00" }},
|
||||
"dateModified": {{ .Lastmod.Format "2006-01-02T15:04:05-07:00" }},
|
||||
"author": {
|
||||
"@id": {{ print $baseURL "#/schema/person/1" }}
|
||||
},
|
||||
"publisher": {
|
||||
"@id": {{ print $baseURL "#/schema/person/1" }}
|
||||
},
|
||||
"image": {
|
||||
"@id": {{ print .Permalink "#/schema/image/2" }}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{{- end -}}
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
{
|
||||
"@type": "ImageObject",
|
||||
"@id": {{ print .Permalink "#/schema/image/2" }},
|
||||
"url": {{ $.Scratch.Get "primaryImage" }},
|
||||
"contentUrl": {{ $.Scratch.Get "primaryImage" }},
|
||||
"caption": {{ with $.Scratch.Get "primaryImageAlt" }}{{ . }}{{ else }}{{ .Title }}{{ end }}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
@ -0,0 +1,33 @@
|
||||
{{ with .Site.Params.twitterSite }}
|
||||
<meta name="twitter:site" content="{{ . }}">
|
||||
{{ end }}
|
||||
{{ with .Site.Params.twitterCreator }}
|
||||
<meta name="twitter:creator" content="{{ . }}">
|
||||
{{ end }}
|
||||
<meta name="twitter:title" content="{{- with .Params.seo_title -}}{{- . -}}{{ else }}{{- .Title -}}{{ end }}{{ if (or (and (ne .Type "posts") (ne .Type "projects") (not .IsHome)) (and (not .IsPage) (not .IsHome))) }} | {{ .Site.Title -}}{{ end -}}">
|
||||
<meta name="twitter:description" content="{{ with .Description }}{{ . }}{{ else }}{{if .IsPage}}{{ .Summary }}{{ else }}{{ with .Site.Params.description }}{{ . }}{{ end }}{{ end }}{{ end }}">
|
||||
{{ $images := $.Resources.ByType "image" -}}
|
||||
{{ $feature := $images.GetMatch "*feature*" -}}
|
||||
{{ $feature_param := $.Params.feature_image }}
|
||||
{{ $feature_frontmatter := $images.GetMatch $feature_param }}
|
||||
{{ if $feature_frontmatter -}}
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta property="twitter:image" content="{{ $feature_frontmatter.Permalink }}"/>
|
||||
{{ with $.Params.feature_image_alt }}
|
||||
<meta name="twitter:image:alt" content="{{ . }}">
|
||||
{{ end }}
|
||||
{{ else if $feature -}}
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta property="twitter:image" content="{{ $feature.Permalink }}"/>
|
||||
{{ with $.Params.feature_image_alt }}
|
||||
<meta name="twitter:image:alt" content="{{ . }}">
|
||||
{{ end }}
|
||||
{{ else if $.Params.images }}
|
||||
<meta name="twitter:card" content="summary_large_image"/>
|
||||
<meta name="twitter:image" content="{{ index $.Params.images 0 | absURL }}"/>
|
||||
{{ else if $.Site.Params.images }}
|
||||
<meta name="twitter:card" content="summary_large_image"/>
|
||||
<meta name="twitter:image" content="{{ index $.Site.Params.images 0 | absURL }}"/>
|
||||
{{ else }}
|
||||
<meta name="twitter:card" content="summary">
|
||||
{{ end }}
|
34
themes/hugo-liftoff/layouts/partials/head/styles.html
Normal file
34
themes/hugo-liftoff/layouts/partials/head/styles.html
Normal file
@ -0,0 +1,34 @@
|
||||
{{ $sass := resources.Get "scss/main.scss" }}
|
||||
{{ $options := (dict "enableSourceMap" (not hugo.IsProduction)) }}
|
||||
{{ $style := $sass | resources.ToCSS $options }}
|
||||
|
||||
{{ $custom := "" }}
|
||||
{{ $custom_no_bundle := false }}
|
||||
{{ with .Site.Params.custom_css }}
|
||||
{{ $custom = resources.Get . }}
|
||||
{{/* Only concatenate in production to allow source maps */}}
|
||||
{{ if hugo.IsProduction }}
|
||||
{{ $bundle := slice $style $custom | resources.Concat "main.css" }}
|
||||
{{ $style = $bundle }}
|
||||
{{ else }}
|
||||
{{ $custom_no_bundle = true }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ $final := "" }}
|
||||
{{/* Only enable PostCSS in production to allow source maps */}}
|
||||
{{ if and (eq $.Site.Params.enable_postcss true) (hugo.IsProduction) }}
|
||||
{{ $final = $style | postCSS (dict "config" "postcss.config.js") }}
|
||||
{{ else }}
|
||||
{{ $final = $style }}
|
||||
{{ end }}
|
||||
|
||||
{{ if hugo.IsProduction }}
|
||||
{{/* Only minify in production to allow source maps */}}
|
||||
{{ $final = $final | minify }}
|
||||
{{ end }}
|
||||
<link rel="stylesheet" href="{{ $final.Permalink }}" />
|
||||
{{/* Custom goes last to preserve cascade in development */}}
|
||||
{{ if $custom_no_bundle }}
|
||||
<link rel="stylesheet" href="{{ $custom.Permalink }}" />
|
||||
{{ end }}
|
36
themes/hugo-liftoff/layouts/partials/header/header.html
Normal file
36
themes/hugo-liftoff/layouts/partials/header/header.html
Normal file
@ -0,0 +1,36 @@
|
||||
<header class="container">
|
||||
<nav class="main-nav" id="js-navbar">
|
||||
<a class="logo" href="{{ .Site.BaseURL }}">{{ .Site.Title }}</a>
|
||||
<ul class="menu" id="js-menu">
|
||||
{{ $currentPage := . }}
|
||||
{{ range .Site.Menus.main }}
|
||||
{{ if .HasChildren }}
|
||||
<li class="menu-item">
|
||||
<span class="menu-link">{{ .Name }}<span class="drop-icon">▾</span></span>
|
||||
<ul class="sub-menu">
|
||||
{{ range .Children }}
|
||||
<li class="menu-item">
|
||||
<a href="{{ .URL }}" class="menu-link">{{ .Name }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</li>
|
||||
{{ else }}
|
||||
<li class="menu-item">
|
||||
<a href="{{ .URL }}" class="menu-link">{{ .Name }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<li class="menu-item--align">
|
||||
<div class="switch">
|
||||
<input class="switch-input" type="checkbox" id="themeSwitch">
|
||||
<label aria-hidden="true" class="switch-label" for="themeSwitch">On</label>
|
||||
<div aria-hidden="true" class="switch-marker"></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="nav-toggle" id="js-navbar-toggle">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="Outline" viewBox="0 0 24 24" width="30" height="30" fill="var(--color-contrast-high)"><rect y="11" width="24" height="2" rx="1"/><rect y="4" width="24" height="2" rx="1"/><rect y="18" width="24" height="2" rx="1"/></svg>
|
||||
</span>
|
||||
</nav>
|
||||
</header>
|
@ -0,0 +1,13 @@
|
||||
{{ if or (.PrevInSection) (.NextInSection) }}
|
||||
<section>
|
||||
<h2>Read Next</h2>
|
||||
<div class="single-next-previous">
|
||||
{{ with .PrevInSection }}
|
||||
<a class="previous" href="{{.Permalink}}">« {{ .Title }}</a>
|
||||
{{ end }}
|
||||
{{ with .NextInSection }}
|
||||
<a class="next" href="{{.Permalink}}">{{ .Title }} »</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
23
themes/hugo-liftoff/layouts/partials/posts/post-entry.html
Normal file
23
themes/hugo-liftoff/layouts/partials/posts/post-entry.html
Normal file
@ -0,0 +1,23 @@
|
||||
<div class="post-entry">
|
||||
<h3 class="post-list-title">
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
</h3>
|
||||
<div class="post-list-meta">
|
||||
{{ partial "posts/post-meta.html" . }}
|
||||
{{ with .Params.categories }}
|
||||
<div class="post-list-categories">
|
||||
{{ range . }}
|
||||
<a href="{{ "categories" | absURL }}/{{ . | urlize }}/">{{ . }}</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ partial "general/label-drafts.html" . }}
|
||||
</div>
|
||||
<p class="post-list-summary">
|
||||
{{- with .Params.Summary -}}
|
||||
{{- . -}}
|
||||
{{- else -}}
|
||||
{{- .Description -}}
|
||||
{{- end -}}
|
||||
</p>
|
||||
</div>
|
15
themes/hugo-liftoff/layouts/partials/posts/post-meta.html
Normal file
15
themes/hugo-liftoff/layouts/partials/posts/post-meta.html
Normal file
@ -0,0 +1,15 @@
|
||||
<div class="post-list-dates">
|
||||
{{- if not (eq .Lastmod .Date) -}}
|
||||
Posted:
|
||||
{{ end -}}
|
||||
{{- if not .PublishDate.IsZero -}}
|
||||
{{- .PublishDate.Format "Jan 2, 2006" -}}
|
||||
{{- else -}}
|
||||
{{ .Date.Format "Jan 2, 2006" -}}
|
||||
{{- end -}}
|
||||
{{- if not (eq .Lastmod .Date) -}}
|
||||
·
|
||||
Updated: {{ .Lastmod.Format "Jan 2, 2006" -}}
|
||||
{{- end -}}
|
||||
·
|
||||
{{- .ReadingTime }} min.</div>
|
14
themes/hugo-liftoff/layouts/partials/posts/related.html
Normal file
14
themes/hugo-liftoff/layouts/partials/posts/related.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!-- Reusable template for related posts (at the end of posts single pages) -->
|
||||
{{ if .Param "related" }}
|
||||
{{ $related := .Site.RegularPages.Related . | first 5 }}
|
||||
{{ with $related }}
|
||||
<section class="related">
|
||||
<h2>See Also</h2>
|
||||
<ul class="related-posts">
|
||||
{{ range . }}
|
||||
<li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</section>
|
||||
{{ end }}
|
||||
{{ end }}
|
44
themes/hugo-liftoff/layouts/partials/posts/social-share.html
Normal file
44
themes/hugo-liftoff/layouts/partials/posts/social-share.html
Normal file
@ -0,0 +1,44 @@
|
||||
<!-- Social Share Button HTML -->
|
||||
{{- if .Param "social_share" }}
|
||||
{{ $title := .Title }}
|
||||
{{ $url := printf "%s" .Permalink }}
|
||||
{{ $body := print $title ", by " .Site.Title "\n" .Params.description "\n\n" $url "\n" }}
|
||||
|
||||
<section>
|
||||
<h2>Share</h2>
|
||||
<div class="social-links">
|
||||
<ul class="social-icons--share">
|
||||
<!-- Twitter -->
|
||||
{{ if .Site.Params.social.share.twitter }}
|
||||
<a href="https://twitter.com/intent/tweet?url={{ .Permalink }}&text={{ .Title }}" target="_blank" rel="noopener" aria-label="Share on Twitter" class="social-btn twitter">
|
||||
<li>{{ partial "svg/twitter.svg" }}</li>
|
||||
</a>
|
||||
{{ end }}
|
||||
<!-- Reddit -->
|
||||
{{ if .Site.Params.social.share.reddit }}
|
||||
<a href="https://www.reddit.com/submit?url={{ .Permalink }}" target="_blank" rel="noopener" aria-label="Share on Reddit" class="social-btn reddit">
|
||||
<li>{{ partial "svg/reddit.svg" }}</li>
|
||||
</a>
|
||||
{{ end }}
|
||||
<!-- Facebook -->
|
||||
{{ if .Site.Params.social.share.facebook }}
|
||||
<a href="https://www.facebook.com/sharer.php?u={{ $url }}" target="_blank" rel="noopener" aria-label="Share on Facebook" class="social-btn facebook">
|
||||
<li>{{ partial "svg/facebook.svg" }}</li>
|
||||
</a>
|
||||
{{ end }}
|
||||
<!-- LinkedIn -->
|
||||
{{ if .Site.Params.social.share.linkedin }}
|
||||
<a href="https://www.linkedin.com/shareArticle?mini=true&url={{ $url }}&source={{ $url }}&title={{ $title }}&summary={{ $title }}" target="_blank" rel="noopener" aria-label="Share on LinkedIn" class="social-btn linkedin">
|
||||
<li>{{ partial "svg/linkedin.svg" }}</li>
|
||||
</a>
|
||||
{{ end }}
|
||||
<!-- Email -->
|
||||
{{ if .Site.Params.social.share.email }}
|
||||
<a href="mailto:?subject={{ .Site.Title }}%20-%20{{ $title }}.&body={{ $body }}" target="_blank" class="social-btn email">
|
||||
<li>{{ partial "svg/email.svg" }}</li>
|
||||
</a>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
{{ end }}
|
||||
{{- end }}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user